Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: regulator: Make probeable from device tree

The regulator LED can easily be adapted to probe from the
device tree.

We switch led_classdev_register() to led_classdev_register_ext()
passing some struct led_init_data init_data that we leave NULL
save the fwnode if platform data isn't present so that it will be
populated from the device tree.

If we have platform data we set up the name from the platform
data but using init_data instead.

Cc: Antonio Ospite <ao2@ao2.it>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Pavel Machek <pavel@ucw.cz>

authored by

Linus Walleij and committed by
Pavel Machek
835fc89e 4c350c65

+23 -19
+23 -19
drivers/leds/leds-regulator.c
··· 8 8 */ 9 9 10 10 #include <linux/module.h> 11 + #include <linux/mod_devicetable.h> 11 12 #include <linux/err.h> 12 13 #include <linux/slab.h> 13 14 #include <linux/leds.h> ··· 125 124 struct led_regulator_platform_data *pdata = 126 125 dev_get_platdata(&pdev->dev); 127 126 struct device *dev = &pdev->dev; 127 + struct led_init_data init_data = {}; 128 128 struct regulator_led *led; 129 129 struct regulator *vcc; 130 130 int ret = 0; 131 131 132 - if (pdata == NULL) { 133 - dev_err(dev, "no platform data\n"); 134 - return -ENODEV; 135 - } 136 - 137 132 vcc = devm_regulator_get_exclusive(dev, "vled"); 138 133 if (IS_ERR(vcc)) { 139 - dev_err(dev, "Cannot get vcc for %s\n", pdata->name); 134 + dev_err(dev, "Cannot get vcc\n"); 140 135 return PTR_ERR(vcc); 141 136 } 142 137 ··· 140 143 if (led == NULL) 141 144 return -ENOMEM; 142 145 146 + init_data.fwnode = dev->fwnode; 147 + 143 148 led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); 144 - if (pdata->brightness > led->cdev.max_brightness) { 145 - dev_err(dev, "Invalid default brightness %d\n", 149 + /* Legacy platform data label assignment */ 150 + if (pdata) { 151 + if (pdata->brightness > led->cdev.max_brightness) { 152 + dev_err(dev, "Invalid default brightness %d\n", 146 153 pdata->brightness); 147 - return -EINVAL; 154 + return -EINVAL; 155 + } 156 + led->cdev.brightness = pdata->brightness; 157 + init_data.default_label = pdata->name; 148 158 } 149 159 150 160 led->cdev.brightness_set_blocking = regulator_led_brightness_set; 151 - led->cdev.name = pdata->name; 152 161 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 153 162 led->vcc = vcc; 154 163 ··· 166 163 167 164 platform_set_drvdata(pdev, led); 168 165 169 - ret = led_classdev_register(dev, &led->cdev); 166 + ret = led_classdev_register_ext(dev, &led->cdev, &init_data); 170 167 if (ret < 0) 171 168 return ret; 172 - 173 - /* to expose the default value to userspace */ 174 - led->cdev.brightness = pdata->brightness; 175 - 176 - /* Set the default led status */ 177 - regulator_led_brightness_set(&led->cdev, led->cdev.brightness); 178 169 179 170 return 0; 180 171 } ··· 182 185 return 0; 183 186 } 184 187 188 + static const struct of_device_id regulator_led_of_match[] = { 189 + { .compatible = "regulator-led", }, 190 + {} 191 + }; 192 + MODULE_DEVICE_TABLE(of, regulator_led_of_match); 193 + 185 194 static struct platform_driver regulator_led_driver = { 186 195 .driver = { 187 - .name = "leds-regulator", 188 - }, 196 + .name = "leds-regulator", 197 + .of_match_table = regulator_led_of_match, 198 + }, 189 199 .probe = regulator_led_probe, 190 200 .remove = regulator_led_remove, 191 201 };