diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 10:49:54 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 10:49:54 -0700 |
| commit | f3033eb79136dd27b17e7a192fac0155ceab5eb8 (patch) | |
| tree | 444aecf3588c6b9d007e8dbb4a3c6baacec62322 | |
| parent | 7eae27cd12a2d305ffad41a8e10cff3bb8c0dcb0 (diff) | |
| parent | f2994f5341e03b8680a88abc5f1dee950033c3a9 (diff) | |
| download | linux-f3033eb79136dd27b17e7a192fac0155ceab5eb8.tar.gz linux-f3033eb79136dd27b17e7a192fac0155ceab5eb8.tar.bz2 linux-f3033eb79136dd27b17e7a192fac0155ceab5eb8.zip | |
Merge tag 'leds-next-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
Pull LED updates from Lee Jones:
"Core Frameworks:
- Ensure seldom updated triggers have a brightness value before first
update
New Device Support:
- Add support for Simatic IPC Device BX_59A to IPC LEDs Core
- Add support for Qualcomm PMI8950 PWM to LPG Core
New Functionality:
- Add a bunch of new LED function identifiers
- Add support for High Resolution Timers in LED Trigger Patten
Fix-ups:
- Shift out Audio Trigger to the Sound subsystem
- Convert suitable calls to devm_* managed resources
- Device Tree binding adaptions/conversions/creation
- Remove superfluous code/variables/attributes and simplify overall
- Use/convert to new/better APIs/helpers/MACROs instead of
hand-rolling implementations
Bug Fixes:
- Repair enabling Torch Mode from V4L2 on the second LED
- Ensure PWM is disabled when suspending"
* tag 'leds-next-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (28 commits)
leds: mt6370: Remove unused field 'reg_cfgs' from 'struct mt6370_priv'
leds: lp50xx: Remove unused field 'num_of_banked_leds' from 'struct lp50xx'
leds: lp50xx: Remove unused field 'bank_modules' from 'struct lp50xx_led'
leds: aat1290: Remove unused field 'torch_brightness' from 'struct aat1290_led'
leds: sun50i-a100: Use match_string() helper to simplify the code
leds: pwm: Disable PWM when going to suspend
leds: trigger: pattern: Add support for hrtimer
leds: mt6360: Fix the second LED can not enable torch mode by V4L2
dt-bindings: leds: leds-qcom-lpg: Add support for PMI8950 PWM
leds: qcom-lpg: Add support for PMI8950 PWM
leds: apu: Remove duplicate DMI lookup data
leds: trigger: netdev: Remove not needed call to led_set_brightness in deactivate
dt-bindings: leds: Add LED_FUNCTION_SPEED_* for link speed on LAN/WAN
dt-bindings: leds: Add LED_FUNCTION_MOBILE for mobile network
leds: simatic-ipc-leds-gpio: Add support for module BX-59A
dt-bindings: leds: qcom-lpg: Document PM6150L compatible
dt-bindings: leds: pca963x: Convert text bindings to YAML
leds: an30259a: Use devm_mutex_init() for mutex initialization
leds: mlxreg: Use devm_mutex_init() for mutex initialization
leds: nic78bx: Use devm API to cleanup module's resources
...
34 files changed, 501 insertions, 275 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-pattern b/Documentation/ABI/testing/sysfs-class-led-trigger-pattern index 8c57d2780554..22f28f2e9ac4 100644 --- a/Documentation/ABI/testing/sysfs-class-led-trigger-pattern +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-pattern @@ -12,6 +12,16 @@ Description: The exact format is described in: Documentation/devicetree/bindings/leds/leds-trigger-pattern.txt +What: /sys/class/leds/<led>/hr_pattern +Date: April 2024 +Description: + Specify a software pattern for the LED, that supports altering + the brightness for the specified duration with one software + timer. It can do gradual dimming and step change of brightness. + + Unlike the /sys/class/leds/<led>/pattern, this attribute runs + a pattern on high-resolution timer (hrtimer). + What: /sys/class/leds/<led>/hw_pattern Date: September 2018 KernelVersion: 4.20 diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml index 54a428d3d46f..8b82c45d1a48 100644 --- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -27,11 +27,16 @@ properties: - qcom,pm8994-lpg - qcom,pmc8180c-lpg - qcom,pmi632-lpg + - qcom,pmi8950-pwm - qcom,pmi8994-lpg - qcom,pmi8998-lpg - qcom,pmk8550-pwm - items: - enum: + - qcom,pm6150l-lpg + - const: qcom,pm8150l-lpg + - items: + - enum: - qcom,pm8550-pwm - const: qcom,pm8350c-pwm @@ -142,6 +147,7 @@ allOf: - qcom,pm8941-lpg - qcom,pm8994-lpg - qcom,pmc8180c-lpg + - qcom,pmi8950-pwm - qcom,pmi8994-lpg - qcom,pmi8998-lpg - qcom,pmk8550-pwm @@ -290,5 +296,3 @@ examples: label = "blue"; }; }; - -... diff --git a/Documentation/devicetree/bindings/leds/nxp,pca963x.yaml b/Documentation/devicetree/bindings/leds/nxp,pca963x.yaml new file mode 100644 index 000000000000..938d0e48fe51 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/nxp,pca963x.yaml @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/nxp,pca963x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP PCA963x LED controllers + +maintainers: + - Laurent Pinchart <laurent.pinchart@ideasonboard.com> + +description: | + The NXP PCA963x are I2C-controlled LED drivers optimized for + Red/Green/Blue/Amber (RGBA) color mixing applications. Each LED is + individually controllable and has its own PWM controller. + + Datasheets are available at + + - https://www.nxp.com/docs/en/data-sheet/PCA9632.pdf + - https://www.nxp.com/docs/en/data-sheet/PCA9633.pdf + - https://www.nxp.com/docs/en/data-sheet/PCA9634.pdf + - https://www.nxp.com/docs/en/data-sheet/PCA9635.pdf + +properties: + compatible: + enum: + - nxp,pca9632 + - nxp,pca9633 + - nxp,pca9634 + - nxp,pca9635 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + nxp,hw-blink: + type: boolean + description: + Use hardware blinking instead of software blinking + + nxp,inverted-out: + type: boolean + description: + Invert the polarity of the generated PWM. + + nxp,period-scale: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + In some configurations, the chip blinks faster than expected. This + parameter provides a scaling ratio (fixed point, decimal divided by 1000) + to compensate, e.g. 1300=1.3x and 750=0.75x. + + nxp,totem-pole: + type: boolean + description: + Use totem pole (push-pull) instead of open-drain (pca9632 defaults to + open-drain, newer chips to totem pole). + +patternProperties: + "^led@[0-9a-f]+$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 0 + + required: + - reg + +allOf: + - if: + properties: + compatible: + contains: + enum: + - nxp,pca9632 + - nxp,pca9633 + then: + patternProperties: + "^led@[0-9a-f]+$": + properties: + reg: + maximum: 3 + else: + patternProperties: + "^led@[0-9a-f]+$": + properties: + reg: + maximum: 7 + +additionalProperties: false + +examples: + - | + #include <dt-bindings/leds/common.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_RED>; + function = LED_FUNCTION_STATUS; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_STATUS; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_STATUS; + }; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_WHITE>; + function = LED_FUNCTION_STATUS; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/leds/pca963x.txt b/Documentation/devicetree/bindings/leds/pca963x.txt deleted file mode 100644 index 4eee41482041..000000000000 --- a/Documentation/devicetree/bindings/leds/pca963x.txt +++ /dev/null @@ -1,52 +0,0 @@ -LEDs connected to pca9632, pca9633 or pca9634 - -Required properties: -- compatible : should be : "nxp,pca9632", "nxp,pca9633", "nxp,pca9634" or "nxp,pca9635" - -Optional properties: -- nxp,totem-pole : use totem pole (push-pull) instead of open-drain (pca9632 defaults - to open-drain, newer chips to totem pole) -- nxp,hw-blink : use hardware blinking instead of software blinking -- nxp,period-scale : In some configurations, the chip blinks faster than expected. - This parameter provides a scaling ratio (fixed point, decimal divided - by 1000) to compensate, e.g. 1300=1.3x and 750=0.75x. -- nxp,inverted-out: invert the polarity of the generated PWM - -Each led is represented as a sub-node of the nxp,pca963x device. - -LED sub-node properties: -- label : (optional) see Documentation/devicetree/bindings/leds/common.txt -- reg : number of LED line (could be from 0 to 3 in pca9632 or pca9633, - 0 to 7 in pca9634, or 0 to 15 in pca9635) -- linux,default-trigger : (optional) - see Documentation/devicetree/bindings/leds/common.txt - -Examples: - -pca9632: pca9632 { - compatible = "nxp,pca9632"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x62>; - - red@0 { - label = "red"; - reg = <0>; - linux,default-trigger = "none"; - }; - green@1 { - label = "green"; - reg = <1>; - linux,default-trigger = "none"; - }; - blue@2 { - label = "blue"; - reg = <2>; - linux,default-trigger = "none"; - }; - unused@3 { - label = "unused"; - reg = <3>; - linux,default-trigger = "none"; - }; -}; diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index cdf2a782dee1..7827b2b392f6 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -152,7 +152,6 @@ CONFIG_LEDS_TRIGGER_CAMERA=m CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_LEDS_TRIGGER_NETDEV=y CONFIG_LEDS_TRIGGER_PATTERN=y -CONFIG_LEDS_TRIGGER_AUDIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_JZ4740=y CONFIG_DMADEVICES=y diff --git a/drivers/leds/flash/leds-aat1290.c b/drivers/leds/flash/leds-aat1290.c index 0195935a7c99..e8f9dd293592 100644 --- a/drivers/leds/flash/leds-aat1290.c +++ b/drivers/leds/flash/leds-aat1290.c @@ -77,8 +77,6 @@ struct aat1290_led { int *mm_current_scale; /* device mode */ bool movie_mode; - /* brightness cache */ - unsigned int torch_brightness; }; static struct aat1290_led *fled_cdev_to_led( diff --git a/drivers/leds/flash/leds-mt6360.c b/drivers/leds/flash/leds-mt6360.c index a90de82f4568..1b75b4d36834 100644 --- a/drivers/leds/flash/leds-mt6360.c +++ b/drivers/leds/flash/leds-mt6360.c @@ -241,11 +241,21 @@ static int mt6360_strobe_set(struct led_classdev_flash *fl_cdev, bool state) u32 enable_mask = MT6360_STROBEN_MASK | MT6360_FLCSEN_MASK(led->led_no); u32 val = state ? MT6360_FLCSEN_MASK(led->led_no) : 0; u32 prev = priv->fled_strobe_used, curr; - int ret; + int ret = 0; mutex_lock(&priv->lock); /* + * If the state of the upcoming change is the same as the current LED + * device state, then skip the subsequent code to avoid conflict + * with the flow of turning on LED torch mode in V4L2. + */ + if (state == !!(BIT(led->led_no) & prev)) { + dev_info(lcdev->dev, "No change in strobe state [0x%x]\n", prev); + goto unlock; + } + + /* * Only one set of flash control logic, use the flag to avoid torch is * currently used */ diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 0f5ac30053ad..b1b323b19301 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -194,11 +194,11 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) spin_unlock(&trig->leddev_list_lock); led_cdev->trigger = trig; + ret = 0; if (trig->activate) ret = trig->activate(led_cdev); else - ret = 0; - + led_set_brightness(led_cdev, trig->brightness); if (ret) goto err_activate; @@ -387,6 +387,8 @@ void led_trigger_event(struct led_trigger *trig, if (!trig) return; + trig->brightness = brightness; + rcu_read_lock(); list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c index 0216afed3b6e..decfca447d8a 100644 --- a/drivers/leds/leds-an30259a.c +++ b/drivers/leds/leds-an30259a.c @@ -283,7 +283,10 @@ static int an30259a_probe(struct i2c_client *client) if (err < 0) return err; - mutex_init(&chip->mutex); + err = devm_mutex_init(&client->dev, &chip->mutex); + if (err) + return err; + chip->client = client; i2c_set_clientdata(client, chip); @@ -317,17 +320,9 @@ static int an30259a_probe(struct i2c_client *client) return 0; exit: - mutex_destroy(&chip->mutex); return err; } -static void an30259a_remove(struct i2c_client *client) -{ - struct an30259a *chip = i2c_get_clientdata(client); - - mutex_destroy(&chip->mutex); -} - static const struct of_device_id an30259a_match_table[] = { { .compatible = "panasonic,an30259a", }, { /* sentinel */ }, @@ -347,7 +342,6 @@ static struct i2c_driver an30259a_driver = { .of_match_table = an30259a_match_table, }, .probe = an30259a_probe, - .remove = an30259a_remove, .id_table = an30259a_id, }; diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c index c409b80c236d..1c116aaa9b6e 100644 --- a/drivers/leds/leds-apu.c +++ b/drivers/leds/leds-apu.c @@ -181,8 +181,7 @@ static int __init apu_led_init(void) struct platform_device *pdev; int err; - if (!(dmi_match(DMI_SYS_VENDOR, "PC Engines") && - (dmi_match(DMI_PRODUCT_NAME, "APU") || dmi_match(DMI_PRODUCT_NAME, "apu1")))) { + if (!dmi_check_system(apu_led_dmi_table)) { pr_err("No PC Engines APUv1 board detected. For APUv2,3 support, enable CONFIG_PCENGINES_APU2\n"); return -ENODEV; } diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c index 6c8c9f2c19e3..f9d9844e0273 100644 --- a/drivers/leds/leds-aw200xx.c +++ b/drivers/leds/leds-aw200xx.c @@ -530,6 +530,16 @@ static const struct regmap_config aw200xx_regmap_config = { .disable_locking = true, }; +static void aw200xx_chip_reset_action(void *data) +{ + aw200xx_chip_reset(data); +} + +static void aw200xx_disable_action(void *data) +{ + aw200xx_disable(data); +} + static int aw200xx_probe(struct i2c_client *client) { const struct aw200xx_chipdef *cdef; @@ -568,11 +578,17 @@ static int aw200xx_probe(struct i2c_client *client) aw200xx_enable(chip); + ret = devm_add_action(&client->dev, aw200xx_disable_action, chip); + if (ret) + return ret; + ret = aw200xx_chip_check(chip); if (ret) return ret; - mutex_init(&chip->mutex); + ret = devm_mutex_init(&client->dev, &chip->mutex); + if (ret) + return ret; /* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */ mutex_lock(&chip->mutex); @@ -581,6 +597,10 @@ static int aw200xx_probe(struct i2c_client *client) if (ret) goto out_unlock; + ret = devm_add_action(&client->dev, aw200xx_chip_reset_action, chip); + if (ret) + goto out_unlock; + ret = aw200xx_probe_fw(&client->dev, chip); if (ret) goto out_unlock; @@ -595,15 +615,6 @@ out_unlock: return ret; } -static void aw200xx_remove(struct i2c_client *client) -{ - struct aw200xx *chip = i2c_get_clientdata(client); - - aw200xx_chip_reset(chip); - aw200xx_disable(chip); - mutex_destroy(&chip->mutex); -} - static const struct aw200xx_chipdef aw20036_cdef = { .channels = 36, .display_size_rows_max = 3, @@ -652,7 +663,6 @@ static struct i2c_driver aw200xx_driver = { .of_match_table = aw200xx_match_table, }, .probe = aw200xx_probe, - .remove = aw200xx_remove, .id_table = aw200xx_id, }; module_i2c_driver(aw200xx_driver); diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c index 17235a5e576a..6475eadcb0df 100644 --- a/drivers/leds/leds-aw2013.c +++ b/drivers/leds/leds-aw2013.c @@ -320,6 +320,11 @@ static int aw2013_probe_dt(struct aw2013 *chip) return 0; } +static void aw2013_chip_disable_action(void *data) +{ + aw2013_chip_disable(data); +} + static const struct regmap_config aw2013_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -336,7 +341,10 @@ static int aw2013_probe(struct i2c_client *client) if (!chip) return -ENOMEM; - mutex_init(&chip->mutex); + ret = devm_mutex_init(&client->dev, &chip->mutex); + if (ret) + return ret; + mutex_lock(&chip->mutex); chip->client = client; @@ -384,6 +392,10 @@ static int aw2013_probe(struct i2c_client *client) goto error_reg; } + ret = devm_add_action(&client->dev, aw2013_chip_disable_action, chip); + if (ret) + goto error_reg; + ret = aw2013_probe_dt(chip); if (ret < 0) goto error_reg; @@ -406,19 +418,9 @@ error_reg: error: mutex_unlock(&chip->mutex); - mutex_destroy(&chip->mutex); return ret; } -static void aw2013_remove(struct i2c_client *client) -{ - struct aw2013 *chip = i2c_get_clientdata(client); - - aw2013_chip_disable(chip); - - mutex_destroy(&chip->mutex); -} - static const struct of_device_id aw2013_match_table[] = { { .compatible = "awinic,aw2013", }, { /* sentinel */ }, @@ -432,7 +434,6 @@ static struct i2c_driver aw2013_driver = { .of_match_table = aw2013_match_table, }, .probe = aw2013_probe, - .remove = aw2013_remove, }; module_i2c_driver(aw2013_driver); diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c index 13662a4aa1f2..8c90701dc50d 100644 --- a/drivers/leds/leds-lm3532.c +++ b/drivers/leds/leds-lm3532.c @@ -542,6 +542,13 @@ static int lm3532_parse_als(struct lm3532_data *priv) return ret; } +static void gpio_set_low_action(void *data) +{ + struct lm3532_data *priv = data; + + gpiod_direction_output(priv->enable_gpio, 0); +} + static int lm3532_parse_node(struct lm3532_data *priv) { struct fwnode_handle *child = NULL; @@ -556,6 +563,12 @@ static int lm3532_parse_node(struct lm3532_data *priv) if (IS_ERR(priv->enable_gpio)) priv->enable_gpio = NULL; + if (priv->enable_gpio) { + ret = devm_add_action(&priv->client->dev, gpio_set_low_action, priv); + if (ret) + return ret; + } + priv->regulator = devm_regulator_get(&priv->client->dev, "vin"); if (IS_ERR(priv->regulator)) priv->regulator = NULL; @@ -691,7 +704,10 @@ static int lm3532_probe(struct i2c_client *client) return ret; } - mutex_init(&drvdata->lock); + ret = devm_mutex_init(&client->dev, &drvdata->lock); + if (ret) + return ret; + i2c_set_clientdata(client, drvdata); ret = lm3532_parse_node(drvdata); @@ -703,16 +719,6 @@ static int lm3532_probe(struct i2c_client *client) return ret; } -static void lm3532_remove(struct i2c_client *client) -{ - struct lm3532_data *drvdata = i2c_get_clientdata(client); - - mutex_destroy(&drvdata->lock); - - if (drvdata->enable_gpio) - gpiod_direction_output(drvdata->enable_gpio, 0); -} - static const struct of_device_id of_lm3532_leds_match[] = { { .compatible = "ti,lm3532", }, {}, @@ -727,7 +733,6 @@ MODULE_DEVICE_TABLE(i2c, lm3532_id); static struct i2c_driver lm3532_i2c_driver = { .probe = lm3532_probe, - .remove = lm3532_remove, .id_table = lm3532_id, .driver = { .name = LM3532_NAME, diff --git a/drivers/leds/leds-lp3952.c b/drivers/leds/leds-lp3952.c index 5d18bbfd1f23..ff7bae2447dd 100644 --- a/drivers/leds/leds-lp3952.c +++ b/drivers/leds/leds-lp3952.c @@ -207,6 +207,13 @@ static const struct regmap_config lp3952_regmap = { .cache_type = REGCACHE_MAPLE, }; +static void gpio_set_low_action(void *data) +{ + struct lp3952_led_array *priv = data; + + gpiod_set_value(priv->enable_gpio, 0); +} + static int lp3952_probe(struct i2c_client *client) { int status; @@ -226,6 +233,10 @@ static int lp3952_probe(struct i2c_client *client) return status; } + status = devm_add_action(&client->dev, gpio_set_low_action, priv); + if (status) + return status; + priv->regmap = devm_regmap_init_i2c(client, &lp3952_regmap); if (IS_ERR(priv->regmap)) { int err = PTR_ERR(priv->regmap); @@ -254,15 +265,6 @@ static int lp3952_probe(struct i2c_client *client) return 0; } -static void lp3952_remove(struct i2c_client *client) -{ - struct lp3952_led_array *priv; - - priv = i2c_get_clientdata(client); - lp3952_on_off(priv, LP3952_LED_ALL, false); - gpiod_set_value(priv->enable_gpio, 0); -} - static const struct i2c_device_id lp3952_id[] = { {LP3952_NAME, 0}, {} @@ -274,7 +276,6 @@ static struct i2c_driver lp3952_i2c_driver = { .name = LP3952_NAME, }, .probe = lp3952_probe, - .remove = lp3952_remove, .id_table = lp3952_id, }; diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 68c4d9967d68..175d4b06659b 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -265,7 +265,6 @@ static const struct lp50xx_chip_info lp50xx_chip_info_tbl[] = { struct lp50xx_led { struct led_classdev_mc mc_cdev; struct lp50xx *priv; - unsigned long bank_modules; u8 ctrl_bank_enabled; int led_number; }; @@ -279,7 +278,6 @@ struct lp50xx_led { * @dev: pointer to the devices device struct * @lock: lock for reading/writing the device * @chip_info: chip specific information (ie num_leds) - * @num_of_banked_leds: holds the number of banked LEDs * @leds: array of LED strings */ struct lp50xx { @@ -290,7 +288,6 @@ struct lp50xx { struct device *dev; struct mutex lock; const struct lp50xx_chip_info *chip_info; - int num_of_banked_leds; /* This needs to be at the end of the struct */ struct lp50xx_led leds[]; @@ -404,8 +401,6 @@ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, return -EINVAL; } - priv->num_of_banked_leds = num_leds; - ret = fwnode_property_read_u32_array(child, "reg", led_banks, num_leds); if (ret) { dev_err(priv->dev, "reg property is missing\n"); diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c index 5595788d98d2..1b70de72376c 100644 --- a/drivers/leds/leds-mlxreg.c +++ b/drivers/leds/leds-mlxreg.c @@ -256,6 +256,7 @@ static int mlxreg_led_probe(struct platform_device *pdev) { struct mlxreg_core_platform_data *led_pdata; struct mlxreg_led_priv_data *priv; + int err; led_pdata = dev_get_platdata(&pdev->dev); if (!led_pdata) { @@ -267,26 +268,21 @@ static int mlxreg_led_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - mutex_init(&priv->access_lock); + err = devm_mutex_init(&pdev->dev, &priv->access_lock); + if (err) + return err; + priv->pdev = pdev; priv->pdata = led_pdata; return mlxreg_led_config(priv); } -static void mlxreg_led_remove(struct platform_device *pdev) -{ - struct mlxreg_led_priv_data *priv = dev_get_drvdata(&pdev->dev); - - mutex_destroy(&priv->access_lock); -} - static struct platform_driver mlxreg_led_driver = { .driver = { .name = "leds-mlxreg", }, .probe = mlxreg_led_probe, - .remove_new = mlxreg_led_remove, }; module_platform_driver(mlxreg_led_driver); diff --git a/drivers/leds/leds-nic78bx.c b/drivers/leds/leds-nic78bx.c index a86b43dd995e..282d9e4cf116 100644 --- a/drivers/leds/leds-nic78bx.c +++ b/drivers/leds/leds-nic78bx.c @@ -118,6 +118,15 @@ static struct nic78bx_led nic78bx_leds[] = { } }; +static void lock_led_reg_action(void *data) +{ + struct nic78bx_led_data *led_data = data; + + /* Lock LED register */ + outb(NIC78BX_LOCK_VALUE, + led_data->io_base + NIC78BX_LOCK_REG_OFFSET); +} + static int nic78bx_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -152,6 +161,10 @@ static int nic78bx_probe( |
