aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-01-23 07:43:28 -0500
committerLee Jones <lee.jones@linaro.org>2014-03-19 04:58:05 -0400
commita381b13e2aa064122325de9deaec51d6e4765ad7 (patch)
tree88ae5275f6b737eafc4dbce1834b19ba8729a50d
parent47ec66a17cca571eb7038b7835dff7cbd5851b90 (diff)
mfd: tc3589x: Reform device tree probing
This changes the following mechanisms in the TC3589x device tree probing path: - Use the .of_match_table in struct device_driver to match the device in the device tree. - Add matches for the proper compatible strings "toshiba,..." and all sub-variants, just as is done for the .id matches. - Move over all the allocation of platform data etc to the tc3589x_of_probe() function and follow the pattern of passing a platform data pointer back, or an error pointer on error, as found in the STMPE driver. - Match the new (proper) compatible strings for the GPIO and keypad MFD cells. - Use of_device_is_compatible() rather than just !strcmp() to discover which cells to instantiate. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/tc3589x.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index 2cf636c267d9..bd83accc0f6d 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -13,8 +13,10 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_device.h>
16#include <linux/mfd/core.h> 17#include <linux/mfd/core.h>
17#include <linux/mfd/tc3589x.h> 18#include <linux/mfd/tc3589x.h>
19#include <linux/err.h>
18 20
19/** 21/**
20 * enum tc3589x_version - indicates the TC3589x version 22 * enum tc3589x_version - indicates the TC3589x version
@@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = {
160 .name = "tc3589x-gpio", 162 .name = "tc3589x-gpio",
161 .num_resources = ARRAY_SIZE(gpio_resources), 163 .num_resources = ARRAY_SIZE(gpio_resources),
162 .resources = &gpio_resources[0], 164 .resources = &gpio_resources[0],
163 .of_compatible = "tc3589x-gpio", 165 .of_compatible = "toshiba,tc3589x-gpio",
164 }, 166 },
165}; 167};
166 168
@@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = {
169 .name = "tc3589x-keypad", 171 .name = "tc3589x-keypad",
170 .num_resources = ARRAY_SIZE(keypad_resources), 172 .num_resources = ARRAY_SIZE(keypad_resources),
171 .resources = &keypad_resources[0], 173 .resources = &keypad_resources[0],
172 .of_compatible = "tc3589x-keypad", 174 .of_compatible = "toshiba,tc3589x-keypad",
173 }, 175 },
174}; 176};
175 177
@@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x)
318 return ret; 320 return ret;
319} 321}
320 322
321static int tc3589x_of_probe(struct device_node *np, 323#ifdef CONFIG_OF
322 struct tc3589x_platform_data *pdata) 324static const struct of_device_id tc3589x_match[] = {
325 /* Legacy compatible string */
326 { .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN },
327 { .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 },
328 { .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 },
329 { .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 },
330 { .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 },
331 { .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 },
332 { .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 },
333 { }
334};
335
336MODULE_DEVICE_TABLE(of, tc3589x_match);
337
338static struct tc3589x_platform_data *
339tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
323{ 340{
341 struct device_node *np = dev->of_node;
342 struct tc3589x_platform_data *pdata;
324 struct device_node *child; 343 struct device_node *child;
344 const struct of_device_id *of_id;
345
346 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
347 if (!pdata)
348 return ERR_PTR(-ENOMEM);
349
350 of_id = of_match_device(tc3589x_match, dev);
351 if (!of_id)
352 return ERR_PTR(-ENODEV);
353 *version = (enum tc3589x_version) of_id->data;
325 354
326 for_each_child_of_node(np, child) { 355 for_each_child_of_node(np, child) {
327 if (!strcmp(child->name, "tc3589x_gpio")) { 356 if (of_device_is_compatible(child, "toshiba,tc3589x-gpio"))
328 pdata->block |= TC3589x_BLOCK_GPIO; 357 pdata->block |= TC3589x_BLOCK_GPIO;
329 } 358 if (of_device_is_compatible(child, "toshiba,tc3589x-keypad"))
330 if (!strcmp(child->name, "tc3589x_keypad")) {
331 pdata->block |= TC3589x_BLOCK_KEYPAD; 359 pdata->block |= TC3589x_BLOCK_KEYPAD;
332 }
333 } 360 }
334 361
335 return 0; 362 return pdata;
336} 363}
364#else
365static inline struct tc3589x_platform_data *
366tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
367{
368 dev_err(dev, "no device tree support\n");
369 return ERR_PTR(-ENODEV);
370}
371#endif
337 372
338static int tc3589x_probe(struct i2c_client *i2c, 373static int tc3589x_probe(struct i2c_client *i2c,
339 const struct i2c_device_id *id) 374 const struct i2c_device_id *id)
340{ 375{
341 struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
342 struct device_node *np = i2c->dev.of_node; 376 struct device_node *np = i2c->dev.of_node;
377 struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
343 struct tc3589x *tc3589x; 378 struct tc3589x *tc3589x;
379 enum tc3589x_version version;
344 int ret; 380 int ret;
345 381
346 if (!pdata) { 382 if (!pdata) {
347 if (np) { 383 pdata = tc3589x_of_probe(&i2c->dev, &version);
348 pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); 384 if (IS_ERR(pdata)) {
349 if (!pdata)
350 return -ENOMEM;
351
352 ret = tc3589x_of_probe(np, pdata);
353 if (ret)
354 return ret;
355 }
356 else {
357 dev_err(&i2c->dev, "No platform data or DT found\n"); 385 dev_err(&i2c->dev, "No platform data or DT found\n");
358 return -EINVAL; 386 return PTR_ERR(pdata);
359 } 387 }
388 } else {
389 /* When not probing from device tree we have this ID */
390 version = id->driver_data;
360 } 391 }
361 392
362 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA 393 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
@@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c,
375 tc3589x->pdata = pdata; 406 tc3589x->pdata = pdata;
376 tc3589x->irq_base = pdata->irq_base; 407 tc3589x->irq_base = pdata->irq_base;
377 408
378 switch (id->driver_data) { 409 switch (version) {
379 case TC3589X_TC35893: 410 case TC3589X_TC35893:
380 case TC3589X_TC35895: 411 case TC3589X_TC35895:
381 case TC3589X_TC35896: 412 case TC3589X_TC35896:
@@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = {
471MODULE_DEVICE_TABLE(i2c, tc3589x_id); 502MODULE_DEVICE_TABLE(i2c, tc3589x_id);
472 503
473static struct i2c_driver tc3589x_driver = { 504static struct i2c_driver tc3589x_driver = {
474 .driver.name = "tc3589x", 505 .driver = {
475 .driver.owner = THIS_MODULE, 506 .name = "tc3589x",
476 .driver.pm = &tc3589x_dev_pm_ops, 507 .owner = THIS_MODULE,
508 .pm = &tc3589x_dev_pm_ops,
509 .of_match_table = of_match_ptr(tc3589x_match),
510 },
477 .probe = tc3589x_probe, 511 .probe = tc3589x_probe,
478 .remove = tc3589x_remove, 512 .remove = tc3589x_remove,
479 .id_table = tc3589x_id, 513 .id_table = tc3589x_id,