From ed133352047e46687afd98c299ec8ce7f6ea07bd Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Mon, 24 Aug 2015 16:09:55 +0900 Subject: 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 Cc: linux-leds@vger.kernel.org Signed-off-by: Milo Kim Signed-off-by: Jacek Anaszewski --- drivers/leds/leds-lp55xx-common.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/leds/leds-lp55xx-common.c') 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) } EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); -int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) +struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, + struct device_node *np) { struct device_node *child; struct lp55xx_platform_data *pdata; @@ -553,17 +554,17 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) - return -ENOMEM; + return ERR_PTR(-ENOMEM); num_channels = of_get_child_count(np); if (num_channels == 0) { dev_err(dev, "no LED channels\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL); if (!cfg) - return -ENOMEM; + return ERR_PTR(-ENOMEM); pdata->led_config = &cfg[0]; pdata->num_channels = num_channels; @@ -588,9 +589,7 @@ int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np) /* LP8501 specific */ of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel); - dev->platform_data = pdata; - - return 0; + return pdata; } EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata); -- cgit v1.2.3