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 | } |
