diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/twl-core.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index f462ff226c8d..9d3a0bc1a65f 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include <linux/i2c.h> | 46 | #include <linux/i2c.h> |
47 | #include <linux/i2c/twl.h> | 47 | #include <linux/i2c/twl.h> |
48 | 48 | ||
49 | #include <plat/cpu.h> | ||
50 | |||
51 | #include "twl-core.h" | 49 | #include "twl-core.h" |
52 | 50 | ||
53 | /* | 51 | /* |
@@ -1134,12 +1132,7 @@ static void clocks_init(struct device *dev, | |||
1134 | u32 rate; | 1132 | u32 rate; |
1135 | u8 ctrl = HFCLK_FREQ_26_MHZ; | 1133 | u8 ctrl = HFCLK_FREQ_26_MHZ; |
1136 | 1134 | ||
1137 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 1135 | osc = clk_get(dev, "fck"); |
1138 | if (cpu_is_omap2430()) | ||
1139 | osc = clk_get(dev, "osc_ck"); | ||
1140 | else | ||
1141 | osc = clk_get(dev, "osc_sys_ck"); | ||
1142 | |||
1143 | if (IS_ERR(osc)) { | 1136 | if (IS_ERR(osc)) { |
1144 | printk(KERN_WARNING "Skipping twl internal clock init and " | 1137 | printk(KERN_WARNING "Skipping twl internal clock init and " |
1145 | "using bootloader value (unknown osc rate)\n"); | 1138 | "using bootloader value (unknown osc rate)\n"); |
@@ -1149,18 +1142,6 @@ static void clocks_init(struct device *dev, | |||
1149 | rate = clk_get_rate(osc); | 1142 | rate = clk_get_rate(osc); |
1150 | clk_put(osc); | 1143 | clk_put(osc); |
1151 | 1144 | ||
1152 | #else | ||
1153 | /* REVISIT for non-OMAP systems, pass the clock rate from | ||
1154 | * board init code, using platform_data. | ||
1155 | */ | ||
1156 | osc = ERR_PTR(-EIO); | ||
1157 | |||
1158 | printk(KERN_WARNING "Skipping twl internal clock init and " | ||
1159 | "using bootloader value (unknown osc rate)\n"); | ||
1160 | |||
1161 | return; | ||
1162 | #endif | ||
1163 | |||
1164 | switch (rate) { | 1145 | switch (rate) { |
1165 | case 19200000: | 1146 | case 19200000: |
1166 | ctrl = HFCLK_FREQ_19p2_MHZ; | 1147 | ctrl = HFCLK_FREQ_19p2_MHZ; |
@@ -1222,10 +1203,23 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1222 | { | 1203 | { |
1223 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1204 | struct twl4030_platform_data *pdata = client->dev.platform_data; |
1224 | struct device_node *node = client->dev.of_node; | 1205 | struct device_node *node = client->dev.of_node; |
1206 | struct platform_device *pdev; | ||
1225 | int irq_base = 0; | 1207 | int irq_base = 0; |
1226 | int status; | 1208 | int status; |
1227 | unsigned i, num_slaves; | 1209 | unsigned i, num_slaves; |
1228 | 1210 | ||
1211 | pdev = platform_device_alloc(DRIVER_NAME, -1); | ||
1212 | if (!pdev) { | ||
1213 | dev_err(&client->dev, "can't alloc pdev\n"); | ||
1214 | return -ENOMEM; | ||
1215 | } | ||
1216 | |||
1217 | status = platform_device_add(pdev); | ||
1218 | if (status) { | ||
1219 | platform_device_put(pdev); | ||
1220 | return status; | ||
1221 | } | ||
1222 | |||
1229 | if (node && !pdata) { | 1223 | if (node && !pdata) { |
1230 | /* | 1224 | /* |
1231 | * XXX: Temporary pdata until the information is correctly | 1225 | * XXX: Temporary pdata until the information is correctly |
@@ -1234,23 +1228,30 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1234 | pdata = devm_kzalloc(&client->dev, | 1228 | pdata = devm_kzalloc(&client->dev, |
1235 | sizeof(struct twl4030_platform_data), | 1229 | sizeof(struct twl4030_platform_data), |
1236 | GFP_KERNEL); | 1230 | GFP_KERNEL); |
1237 | if (!pdata) | 1231 | if (!pdata) { |
1238 | return -ENOMEM; | 1232 | status = -ENOMEM; |
1233 | goto free; | ||
1234 | } | ||
1239 | } | 1235 | } |
1240 | 1236 | ||
1241 | if (!pdata) { | 1237 | if (!pdata) { |
1242 | dev_dbg(&client->dev, "no platform data?\n"); | 1238 | dev_dbg(&client->dev, "no platform data?\n"); |
1243 | return -EINVAL; | 1239 | status = -EINVAL; |
1240 | goto free; | ||
1244 | } | 1241 | } |
1245 | 1242 | ||
1243 | platform_set_drvdata(pdev, pdata); | ||
1244 | |||
1246 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | 1245 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { |
1247 | dev_dbg(&client->dev, "can't talk I2C?\n"); | 1246 | dev_dbg(&client->dev, "can't talk I2C?\n"); |
1248 | return -EIO; | 1247 | status = -EIO; |
1248 | goto free; | ||
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | if (inuse) { | 1251 | if (inuse) { |
1252 | dev_dbg(&client->dev, "driver is already in use\n"); | 1252 | dev_dbg(&client->dev, "driver is already in use\n"); |
1253 | return -EBUSY; | 1253 | status = -EBUSY; |
1254 | goto free; | ||
1254 | } | 1255 | } |
1255 | 1256 | ||
1256 | if ((id->driver_data) & TWL6030_CLASS) { | 1257 | if ((id->driver_data) & TWL6030_CLASS) { |
@@ -1285,7 +1286,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1285 | inuse = true; | 1286 | inuse = true; |
1286 | 1287 | ||
1287 | /* setup clock framework */ | 1288 | /* setup clock framework */ |
1288 | clocks_init(&client->dev, pdata->clock); | 1289 | clocks_init(&pdev->dev, pdata->clock); |
1289 | 1290 | ||
1290 | /* read TWL IDCODE Register */ | 1291 | /* read TWL IDCODE Register */ |
1291 | if (twl_id == TWL4030_CLASS_ID) { | 1292 | if (twl_id == TWL4030_CLASS_ID) { |
@@ -1335,6 +1336,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1335 | fail: | 1336 | fail: |
1336 | if (status < 0) | 1337 | if (status < 0) |
1337 | twl_remove(client); | 1338 | twl_remove(client); |
1339 | free: | ||
1340 | if (status < 0) | ||
1341 | platform_device_unregister(pdev); | ||
1338 | 1342 | ||
1339 | return status; | 1343 | return status; |
1340 | } | 1344 | } |