aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2013-01-16 08:53:57 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2013-02-13 18:22:51 -0500
commit80a97ccd33be9c79018d3d4983eefa3e6d6bfb6d (patch)
tree7090232bab288b42d93edddd89f5bfbcb96cf441 /drivers/mfd
parent6382a0614144901af1cbbfdf9b9a618f5dfb8548 (diff)
mfd: twl-core: Collect global variables behind one private structure (global)
Gather the global variables under a single structure and allocate it with devm_kzalloc(). It is easier to see them and if in the future we try to add support for multiple instance of twl in the system it is going to be much simpler. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/twl-core.c104
1 files changed, 57 insertions, 47 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 182708811065..e2895a4026a1 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -141,33 +141,28 @@
141 141
142/*----------------------------------------------------------------------*/ 142/*----------------------------------------------------------------------*/
143 143
144/* is driver active, bound to a chip? */
145static bool inuse;
146
147/* TWL IDCODE Register value */
148static u32 twl_idcode;
149
150static unsigned int twl_id;
151unsigned int twl_rev(void)
152{
153 return twl_id;
154}
155EXPORT_SYMBOL(twl_rev);
156
157/* Structure for each TWL4030/TWL6030 Slave */ 144/* Structure for each TWL4030/TWL6030 Slave */
158struct twl_client { 145struct twl_client {
159 struct i2c_client *client; 146 struct i2c_client *client;
160 struct regmap *regmap; 147 struct regmap *regmap;
161}; 148};
162 149
163static struct twl_client *twl_modules;
164
165/* mapping the module id to slave id and base address */ 150/* mapping the module id to slave id and base address */
166struct twl_mapping { 151struct twl_mapping {
167 unsigned char sid; /* Slave ID */ 152 unsigned char sid; /* Slave ID */
168 unsigned char base; /* base address */ 153 unsigned char base; /* base address */
169}; 154};
170static struct twl_mapping *twl_map; 155
156struct twl_private {
157 bool ready; /* The core driver is ready to be used */
158 u32 twl_idcode; /* TWL IDCODE Register value */
159 unsigned int twl_id;
160
161 struct twl_mapping *twl_map;
162 struct twl_client *twl_modules;
163};
164
165static struct twl_private *twl_priv;
171 166
172static struct twl_mapping twl4030_map[] = { 167static struct twl_mapping twl4030_map[] = {
173 /* 168 /*
@@ -300,6 +295,12 @@ static inline int twl_get_last_module(void)
300 295
301/* Exported Functions */ 296/* Exported Functions */
302 297
298unsigned int twl_rev(void)
299{
300 return twl_priv ? twl_priv->twl_id : 0;
301}
302EXPORT_SYMBOL(twl_rev);
303
303/** 304/**
304 * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0 305 * twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
305 * @mod_no: module number 306 * @mod_no: module number
@@ -322,16 +323,17 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
322 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); 323 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
323 return -EPERM; 324 return -EPERM;
324 } 325 }
325 if (unlikely(!inuse)) { 326 if (unlikely(!twl_priv->ready)) {
326 pr_err("%s: not initialized\n", DRIVER_NAME); 327 pr_err("%s: not initialized\n", DRIVER_NAME);
327 return -EPERM; 328 return -EPERM;
328 } 329 }
329 330
330 sid = twl_map[mod_no].sid; 331 sid = twl_priv->twl_map[mod_no].sid;
331 twl = &twl_modules[sid]; 332 twl = &twl_priv->twl_modules[sid];
332 333
333 ret = regmap_bulk_write(twl->regmap, twl_map[mod_no].base + reg, 334 ret = regmap_bulk_write(twl->regmap,
334 value, num_bytes); 335 twl_priv->twl_map[mod_no].base + reg, value,
336 num_bytes);
335 337
336 if (ret) 338 if (ret)
337 pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n", 339 pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
@@ -360,16 +362,17 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
360 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); 362 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
361 return -EPERM; 363 return -EPERM;
362 } 364 }
363 if (unlikely(!inuse)) { 365 if (unlikely(!twl_priv->ready)) {
364 pr_err("%s: not initialized\n", DRIVER_NAME); 366 pr_err("%s: not initialized\n", DRIVER_NAME);
365 return -EPERM; 367 return -EPERM;
366 } 368 }
367 369
368 sid = twl_map[mod_no].sid; 370 sid = twl_priv->twl_map[mod_no].sid;
369 twl = &twl_modules[sid]; 371 twl = &twl_priv->twl_modules[sid];
370 372
371 ret = regmap_bulk_read(twl->regmap, twl_map[mod_no].base + reg, 373 ret = regmap_bulk_read(twl->regmap,
372 value, num_bytes); 374 twl_priv->twl_map[mod_no].base + reg, value,
375 num_bytes);
373 376
374 if (ret) 377 if (ret)
375 pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n", 378 pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
@@ -425,7 +428,7 @@ static int twl_read_idcode_register(void)
425 goto fail; 428 goto fail;
426 } 429 }
427 430
428 err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), 431 err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_priv->twl_idcode),
429 REG_IDCODE_7_0, 4); 432 REG_IDCODE_7_0, 4);
430 if (err) { 433 if (err) {
431 pr_err("TWL4030: unable to read IDCODE -%d\n", err); 434 pr_err("TWL4030: unable to read IDCODE -%d\n", err);
@@ -446,7 +449,7 @@ fail:
446 */ 449 */
447int twl_get_type(void) 450int twl_get_type(void)
448{ 451{
449 return TWL_SIL_TYPE(twl_idcode); 452 return TWL_SIL_TYPE(twl_priv->twl_idcode);
450} 453}
451EXPORT_SYMBOL_GPL(twl_get_type); 454EXPORT_SYMBOL_GPL(twl_get_type);
452 455
@@ -457,7 +460,7 @@ EXPORT_SYMBOL_GPL(twl_get_type);
457 */ 460 */
458int twl_get_version(void) 461int twl_get_version(void)
459{ 462{
460 return TWL_SIL_REV(twl_idcode); 463 return TWL_SIL_REV(twl_priv->twl_idcode);
461} 464}
462EXPORT_SYMBOL_GPL(twl_get_version); 465EXPORT_SYMBOL_GPL(twl_get_version);
463 466
@@ -506,8 +509,8 @@ add_numbered_child(unsigned mod_no, const char *name, int num,
506 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); 509 pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
507 return ERR_PTR(-EPERM); 510 return ERR_PTR(-EPERM);
508 } 511 }
509 sid = twl_map[mod_no].sid; 512 sid = twl_priv->twl_map[mod_no].sid;
510 twl = &twl_modules[sid]; 513 twl = &twl_priv->twl_modules[sid];
511 514
512 pdev = platform_device_alloc(name, num); 515 pdev = platform_device_alloc(name, num);
513 if (!pdev) { 516 if (!pdev) {
@@ -1143,13 +1146,13 @@ static int twl_remove(struct i2c_client *client)
1143 1146
1144 num_slaves = twl_get_num_slaves(); 1147 num_slaves = twl_get_num_slaves();
1145 for (i = 0; i < num_slaves; i++) { 1148 for (i = 0; i < num_slaves; i++) {
1146 struct twl_client *twl = &twl_modules[i]; 1149 struct twl_client *twl = &twl_priv->twl_modules[i];
1147 1150
1148 if (twl->client && twl->client != client) 1151 if (twl->client && twl->client != client)
1149 i2c_unregister_device(twl->client); 1152 i2c_unregister_device(twl->client);
1150 twl_modules[i].client = NULL; 1153 twl->client = NULL;
1151 } 1154 }
1152 inuse = false; 1155 twl_priv->ready = false;
1153 return 0; 1156 return 0;
1154} 1157}
1155 1158
@@ -1170,7 +1173,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1170 return -EINVAL; 1173 return -EINVAL;
1171 } 1174 }
1172 1175
1173 if (inuse) { 1176 if (twl_priv) {
1174 dev_dbg(&client->dev, "only one instance of %s allowed\n", 1177 dev_dbg(&client->dev, "only one instance of %s allowed\n",
1175 DRIVER_NAME); 1178 DRIVER_NAME);
1176 return -EBUSY; 1179 return -EBUSY;
@@ -1194,31 +1197,38 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1194 goto free; 1197 goto free;
1195 } 1198 }
1196 1199
1200 twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private),
1201 GFP_KERNEL);
1202 if (!twl_priv) {
1203 status = -ENOMEM;
1204 goto free;
1205 }
1206
1197 if ((id->driver_data) & TWL6030_CLASS) { 1207 if ((id->driver_data) & TWL6030_CLASS) {
1198 twl_id = TWL6030_CLASS_ID; 1208 twl_priv->twl_id = TWL6030_CLASS_ID;
1199 twl_map = &twl6030_map[0]; 1209 twl_priv->twl_map = &twl6030_map[0];
1200 /* The charger base address is different in twl6025 */ 1210 /* The charger base address is different in twl6025 */
1201 if ((id->driver_data) & TWL6025_SUBCLASS) 1211 if ((id->driver_data) & TWL6025_SUBCLASS)
1202 twl_map[TWL_MODULE_MAIN_CHARGE].base = 1212 twl_priv->twl_map[TWL_MODULE_MAIN_CHARGE].base =
1203 TWL6025_BASEADD_CHARGER; 1213 TWL6025_BASEADD_CHARGER;
1204 twl_regmap_config = twl6030_regmap_config; 1214 twl_regmap_config = twl6030_regmap_config;
1205 } else { 1215 } else {
1206 twl_id = TWL4030_CLASS_ID; 1216 twl_priv->twl_id = TWL4030_CLASS_ID;
1207 twl_map = &twl4030_map[0]; 1217 twl_priv->twl_map = &twl4030_map[0];
1208 twl_regmap_config = twl4030_regmap_config; 1218 twl_regmap_config = twl4030_regmap_config;
1209 } 1219 }
1210 1220
1211 num_slaves = twl_get_num_slaves(); 1221 num_slaves = twl_get_num_slaves();
1212 twl_modules = devm_kzalloc(&client->dev, 1222 twl_priv->twl_modules = devm_kzalloc(&client->dev,
1213 sizeof(struct twl_client) * num_slaves, 1223 sizeof(struct twl_client) * num_slaves,
1214 GFP_KERNEL); 1224 GFP_KERNEL);
1215 if (!twl_modules) { 1225 if (!twl_priv->twl_modules) {
1216 status = -ENOMEM; 1226 status = -ENOMEM;
1217 goto free; 1227 goto free;
1218 } 1228 }
1219 1229
1220 for (i = 0; i < num_slaves; i++) { 1230 for (i = 0; i < num_slaves; i++) {
1221 struct twl_client *twl = &twl_modules[i]; 1231 struct twl_client *twl = &twl_priv->twl_modules[i];
1222 1232
1223 if (i == 0) { 1233 if (i == 0) {
1224 twl->client = client; 1234 twl->client = client;
@@ -1244,13 +1254,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1244 } 1254 }
1245 } 1255 }
1246 1256
1247 inuse = true; 1257 twl_priv->ready = true;
1248 1258
1249 /* setup clock framework */ 1259 /* setup clock framework */
1250 clocks_init(&pdev->dev, pdata ? pdata->clock : NULL); 1260 clocks_init(&pdev->dev, pdata ? pdata->clock : NULL);
1251 1261
1252 /* read TWL IDCODE Register */ 1262 /* read TWL IDCODE Register */
1253 if (twl_id == TWL4030_CLASS_ID) { 1263 if (twl_class_is_4030()) {
1254 status = twl_read_idcode_register(); 1264 status = twl_read_idcode_register();
1255 WARN(status < 0, "Error: reading twl_idcode register value\n"); 1265 WARN(status < 0, "Error: reading twl_idcode register value\n");
1256 } 1266 }