aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:37:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:37:16 -0400
commit8b45bc892e6842115fc87c2b2a3b86a20617606a (patch)
tree636c804eb29bb97070e7d2bc4d5ab9d1dad27cac /drivers/leds
parenteb785bef684f2b7d03b530efc8e6f199e9777e2f (diff)
parentfa637bf0595ee1796d728a0d33b6b7fff12e1f3d (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Arnd Bergmann: "These are changes for drivers that are intimately tied to some SoC and for some reason could not get merged through the respective subsystem maintainer tree. Most of the new code is for the Keystone Navigator driver, which is new base support that is going to be needed for their hardware accelerated network driver and other units. Most of the commits are for moving old code around from at91 and omap for things that are done in device drivers nowadays. - at91: move reset, poweroff, memory and clocksource code into drivers directories - socfpga: add edac driver (through arm-soc, as requested by Boris) - omap: move omap-intc code to drivers/irqchip - sunxi: added an RTC driver for sun6i - omap: mailbox driver related changes - keystone: support for the "Navigator" component - versatile: new reboot, led and soc drivers" * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (92 commits) bus: arm-ccn: Fix spurious warning message leds: add device tree bindings for register bit LEDs soc: add driver for the ARM RealView power: reset: driver for the Versatile syscon reboot leds: add a driver for syscon-based LEDs drivers/soc: ti: fix build break with modules MAINTAINERS: Add Keystone Multicore Navigator drivers entry soc: ti: add Keystone Navigator DMA support Documentation: dt: soc: add Keystone Navigator DMA bindings soc: ti: add Keystone Navigator QMSS driver Documentation: dt: soc: add Keystone Navigator QMSS bindings rtc: sunxi: Depend on platforms sun4i/sun7i that actually have the rtc rtc: sun6i: Add sun6i RTC driver irqchip: omap-intc: remove unnecessary comments irqchip: omap-intc: correct maximum number or MIR registers irqchip: omap-intc: enable TURBO idle mode irqchip: omap-intc: enable IP protection irqchip: omap-intc: remove unnecesary of_address_to_resource() call irqchip: omap-intc: comment style cleanup irqchip: omap-intc: minor improvement to omap_irq_pending() ...
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig10
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-syscon.c166
3 files changed, 177 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f6ef7bb2dc11..90e108f9e22e 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -478,6 +478,16 @@ config LEDS_BLINKM
478 This option enables support for the BlinkM RGB LED connected 478 This option enables support for the BlinkM RGB LED connected
479 through I2C. Say Y to enable support for the BlinkM LED. 479 through I2C. Say Y to enable support for the BlinkM LED.
480 480
481config LEDS_SYSCON
482 bool "LED support for LEDs on system controllers"
483 depends on LEDS_CLASS=y
484 depends on MFD_SYSCON
485 depends on OF
486 help
487 This option enabled support for the LEDs on syscon type
488 devices. This will only work with device tree enabled
489 devices.
490
481config LEDS_VERSATILE 491config LEDS_VERSATILE
482 tristate "LED support for the ARM Versatile and RealView" 492 tristate "LED support for the ARM Versatile and RealView"
483 depends on ARCH_REALVIEW || ARCH_VERSATILE 493 depends on ARCH_REALVIEW || ARCH_VERSATILE
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index d8cc5f2777de..822dd83ef97a 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
53obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o 53obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
54obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o 54obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
55obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o 55obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
56obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
56obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o 57obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
57 58
58# LED SPI Drivers 59# LED SPI Drivers
diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c
new file mode 100644
index 000000000000..3afec79c43f4
--- /dev/null
+++ b/drivers/leds/leds-syscon.c
@@ -0,0 +1,166 @@
1/*
2 * Generic Syscon LEDs Driver
3 *
4 * Copyright (c) 2014, Linaro Limited
5 * Author: Linus Walleij <linus.walleij@linaro.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 *
22 * This driver provides system reboot functionality for APM X-Gene SoC.
23 * For system shutdown, this is board specify. If a board designer
24 * implements GPIO shutdown, use the gpio-poweroff.c driver.
25 */
26#include <linux/io.h>
27#include <linux/of_device.h>
28#include <linux/of_address.h>
29#include <linux/platform_device.h>
30#include <linux/stat.h>
31#include <linux/slab.h>
32#include <linux/mfd/syscon.h>
33#include <linux/regmap.h>
34#include <linux/leds.h>
35
36/**
37 * struct syscon_led - state container for syscon based LEDs
38 * @cdev: LED class device for this LED
39 * @map: regmap to access the syscon device backing this LED
40 * @offset: the offset into the syscon regmap for the LED register
41 * @mask: the bit in the register corresponding to the LED
42 * @state: current state of the LED
43 */
44struct syscon_led {
45 struct led_classdev cdev;
46 struct regmap *map;
47 u32 offset;
48 u32 mask;
49 bool state;
50};
51
52static void syscon_led_set(struct led_classdev *led_cdev,
53 enum led_brightness value)
54{
55 struct syscon_led *sled =
56 container_of(led_cdev, struct syscon_led, cdev);
57 u32 val;
58 int ret;
59
60 if (value == LED_OFF) {
61 val = 0;
62 sled->state = false;
63 } else {
64 val = sled->mask;
65 sled->state = true;
66 }
67
68 ret = regmap_update_bits(sled->map, sled->offset, sled->mask, val);
69 if (ret < 0)
70 dev_err(sled->cdev.dev, "error updating LED status\n");
71}
72
73static const struct of_device_id syscon_match[] = {
74 { .compatible = "syscon", },
75 {},
76};
77
78static int __init syscon_leds_init(void)
79{
80 const struct of_device_id *devid;
81 struct device_node *np;
82 struct device_node *child;
83 struct regmap *map;
84 struct platform_device *pdev;
85 struct device *dev;
86 int ret;
87
88 np = of_find_matching_node_and_match(NULL, syscon_match,
89 &devid);
90 if (!np)
91 return -ENODEV;
92
93 map = syscon_node_to_regmap(np);
94 if (IS_ERR(map))
95 return PTR_ERR(map);
96
97 /*
98 * If the map is there, the device should be there, we allocate
99 * memory on the syscon device's behalf here.
100 */
101 pdev = of_find_device_by_node(np);
102 if (!pdev)
103 return -ENODEV;
104 dev = &pdev->dev;
105
106 for_each_available_child_of_node(np, child) {
107 struct syscon_led *sled;
108 const char *state;
109
110 /* Only check for register-bit-leds */
111 if (of_property_match_string(child, "compatible",
112 "register-bit-led") < 0)
113 continue;
114
115 sled = devm_kzalloc(dev, sizeof(*sled), GFP_KERNEL);
116 if (!sled)
117 return -ENOMEM;
118
119 sled->map = map;
120
121 if (of_property_read_u32(child, "offset", &sled->offset))
122 return -EINVAL;
123 if (of_property_read_u32(child, "mask", &sled->mask))
124 return -EINVAL;
125 sled->cdev.name =
126 of_get_property(child, "label", NULL) ? : child->name;
127 sled->cdev.default_trigger =
128 of_get_property(child, "linux,default-trigger", NULL);
129
130 state = of_get_property(child, "default-state", NULL);
131 if (state) {
132 if (!strcmp(state, "keep")) {
133 u32 val;
134
135 ret = regmap_read(map, sled->offset, &val);
136 if (ret < 0)
137 return ret;
138 sled->state = !!(val & sled->mask);
139 } else if (!strcmp(state, "on")) {
140 sled->state = true;
141 ret = regmap_update_bits(map, sled->offset,
142 sled->mask,
143 sled->mask);
144 if (ret < 0)
145 return ret;
146 } else {
147 sled->state = false;
148 ret = regmap_update_bits(map, sled->offset,
149 sled->mask, 0);
150 if (ret < 0)
151 return ret;
152 }
153
154 }
155 sled->cdev.brightness_set = syscon_led_set;
156
157 ret = led_classdev_register(dev, &sled->cdev);
158 if (ret < 0)
159 return ret;
160
161 dev_info(dev, "registered LED %s\n", sled->cdev.name);
162 }
163
164 return 0;
165}
166device_initcall(syscon_leds_init);