Commit 5f9cc570 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'leds_for_4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds

Pull LED updates from Jacek Anaszewski:
 "LED class drivers improvements:

  leds-pca955x:
   - add Device Tree support and bindings
   - use devm_led_classdev_register()
   - add GPIO support
   - prevent crippled LED class device name
   - check for I2C errors

  leds-gpio:
   - add optional retain-state-shutdown DT property
   - allow LED to retain state at shutdown

  leds-tlc591xx:
   - merge conditional tests
   - add missing of_node_put

  leds-powernv:
   - delete an error message for a failed memory allocation in
     powernv_led_create()

  leds-is31fl32xx.c
   - convert to using custom %pOF printf format specifier

  Constify attribute_group structures in:
   - leds-blinkm
   - leds-lm3533

  Make several arrays static const in:
   - leds-aat1290
   - leds-lp5521
   - leds-lp5562
   - leds-lp8501"

* tag 'leds_for_4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds:
  leds: pca955x: check for I2C errors
  leds: gpio: Allow LED to retain state at shutdown
  dt-bindings: leds: gpio: Add optional retain-state-shutdown property
  leds: powernv: Delete an error message for a failed memory allocation in powernv_led_create()
  leds: lp8501: make several arrays static const
  leds: lp5562: make several arrays static const
  leds: lp5521: make several arrays static const
  leds: aat1290: make array max_mm_current_percent static const
  leds: pca955x: Prevent crippled LED device name
  leds: lm3533: constify attribute_group structure
  dt-bindings: leds: add pca955x
  leds: pca955x: add GPIO support
  leds: pca955x: use devm_led_classdev_register
  leds: pca955x: add device tree support
  leds: Convert to using %pOF instead of full_name
  leds: blinkm: constify attribute_group structures.
  leds: tlc591xx: add missing of_node_put
  leds: tlc591xx: merge conditional tests
parents cd7b34fe 1591caf2
......@@ -18,6 +18,9 @@ LED sub-node properties:
see Documentation/devicetree/bindings/leds/common.txt
- retain-state-suspended: (optional) The suspend state can be retained.Such
as charge-led gpio.
- retain-state-shutdown: (optional) Retain the state of the LED on shutdown.
Useful in BMC systems, for example when the BMC is rebooted while the host
remains up.
- panic-indicator : (optional)
see Documentation/devicetree/bindings/leds/common.txt
......
* NXP - pca955x LED driver
The PCA955x family of chips are I2C LED blinkers whose pins not used
to control LEDs can be used as general purpose I/Os. The GPIO pins can
be input or output, and output pins can also be pulse-width controlled.
Required properties:
- compatible : should be one of :
"nxp,pca9550"
"nxp,pca9551"
"nxp,pca9552"
"nxp,pca9553"
- #address-cells: must be 1
- #size-cells: must be 0
- reg: I2C slave address. depends on the model.
Optional properties:
- gpio-controller: allows pins to be used as GPIOs.
- #gpio-cells: must be 2.
- gpio-line-names: define the names of the GPIO lines
LED sub-node properties:
- reg : number of LED line.
from 0 to 1 for the pca9550
from 0 to 7 for the pca9551
from 0 to 15 for the pca9552
from 0 to 3 for the pca9553
- type: (optional) either
PCA9532_TYPE_NONE
PCA9532_TYPE_LED
PCA9532_TYPE_GPIO
see dt-bindings/leds/leds-pca955x.h (default to LED)
- label : (optional)
see Documentation/devicetree/bindings/leds/common.txt
- linux,default-trigger : (optional)
see Documentation/devicetree/bindings/leds/common.txt
Examples:
pca9552: pca9552@60 {
compatible = "nxp,pca9552";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x60>;
gpio-controller;
#gpio-cells = <2>;
gpio-line-names = "GPIO12", "GPIO13", "GPIO14", "GPIO15";
gpio@12 {
reg = <12>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@13 {
reg = <13>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@14 {
reg = <14>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@15 {
reg = <15>;
type = <PCA955X_TYPE_GPIO>;
};
led@0 {
label = "red:power";
linux,default-trigger = "default-on";
reg = <0>;
type = <PCA955X_TYPE_LED>;
};
led@1 {
label = "green:power";
reg = <1>;
type = <PCA955X_TYPE_LED>;
};
led@2 {
label = "pca9552:yellow";
reg = <2>;
type = <PCA955X_TYPE_LED>;
};
led@3 {
label = "pca9552:white";
reg = <3>;
type = <PCA955X_TYPE_LED>;
};
};
......@@ -386,6 +386,17 @@ config LEDS_PCA955X
LED driver chips accessed via the I2C bus. Supported
devices include PCA9550, PCA9551, PCA9552, and PCA9553.
config LEDS_PCA955X_GPIO
bool "Enable GPIO support for PCA955X"
depends on LEDS_PCA955X
depends on GPIOLIB
help
Allow unused pins on PCA955X to be used as gpio.
To use a pin as gpio the pin type should be set to
PCA955X_TYPE_GPIO in the device tree.
config LEDS_PCA963X
tristate "LED support for PCA963x I2C chip"
depends on LEDS_CLASS
......
......@@ -314,8 +314,10 @@ static void aat1290_led_validate_mm_current(struct aat1290_led *led,
static int init_mm_current_scale(struct aat1290_led *led,
struct aat1290_led_config_data *cfg)
{
int max_mm_current_percent[] = { 20, 22, 25, 28, 32, 36, 40, 45, 50, 56,
63, 71, 79, 89, 100 };
static const int max_mm_current_percent[] = {
20, 22, 25, 28, 32, 36, 40, 45, 50, 56,
63, 71, 79, 89, 100
};
int i, max_mm_current =
AAT1290_MAX_MM_CURRENT(cfg->max_flash_current);
......
......@@ -298,7 +298,7 @@ static struct attribute *blinkm_attrs[] = {
NULL,
};
static struct attribute_group blinkm_group = {
static const struct attribute_group blinkm_group = {
.name = "blinkm",
.attrs = blinkm_attrs,
};
......
......@@ -134,6 +134,8 @@ static int create_gpio_led(const struct gpio_led *template,
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
if (template->panic_indicator)
led_dat->cdev.flags |= LED_PANIC_INDICATOR;
if (template->retain_state_shutdown)
led_dat->cdev.flags |= LED_RETAIN_AT_SHUTDOWN;
ret = gpiod_direction_output(led_dat->gpiod, state);
if (ret < 0)
......@@ -205,6 +207,8 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
if (fwnode_property_present(child, "retain-state-suspended"))
led.retain_state_suspended = 1;
if (fwnode_property_present(child, "retain-state-shutdown"))
led.retain_state_shutdown = 1;
if (fwnode_property_present(child, "panic-indicator"))
led.panic_indicator = 1;
......@@ -267,7 +271,8 @@ static void gpio_led_shutdown(struct platform_device *pdev)
for (i = 0; i < priv->num_leds; i++) {
struct gpio_led_data *led = &priv->leds[i];
gpio_led_set(&led->cdev, LED_OFF);
if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
gpio_led_set(&led->cdev, LED_OFF);
}
}
......
......@@ -348,8 +348,8 @@ static int is31fl32xx_parse_child_dt(const struct device *dev,
ret = of_property_read_u32(child, "reg", &reg);
if (ret || reg < 1 || reg > led_data->priv->cdef->channels) {
dev_err(dev,
"Child node %s does not have a valid reg property\n",
child->full_name);
"Child node %pOF does not have a valid reg property\n",
child);
return -EINVAL;
}
led_data->channel = reg;
......
......@@ -626,7 +626,7 @@ static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
return mode;
};
static struct attribute_group lm3533_led_attribute_group = {
static const struct attribute_group lm3533_led_attribute_group = {
.is_visible = lm3533_led_attr_is_visible,
.attrs = lm3533_led_attributes
};
......
......@@ -134,13 +134,13 @@ static void lp5521_set_led_current(struct lp55xx_led *led, u8 led_current)
static void lp5521_load_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
static const u8 mask[] = {
[LP55XX_ENGINE_1] = LP5521_MODE_R_M,
[LP55XX_ENGINE_2] = LP5521_MODE_G_M,
[LP55XX_ENGINE_3] = LP5521_MODE_B_M,
};
u8 val[] = {
static const u8 val[] = {
[LP55XX_ENGINE_1] = LP5521_LOAD_R,
[LP55XX_ENGINE_2] = LP5521_LOAD_G,
[LP55XX_ENGINE_3] = LP5521_LOAD_B,
......@@ -160,7 +160,7 @@ static void lp5521_stop_all_engines(struct lp55xx_chip *chip)
static void lp5521_stop_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
static const u8 mask[] = {
[LP55XX_ENGINE_1] = LP5521_MODE_R_M,
[LP55XX_ENGINE_2] = LP5521_MODE_G_M,
[LP55XX_ENGINE_3] = LP5521_MODE_B_M,
......@@ -226,7 +226,7 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip,
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
u8 addr[] = {
static const u8 addr[] = {
[LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM,
[LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM,
[LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM,
......
......@@ -116,7 +116,7 @@ static inline void lp5562_wait_enable_done(void)
static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
{
u8 addr[] = {
static const u8 addr[] = {
LP5562_REG_R_CURRENT,
LP5562_REG_G_CURRENT,
LP5562_REG_B_CURRENT,
......@@ -130,13 +130,13 @@ static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
static void lp5562_load_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
static const u8 mask[] = {
[LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M,
[LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M,
[LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M,
};
u8 val[] = {
static const u8 val[] = {
[LP55XX_ENGINE_1] = LP5562_LOAD_ENG1,
[LP55XX_ENGINE_2] = LP5562_LOAD_ENG2,
[LP55XX_ENGINE_3] = LP5562_LOAD_ENG3,
......@@ -211,7 +211,7 @@ static int lp5562_update_firmware(struct lp55xx_chip *chip,
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 pattern[LP5562_PROGRAM_LENGTH] = {0};
u8 addr[] = {
static const u8 addr[] = {
[LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1,
[LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2,
[LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3,
......@@ -314,7 +314,7 @@ static int lp5562_post_init_device(struct lp55xx_chip *chip)
static int lp5562_led_brightness(struct lp55xx_led *led)
{
struct lp55xx_chip *chip = led->chip;
u8 addr[] = {
static const u8 addr[] = {
LP5562_REG_R_PWM,
LP5562_REG_G_PWM,
LP5562_REG_B_PWM,
......
......@@ -118,19 +118,19 @@ static int lp8501_post_init_device(struct lp55xx_chip *chip)
static void lp8501_load_engine(struct lp55xx_chip *chip)
{
enum lp55xx_engine_index idx = chip->engine_idx;
u8 mask[] = {
static const u8 mask[] = {
[LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M,
[LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M,
[LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M,
};
u8 val[] = {
static const u8 val[] = {
[LP55XX_ENGINE_1] = LP8501_LOAD_ENG1,
[LP55XX_ENGINE_2] = LP8501_LOAD_ENG2,
[LP55XX_ENGINE_3] = LP8501_LOAD_ENG3,
};
u8 page_sel[] = {
static const u8 page_sel[] = {
[LP55XX_ENGINE_1] = LP8501_PAGE_ENG1,
[LP55XX_ENGINE_2] = LP8501_PAGE_ENG2,
[LP55XX_ENGINE_3] = LP8501_PAGE_ENG3,
......
This diff is collapsed.
......@@ -224,12 +224,8 @@ static int powernv_led_create(struct device *dev,
powernv_led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
powernv_led->loc_code,
led_type_desc);
if (!powernv_led->cdev.name) {
dev_err(dev,
"%s: Memory allocation failed for classdev name\n",
__func__);
if (!powernv_led->cdev.name)
return -ENOMEM;
}
powernv_led->cdev.brightness_set_blocking = powernv_brightness_set;
powernv_led->cdev.brightness_get = powernv_brightness_get;
......
......@@ -230,12 +230,15 @@ tlc591xx_probe(struct i2c_client *client,
for_each_child_of_node(np, child) {
err = of_property_read_u32(child, "reg", &reg);
if (err)
if (err) {
of_node_put(child);
return err;
if (reg < 0 || reg >= tlc591xx->max_leds)
return -EINVAL;
if (priv->leds[reg].active)
}
if (reg < 0 || reg >= tlc591xx->max_leds ||
priv->leds[reg].active) {
of_node_put(child);
return -EINVAL;
}
priv->leds[reg].active = true;
priv->leds[reg].ldev.name =
of_get_property(child, "label", NULL) ? : child->name;
......
/*
* This header provides constants for pca955x LED bindings.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef _DT_BINDINGS_LEDS_PCA955X_H
#define _DT_BINDINGS_LEDS_PCA955X_H
#define PCA955X_TYPE_NONE 0
#define PCA955X_TYPE_LED 1
#define PCA955X_TYPE_GPIO 2
#endif /* _DT_BINDINGS_LEDS_PCA955X_H */
......@@ -49,6 +49,7 @@ struct led_classdev {
#define LED_HW_PLUGGABLE (1 << 19)
#define LED_PANIC_INDICATOR (1 << 20)
#define LED_BRIGHT_HW_CHANGED (1 << 21)
#define LED_RETAIN_AT_SHUTDOWN (1 << 22)
/* set_brightness_work / blink_timer flags, atomic, private. */
unsigned long work_flags;
......@@ -392,6 +393,7 @@ struct gpio_led {
unsigned retain_state_suspended : 1;
unsigned panic_indicator : 1;
unsigned default_state : 2;
unsigned retain_state_shutdown : 1;
/* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */
struct gpio_desc *gpiod;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment