aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorMilo Kim <milo.kim@ti.com>2015-08-24 03:09:55 -0400
committerJacek Anaszewski <j.anaszewski@samsung.com>2015-08-28 08:06:28 -0400
commited133352047e46687afd98c299ec8ce7f6ea07bd (patch)
tree6b35cca71f5451782c5979106336d1321a03cc71 /drivers/leds
parent991a3f61fa93c1752a47ae157a8238395850c730 (diff)
leds:lp55xx: use the private data instead of updating I2C device platform data
Currently, lp55xx_of_populate_pdata() allocates lp55xx_platform_data if it's null. And it parses the DT and copies values into the 'client->dev.platform_data'. This may have architectural issue. Platform data is configurable through the DT or I2C board info inside the platform area. However, lp55xx common driver changes this configuration when it is loaded. So 'client->dev.platform_data' is not null anymore. Eventually, the driver initialization is not identical when it's unloaded and loaded again. The lp55xx common driver should use the private data, 'lp55xx_chip->pdata' instead of changing the original platform data. So, lp55xx_of_populate_pdata() is modified as follows. * Do not update 'dev->platform_data'. Return the pointer of new allocated lp55xx_platform_data. Then the driver points it to private data, 'lp55xx_chip->pdata'. * Each lp55xx driver checks the pointer and handles an error case. Then, original platform data configuration will be kept regardless of loading or unloading the driver. The driver allocates the memory and copies them from the DT if it's NULL. After the driver is loaded again, 'client->dev.platform_data' is same as initial load, so the driver is initialized identically. Cc: Toshi Kikuchi <toshik@chromium.org> Cc: linux-leds@vger.kernel.org Signed-off-by: Milo Kim <milo.kim@ti.com> Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp5521.c11
-rw-r--r--drivers/leds/leds-lp5523.c11
-rw-r--r--drivers/leds/leds-lp5562.c11
-rw-r--r--drivers/leds/leds-lp55xx-common.c13
-rw-r--r--drivers/leds/leds-lp55xx-common.h4
-rw-r--r--drivers/leds/leds-lp8501.c11
6 files changed, 28 insertions, 33 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 8ca197af2864..63a92542c8cb 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -514,20 +514,19 @@ static int lp5521_probe(struct i2c_client *client,
514 int ret; 514 int ret;
515 struct lp55xx_chip *chip; 515 struct lp55xx_chip *chip;
516 struct lp55xx_led *led; 516 struct lp55xx_led *led;
517 struct lp55xx_platform_data *pdata; 517 struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
518 struct device_node *np = client->dev.of_node; 518 struct device_node *np = client->dev.of_node;
519 519
520 if (!dev_get_platdata(&client->dev)) { 520 if (!pdata) {
521 if (np) { 521 if (np) {
522 ret = lp55xx_of_populate_pdata(&client->dev, np); 522 pdata = lp55xx_of_populate_pdata(&client->dev, np);
523 if (ret < 0) 523 if (IS_ERR(pdata))
524 return ret; 524 return PTR_ERR(pdata);
525 } else { 525 } else {
526 dev_err(&client->dev, "no platform data\n"); 526 dev_err(&client->dev, "no platform data\n");
527 return -EINVAL; 527 return -EINVAL;
528 } 528 }
529 } 529 }
530 pdata = dev_get_platdata(&client->dev);
531 530
532 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 531 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
533 if (!chip) 532 if (!chip)
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 584dbbcec659..1d0187f42941 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -880,20 +880,19 @@ static int lp5523_probe(struct i2c_client *client,
880 int ret; 880 int ret;
881 struct lp55xx_chip *chip; 881 struct lp55xx_chip *chip;
882 struct lp55xx_led *led; 882 struct lp55xx_led *led;
883 struct lp55xx_platform_data *pdata; 883 struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
884 struct device_node *np = client->dev.of_node; 884 struct device_node *np = client->dev.of_node;
885 885
886 if (!dev_get_platdata(&client->dev)) { 886 if (!pdata) {
887 if (np) { 887 if (np) {
888 ret = lp55xx_of_populate_pdata(&client->dev, np); 888 pdata = lp55xx_of_populate_pdata(&client->dev, np);
889 if (ret < 0) 889 if (IS_ERR(pdata))
890 return ret; 890 return PTR_ERR(pdata);
891 } else { 891 } else {
892 dev_err(&client->dev, "no platform data\n"); 892 dev_err(&client->dev, "no platform data\n");
893 return -EINVAL; 893 return -EINVAL;
894 } 894 }
895 } 895 }
896 pdata = dev_get_platdata(&client->dev);
897 896
898 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 897 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
899 if (!chip) 898 if (!chip)
diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c
index ca85724ab138..0360c59dbdc9 100644
--- a/drivers/leds/leds-lp5562.c
+++ b/drivers/leds/leds-lp5562.c
@@ -515,20 +515,19 @@ static int lp5562_probe(struct i2c_client *client,
515 int ret; 515 int ret;
516 struct lp55xx_chip *chip; 516 struct lp55xx_chip *chip;
517 struct lp55xx_led *led; 517 struct lp55xx_led *led;
518 struct lp55xx_platform_data *pdata; 518 struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
519 struct device_node *np = client->dev.of_node; 519 struct device_node *np = client->dev.of_node;
520 520
521 if (!dev_get_platdata(&client->dev)) { 521 if (!pdata) {
522 if (np) { 522 if (np) {
523 ret = lp55xx_of_populate_pdata(&client->dev, np); 523 pdata = lp55xx_of_populate_pdata(&client->dev, np);
524 if (ret < 0) 524 if (IS_ERR(pdata))
525 return ret; 525 return PTR_ERR(pdata);
526 } else { 526 } else {
527 dev_err(&client->dev, "no platform data\n"); 527 dev_err(&client->dev, "no platform data\n");
528 return -EINVAL; 528 return -EINVAL;
529 } 529 }
530 } 530 }
531 pdata = dev_get_platdata(&client->dev);
532 531
533 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 532 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
534 if (!chip) 533 if (!chip)
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 96d51e9879c9..59b76833f0d3 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -543,7 +543,8 @@ void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
543} 543}
544EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); 544EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
545 545
546int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) 546struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
547 struct device_node *np)
547{ 548{
548 struct device_node *child; 549 struct device_node *child;
549 struct lp55xx_platform_data *pdata; 550 struct lp55xx_platform_data *pdata;
@@ -553,17 +554,17 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
553 554
554 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 555 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
555 if (!pdata) 556 if (!pdata)
556 return -ENOMEM; 557 return ERR_PTR(-ENOMEM);
557 558
558 num_channels = of_get_child_count(np); 559 num_channels = of_get_child_count(np);
559 if (num_channels == 0) { 560 if (num_channels == 0) {
560 dev_err(dev, "no LED channels\n"); 561 dev_err(dev, "no LED channels\n");
561 return -EINVAL; 562 return ERR_PTR(-EINVAL);
562 } 563 }
563 564
564 cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL); 565 cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL);
565 if (!cfg) 566 if (!cfg)
566 return -ENOMEM; 567 return ERR_PTR(-ENOMEM);
567 568
568 pdata->led_config = &cfg[0]; 569 pdata->led_config = &cfg[0];
569 pdata->num_channels = num_channels; 570 pdata->num_channels = num_channels;
@@ -588,9 +589,7 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
588 /* LP8501 specific */ 589 /* LP8501 specific */
589 of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel); 590 of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
590 591
591 dev->platform_data = pdata; 592 return pdata;
592
593 return 0;
594} 593}
595EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata); 594EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
596 595
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index cceab483edd0..c7f1e6155001 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -202,7 +202,7 @@ extern int lp55xx_register_sysfs(struct lp55xx_chip *chip);
202extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip); 202extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip);
203 203
204/* common device tree population function */ 204/* common device tree population function */
205extern int lp55xx_of_populate_pdata(struct device *dev, 205extern struct lp55xx_platform_data
206 struct device_node *np); 206*lp55xx_of_populate_pdata(struct device *dev, struct device_node *np);
207 207
208#endif /* _LEDS_LP55XX_COMMON_H */ 208#endif /* _LEDS_LP55XX_COMMON_H */
diff --git a/drivers/leds/leds-lp8501.c b/drivers/leds/leds-lp8501.c
index d3098e395fff..3f54f6f2b821 100644
--- a/drivers/leds/leds-lp8501.c
+++ b/drivers/leds/leds-lp8501.c
@@ -308,20 +308,19 @@ static int lp8501_probe(struct i2c_client *client,
308 int ret; 308 int ret;
309 struct lp55xx_chip *chip; 309 struct lp55xx_chip *chip;
310 struct lp55xx_led *led; 310 struct lp55xx_led *led;
311 struct lp55xx_platform_data *pdata; 311 struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
312 struct device_node *np = client->dev.of_node; 312 struct device_node *np = client->dev.of_node;
313 313
314 if (!dev_get_platdata(&client->dev)) { 314 if (!pdata) {
315 if (np) { 315 if (np) {
316 ret = lp55xx_of_populate_pdata(&client->dev, np); 316 pdata = lp55xx_of_populate_pdata(&client->dev, np);
317 if (ret < 0) 317 if (IS_ERR(pdata))
318 return ret; 318 return PTR_ERR(pdata);
319 } else { 319 } else {
320 dev_err(&client->dev, "no platform data\n"); 320 dev_err(&client->dev, "no platform data\n");
321 return -EINVAL; 321 return -EINVAL;
322 } 322 }
323 } 323 }
324 pdata = dev_get_platdata(&client->dev);
325 324
326 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 325 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
327 if (!chip) 326 if (!chip)