|
@@ -46,8 +46,6 @@
|
|
|
#include <linux/i2c.h>
|
|
|
#include <linux/i2c/twl.h>
|
|
|
|
|
|
-#include <plat/cpu.h>
|
|
|
-
|
|
|
#include "twl-core.h"
|
|
|
|
|
|
/*
|
|
@@ -1134,12 +1132,7 @@ static void clocks_init(struct device *dev,
|
|
|
u32 rate;
|
|
|
u8 ctrl = HFCLK_FREQ_26_MHZ;
|
|
|
|
|
|
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
|
|
- if (cpu_is_omap2430())
|
|
|
- osc = clk_get(dev, "osc_ck");
|
|
|
- else
|
|
|
- osc = clk_get(dev, "osc_sys_ck");
|
|
|
-
|
|
|
+ osc = clk_get(dev, "fck");
|
|
|
if (IS_ERR(osc)) {
|
|
|
printk(KERN_WARNING "Skipping twl internal clock init and "
|
|
|
"using bootloader value (unknown osc rate)\n");
|
|
@@ -1149,18 +1142,6 @@ static void clocks_init(struct device *dev,
|
|
|
rate = clk_get_rate(osc);
|
|
|
clk_put(osc);
|
|
|
|
|
|
-#else
|
|
|
- /* REVISIT for non-OMAP systems, pass the clock rate from
|
|
|
- * board init code, using platform_data.
|
|
|
- */
|
|
|
- osc = ERR_PTR(-EIO);
|
|
|
-
|
|
|
- printk(KERN_WARNING "Skipping twl internal clock init and "
|
|
|
- "using bootloader value (unknown osc rate)\n");
|
|
|
-
|
|
|
- return;
|
|
|
-#endif
|
|
|
-
|
|
|
switch (rate) {
|
|
|
case 19200000:
|
|
|
ctrl = HFCLK_FREQ_19p2_MHZ;
|
|
@@ -1222,10 +1203,23 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
|
{
|
|
|
struct twl4030_platform_data *pdata = client->dev.platform_data;
|
|
|
struct device_node *node = client->dev.of_node;
|
|
|
+ struct platform_device *pdev;
|
|
|
int irq_base = 0;
|
|
|
int status;
|
|
|
unsigned i, num_slaves;
|
|
|
|
|
|
+ pdev = platform_device_alloc(DRIVER_NAME, -1);
|
|
|
+ if (!pdev) {
|
|
|
+ dev_err(&client->dev, "can't alloc pdev\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = platform_device_add(pdev);
|
|
|
+ if (status) {
|
|
|
+ platform_device_put(pdev);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
if (node && !pdata) {
|
|
|
/*
|
|
|
* XXX: Temporary pdata until the information is correctly
|
|
@@ -1234,23 +1228,30 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
|
pdata = devm_kzalloc(&client->dev,
|
|
|
sizeof(struct twl4030_platform_data),
|
|
|
GFP_KERNEL);
|
|
|
- if (!pdata)
|
|
|
- return -ENOMEM;
|
|
|
+ if (!pdata) {
|
|
|
+ status = -ENOMEM;
|
|
|
+ goto free;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (!pdata) {
|
|
|
dev_dbg(&client->dev, "no platform data?\n");
|
|
|
- return -EINVAL;
|
|
|
+ status = -EINVAL;
|
|
|
+ goto free;
|
|
|
}
|
|
|
|
|
|
+ platform_set_drvdata(pdev, pdata);
|
|
|
+
|
|
|
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
|
|
|
dev_dbg(&client->dev, "can't talk I2C?\n");
|
|
|
- return -EIO;
|
|
|
+ status = -EIO;
|
|
|
+ goto free;
|
|
|
}
|
|
|
|
|
|
if (inuse) {
|
|
|
dev_dbg(&client->dev, "driver is already in use\n");
|
|
|
- return -EBUSY;
|
|
|
+ status = -EBUSY;
|
|
|
+ goto free;
|
|
|
}
|
|
|
|
|
|
if ((id->driver_data) & TWL6030_CLASS) {
|
|
@@ -1285,7 +1286,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
|
inuse = true;
|
|
|
|
|
|
/* setup clock framework */
|
|
|
- clocks_init(&client->dev, pdata->clock);
|
|
|
+ clocks_init(&pdev->dev, pdata->clock);
|
|
|
|
|
|
/* read TWL IDCODE Register */
|
|
|
if (twl_id == TWL4030_CLASS_ID) {
|
|
@@ -1335,6 +1336,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
|
fail:
|
|
|
if (status < 0)
|
|
|
twl_remove(client);
|
|
|
+free:
|
|
|
+ if (status < 0)
|
|
|
+ platform_device_unregister(pdev);
|
|
|
|
|
|
return status;
|
|
|
}
|