From bb29b9cccd95feeb43e11e9b1c2479777082e28a Mon Sep 17 00:00:00 2001 From: Anders Darander Date: Thu, 27 Apr 2017 08:37:33 +0200 Subject: leds: pca963x: Add bindings to invert polarity Add a new DT property, nxp,inverted-out, to invert the polarity of the output. Tested on PCA9634. Signed-off-by: Anders Darander Acked-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- Documentation/devicetree/bindings/leds/pca963x.txt | 1 + drivers/leds/leds-pca963x.c | 17 +++++++++++++++-- include/linux/platform_data/leds-pca963x.h | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/leds/pca963x.txt b/Documentation/devicetree/bindings/leds/pca963x.txt index dfbdb123a9bf..4eee41482041 100644 --- a/Documentation/devicetree/bindings/leds/pca963x.txt +++ b/Documentation/devicetree/bindings/leds/pca963x.txt @@ -10,6 +10,7 @@ Optional properties: - 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. diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c index ded1e4dac36a..3bf9a1271819 100644 --- a/drivers/leds/leds-pca963x.c +++ b/drivers/leds/leds-pca963x.c @@ -342,6 +342,12 @@ pca963x_dt_init(struct i2c_client *client, struct pca963x_chipdef *chip) if (of_property_read_u32(np, "nxp,period-scale", &chip->scaling)) chip->scaling = 1000; + /* default to non-inverted output, unless inverted is specified */ + if (of_property_read_bool(np, "nxp,inverted-out")) + pdata->dir = PCA963X_INVERTED; + else + pdata->dir = PCA963X_NORMAL; + return pdata; } @@ -452,11 +458,18 @@ static int pca963x_probe(struct i2c_client *client, i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4)); if (pdata) { + u8 mode2 = i2c_smbus_read_byte_data(pca963x->chip->client, + PCA963X_MODE2); /* Configure output: open-drain or totem pole (push-pull) */ if (pdata->outdrv == PCA963X_OPEN_DRAIN) - i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01); + mode2 |= 0x01; else - i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x05); + mode2 |= 0x05; + /* Configure direction: normal or inverted */ + if (pdata->dir == PCA963X_INVERTED) + mode2 |= 0x10; + i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2, + mode2); } return 0; diff --git a/include/linux/platform_data/leds-pca963x.h b/include/linux/platform_data/leds-pca963x.h index e731f0036329..54e845ffb5ed 100644 --- a/include/linux/platform_data/leds-pca963x.h +++ b/include/linux/platform_data/leds-pca963x.h @@ -33,10 +33,16 @@ enum pca963x_blink_type { PCA963X_HW_BLINK, }; +enum pca963x_direction { + PCA963X_NORMAL, + PCA963X_INVERTED, +}; + struct pca963x_platform_data { struct led_platform_data leds; enum pca963x_outdrv outdrv; enum pca963x_blink_type blink_type; + enum pca963x_direction dir; }; #endif /* __LINUX_PCA963X_H*/ -- cgit v1.2.3 From 7678da8ee6dec14eda83672b319b2f7b3b2cd22e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 May 2017 14:03:08 +0200 Subject: leds: Delete obsolete Versatile driver All users of the Versatile LED driver are deleted and replaced with the very generic leds-syscon. Delete the old driver. Signed-off-by: Linus Walleij Acked-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- drivers/leds/Kconfig | 8 --- drivers/leds/Makefile | 1 - drivers/leds/leds-versatile.c | 110 ------------------------------------------ 3 files changed, 119 deletions(-) delete mode 100644 drivers/leds/leds-versatile.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 6c2999872090..fbe3468eb911 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -651,14 +651,6 @@ config LEDS_SYSCON devices. This will only work with device tree enabled devices. -config LEDS_VERSATILE - tristate "LED support for the ARM Versatile and RealView" - depends on ARCH_REALVIEW || ARCH_VERSATILE - depends on LEDS_CLASS - help - This option enabled support for the LEDs on the ARM Versatile - and RealView boards. Say Y to enabled these. - config LEDS_PM8058 tristate "LED Support for the Qualcomm PM8058 PMIC" depends on MFD_PM8XXX diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 45f133962ed8..e4a8d007c5a9 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o -obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o diff --git a/drivers/leds/leds-versatile.c b/drivers/leds/leds-versatile.c deleted file mode 100644 index 80553022d661..000000000000 --- a/drivers/leds/leds-versatile.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Driver for the 8 user LEDs found on the RealViews and Versatiles - * Based on DaVinci's DM365 board code - * - * License terms: GNU General Public License (GPL) version 2 - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include - -struct versatile_led { - void __iomem *base; - struct led_classdev cdev; - u8 mask; -}; - -/* - * The triggers lines up below will only be used if the - * LED triggers are compiled in. - */ -static const struct { - const char *name; - const char *trigger; -} versatile_leds[] = { - { "versatile:0", "heartbeat", }, - { "versatile:1", "mmc0", }, - { "versatile:2", "cpu0" }, - { "versatile:3", "cpu1" }, - { "versatile:4", "cpu2" }, - { "versatile:5", "cpu3" }, - { "versatile:6", }, - { "versatile:7", }, -}; - -static void versatile_led_set(struct led_classdev *cdev, - enum led_brightness b) -{ - struct versatile_led *led = container_of(cdev, - struct versatile_led, cdev); - u32 reg = readl(led->base); - - if (b != LED_OFF) - reg |= led->mask; - else - reg &= ~led->mask; - writel(reg, led->base); -} - -static enum led_brightness versatile_led_get(struct led_classdev *cdev) -{ - struct versatile_led *led = container_of(cdev, - struct versatile_led, cdev); - u32 reg = readl(led->base); - - return (reg & led->mask) ? LED_FULL : LED_OFF; -} - -static int versatile_leds_probe(struct platform_device *dev) -{ - int i; - struct resource *res; - void __iomem *base; - - res = platform_get_resource(dev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&dev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - /* All off */ - writel(0, base); - for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { - struct versatile_led *led; - - led = kzalloc(sizeof(*led), GFP_KERNEL); - if (!led) - break; - - led->base = base; - led->cdev.name = versatile_leds[i].name; - led->cdev.brightness_set = versatile_led_set; - led->cdev.brightness_get = versatile_led_get; - led->cdev.default_trigger = versatile_leds[i].trigger; - led->mask = BIT(i); - - if (led_classdev_register(NULL, &led->cdev) < 0) { - kfree(led); - break; - } - } - - return 0; -} - -static struct platform_driver versatile_leds_driver = { - .driver = { - .name = "versatile-leds", - }, - .probe = versatile_leds_probe, -}; - -module_platform_driver(versatile_leds_driver); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ARM Versatile LED driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 71afe3cb1e8fdf89556047e03bcbcd731f1ab108 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 26 May 2017 15:17:46 +0200 Subject: leds: trigger: gpio: Refresh LED state after GPIO change The new GPIO may have a different state than the old one. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Jacek Anaszewski --- drivers/leds/trigger/ledtrig-gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index 51288a45fbcb..93d6b82e6437 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c @@ -170,6 +170,8 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, if (gpio_data->gpio != 0) free_irq(gpio_to_irq(gpio_data->gpio), led); gpio_data->gpio = gpio; + /* After changing the GPIO, we need to update the LED. */ + schedule_work(&gpio_data->work); } return ret ? ret : n; -- cgit v1.2.3 From 71c17b06ef7dd23a09725827303e6ed19bf16cce Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 26 May 2017 15:17:47 +0200 Subject: leds: trigger: gpio: Use threaded IRQ This both simplifies the code because we can drop the workqueue indirection, and it enables using the trigger for GPIOs that work with threaded IRQs themselves. Signed-off-by: Jan Kiszka Reviewed-by: Andy Shevchenko Signed-off-by: Jacek Anaszewski --- drivers/leds/trigger/ledtrig-gpio.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index 93d6b82e6437..8891e88d54dd 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c @@ -14,14 +14,12 @@ #include #include #include -#include #include #include #include "../leds.h" struct gpio_trig_data { struct led_classdev *led; - struct work_struct work; unsigned desired_brightness; /* desired brightness when led is on */ unsigned inverted; /* true when gpio is inverted */ @@ -32,22 +30,8 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led) { struct led_classdev *led = _led; struct gpio_trig_data *gpio_data = led->trigger_data; - - /* just schedule_work since gpio_get_value can sleep */ - schedule_work(&gpio_data->work); - - return IRQ_HANDLED; -}; - -static void gpio_trig_work(struct work_struct *work) -{ - struct gpio_trig_data *gpio_data = container_of(work, - struct gpio_trig_data, work); int tmp; - if (!gpio_data->gpio) - return; - tmp = gpio_get_value_cansleep(gpio_data->gpio); if (gpio_data->inverted) tmp = !tmp; @@ -61,6 +45,8 @@ static void gpio_trig_work(struct work_struct *work) } else { led_set_brightness_nosleep(gpio_data->led, LED_OFF); } + + return IRQ_HANDLED; } static ssize_t gpio_trig_brightness_show(struct device *dev, @@ -120,7 +106,7 @@ static ssize_t gpio_trig_inverted_store(struct device *dev, gpio_data->inverted = inverted; /* After inverting, we need to update the LED. */ - schedule_work(&gpio_data->work); + gpio_trig_irq(0, led); return n; } @@ -147,7 +133,6 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, ret = sscanf(buf, "%u", &gpio); if (ret < 1) { dev_err(dev, "couldn't read gpio number\n"); - flush_work(&gpio_data->work); return -EINVAL; } @@ -161,8 +146,8 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, return n; } - ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq, - IRQF_SHARED | IRQF_TRIGGER_RISING + ret = request_threaded_irq(gpio_to_irq(gpio), NULL, gpio_trig_irq, + IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led); if (ret) { dev_err(dev, "request_irq failed with error %d\n", ret); @@ -171,7 +156,7 @@ static ssize_t gpio_trig_gpio_store(struct device *dev, free_irq(gpio_to_irq(gpio_data->gpio), led); gpio_data->gpio = gpio; /* After changing the GPIO, we need to update the LED. */ - schedule_work(&gpio_data->work); + gpio_trig_irq(0, led); } return ret ? ret : n; @@ -201,7 +186,6 @@ static void gpio_trig_activate(struct led_classdev *led) gpio_data->led = led; led->trigger_data = gpio_data; - INIT_WORK(&gpio_data->work, gpio_trig_work); led->activated = true; return; @@ -224,7 +208,6 @@ static void gpio_trig_deactivate(struct led_classdev *led) device_remove_file(led->dev, &dev_attr_gpio); device_remove_file(led->dev, &dev_attr_inverted); device_remove_file(led->dev, &dev_attr_desired_brightness); - flush_work(&gpio_data->work); if (gpio_data->gpio != 0) free_irq(gpio_to_irq(gpio_data->gpio), led); kfree(gpio_data); -- cgit v1.2.3 From 64601cb1343f1b740aa7a612a1aec778a8163445 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 2 Jun 2017 15:00:07 -0700 Subject: leds: Remove SEAD-3 driver SEAD3 is using the generic syscon & regmap based register-bit-led driver as of commit c764583f40b8 ("MIPS: SEAD3: Use register-bit-led driver via DT for LEDs") merged in the v4.9 cycle. As such the custom SEAD-3 LED driver is now unused, so remove it. Signed-off-by: Paul Burton Cc: Jacek Anaszewski Cc: Pavel Machek Cc: Ralf Baechle Cc: Richard Purdie Cc: linux-leds@vger.kernel.org Cc: linux-mips@linux-mips.org Signed-off-by: Jacek Anaszewski --- drivers/leds/Kconfig | 10 ------ drivers/leds/Makefile | 1 - drivers/leds/leds-sead3.c | 78 ----------------------------------------------- 3 files changed, 89 deletions(-) delete mode 100644 drivers/leds/leds-sead3.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index fbe3468eb911..594b24d410c3 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -590,16 +590,6 @@ config LEDS_KTD2692 Say Y to enable this driver. -config LEDS_SEAD3 - tristate "LED support for the MIPS SEAD 3 board" - depends on LEDS_CLASS && MIPS_SEAD3 - help - Say Y here to include support for the FLED and PLED LEDs on SEAD3 eval - boards. - - This driver can also be built as a module. If so the module - will be called leds-sead3. - config LEDS_IS31FL319X tristate "LED Support for ISSI IS31FL319x I2C LED controller family" depends on LEDS_CLASS && I2C && OF diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e4a8d007c5a9..909dae62ba05 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -65,7 +65,6 @@ obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o -obj-$(CONFIG_LEDS_SEAD3) += leds-sead3.o obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o diff --git a/drivers/leds/leds-sead3.c b/drivers/leds/leds-sead3.c deleted file mode 100644 index eb97a3271bb3..000000000000 --- a/drivers/leds/leds-sead3.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2015 Imagination Technologies, Inc. - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -static void sead3_pled_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - writel(value, (void __iomem *)SEAD3_CPLD_P_LED); -} - -static void sead3_fled_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - writel(value, (void __iomem *)SEAD3_CPLD_F_LED); -} - -static struct led_classdev sead3_pled = { - .name = "sead3::pled", - .brightness_set = sead3_pled_set, - .flags = LED_CORE_SUSPENDRESUME, -}; - -static struct led_classdev sead3_fled = { - .name = "sead3::fled", - .brightness_set = sead3_fled_set, - .flags = LED_CORE_SUSPENDRESUME, -}; - -static int sead3_led_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &sead3_pled); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &sead3_fled); - if (ret < 0) - led_classdev_unregister(&sead3_pled); - - return ret; -} - -static int sead3_led_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&sead3_pled); - led_classdev_unregister(&sead3_fled); - - return 0; -} - -static struct platform_driver sead3_led_driver = { - .probe = sead3_led_probe, - .remove = sead3_led_remove, - .driver = { - .name = "sead3-led", - }, -}; - -module_platform_driver(sead3_led_driver); - -MODULE_AUTHOR("Kristian Kielhofner "); -MODULE_DESCRIPTION("SEAD3 LED driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4d1707c1c6901906707b9419cac8d9c84bc17d88 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 29 Jun 2017 18:57:38 +0100 Subject: leds: lp55xx: make various arrays static const Several arrays are currently on-stack and instead should be made static const. Signed-off-by: Colin Ian King Acked-by: Pavel Machek Signed-off-by: Jacek Anaszewski --- drivers/leds/leds-lp5523.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index e9ba8cd32d66..924e50aefb00 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -168,13 +168,13 @@ static int lp5523_post_init_device(struct lp55xx_chip *chip) static void lp5523_load_engine(struct lp55xx_chip *chip) { enum lp55xx_engine_index idx = chip->engine_idx; - u8 mask[] = { + static const u8 mask[] = { [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M, [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M, [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M, }; - u8 val[] = { + static const u8 val[] = { [LP55XX_ENGINE_1] = LP5523_LOAD_ENG1, [LP55XX_ENGINE_2] = LP5523_LOAD_ENG2, [LP55XX_ENGINE_3] = LP5523_LOAD_ENG3, @@ -188,7 +188,7 @@ static void lp5523_load_engine(struct lp55xx_chip *chip) static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip) { enum lp55xx_engine_index idx = chip->engine_idx; - u8 page_sel[] = { + static const u8 page_sel[] = { [LP55XX_ENGINE_1] = LP5523_PAGE_ENG1, [LP55XX_ENGINE_2] = LP5523_PAGE_ENG2, [LP55XX_ENGINE_3] = LP5523_PAGE_ENG3, @@ -208,7 +208,7 @@ static void lp5523_stop_all_engines(struct lp55xx_chip *chip) static void lp5523_stop_engine(struct lp55xx_chip *chip) { enum lp55xx_engine_index idx = chip->engine_idx; - u8 mask[] = { + static const u8 mask[] = { [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M, [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M, [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M, @@ -505,7 +505,7 @@ static int lp5523_load_mux(struct lp55xx_chip *chip, u16 mux, int nr) { struct lp55xx_engine *engine = &chip->engines[nr - 1]; int ret; - u8 mux_page[] = { + static const u8 mux_page[] = { [LP55XX_ENGINE_1] = LP5523_PAGE_MUX1, [LP55XX_ENGINE_2] = LP5523_PAGE_MUX2, [LP55XX_ENGINE_3] = LP5523_PAGE_MUX3, -- cgit v1.2.3