aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 21:37:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 21:37:06 -0400
commit490e142209da64243577a997b6d2ed050684ef7b (patch)
treec8b269f2ca0e303cee1377ef550c86c79acda72e
parentb6ae4055f4ab55c05df31cc1b6a7ea8c85eb525d (diff)
parent80d6737b27bbdf645a815c136606836b435f0268 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
Pull LED updates from Jacek Anaszewski: "In this merge cycle we had an interaction with MTD subsystem, that included converting drivers/mtd/nand/nand_base.c to use newly introduced MTD (NAND/NOR) LED trigger instead of implementing it on its own. Related MTD patches are intended to be merged through the LED tree, before MTD tree is merged, since further MTD development is based on those modifications. Summary: LEDs: - Introduce a kernel panic LED trigger - Introduce a MTD (NAND/NOR) trigger - led-tca6507: silence an uninitialized variable warning - ledtrig-ide-disk: Move ide_blink_delay to ledtrig_ide_activity() - leds-ss4200: Add depend on x86 arch - leds-ss4200: add DMI data for FSC SCALEO Home Server - leds-triggers: Allow to switch the trigger to "panic" on a kernel panic - devicetree: leds: Introduce "panic-indicator" optional property - leds-gpio: Support the "panic-indicator" firmware property MTD: - Uninline mtd_write_oob and move it to mtdcore.c - Remove the "nand-disk" LED trigger - Hook I/O activity to the MTD LED trigger" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: leds: gpio: Support the "panic-indicator" firmware property devicetree: leds: Introduce "panic-indicator" optional property leds: triggers: Allow to switch the trigger to "panic" on a kernel panic leds: ss4200: add DMI data for FSC SCALEO Home Server leds: ss4200: Add depend on x86 arch leds: ledtrig-ide-disk: Move ide_blink_delay to ledtrig_ide_activity() leds: tca6507: silence an uninitialized variable warning mtd: Hook I/O activity to the MTD LED trigger mtd: nand: Remove the "nand-disk" LED trigger leds: trigger: Introduce a MTD (NAND/NOR) trigger mtd: Uninline mtd_write_oob and move it to mtdcore.c leds: trigger: Introduce a kernel panic LED trigger
-rw-r--r--Documentation/devicetree/bindings/leds/common.txt3
-rw-r--r--Documentation/devicetree/bindings/leds/leds-gpio.txt2
-rw-r--r--drivers/leds/Kconfig5
-rw-r--r--drivers/leds/led-triggers.c2
-rw-r--r--drivers/leds/leds-gpio.c4
-rw-r--r--drivers/leds/leds-ss4200.c13
-rw-r--r--drivers/leds/leds-tca6507.c2
-rw-r--r--drivers/leds/leds.h1
-rw-r--r--drivers/leds/trigger/Kconfig18
-rw-r--r--drivers/leds/trigger/Makefile2
-rw-r--r--drivers/leds/trigger/ledtrig-ide-disk.c3
-rw-r--r--drivers/leds/trigger/ledtrig-mtd.c45
-rw-r--r--drivers/leds/trigger/ledtrig-panic.c77
-rw-r--r--drivers/mtd/mtdcore.c19
-rw-r--r--drivers/mtd/nand/nand_base.c29
-rw-r--r--include/linux/leds.h8
-rw-r--r--include/linux/mtd/mtd.h12
17 files changed, 202 insertions, 43 deletions
diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt
index 68419843e32f..af10678ea2f6 100644
--- a/Documentation/devicetree/bindings/leds/common.txt
+++ b/Documentation/devicetree/bindings/leds/common.txt
@@ -37,6 +37,9 @@ Optional properties for child nodes:
37 property is mandatory for the LEDs in the non-flash modes 37 property is mandatory for the LEDs in the non-flash modes
38 (e.g. torch or indicator). 38 (e.g. torch or indicator).
39 39
40- panic-indicator : This property specifies that the LED should be used,
41 if at all possible, as a panic indicator.
42
40Required properties for flash LED child nodes: 43Required properties for flash LED child nodes:
41- flash-max-microamp : Maximum flash LED supply current in microamperes. 44- flash-max-microamp : Maximum flash LED supply current in microamperes.
42- flash-max-timeout-us : Maximum timeout in microseconds after which the flash 45- flash-max-timeout-us : Maximum timeout in microseconds after which the flash
diff --git a/Documentation/devicetree/bindings/leds/leds-gpio.txt b/Documentation/devicetree/bindings/leds/leds-gpio.txt
index fea1ebfe24a9..cbbeb1850910 100644
--- a/Documentation/devicetree/bindings/leds/leds-gpio.txt
+++ b/Documentation/devicetree/bindings/leds/leds-gpio.txt
@@ -23,6 +23,8 @@ LED sub-node properties:
23 property is not present. 23 property is not present.
24- retain-state-suspended: (optional) The suspend state can be retained.Such 24- retain-state-suspended: (optional) The suspend state can be retained.Such
25 as charge-led gpio. 25 as charge-led gpio.
26- panic-indicator : (optional)
27 see Documentation/devicetree/bindings/leds/common.txt
26 28
27Examples: 29Examples:
28 30
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 225147863e02..5ae28340a98b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -413,10 +413,11 @@ config LEDS_INTEL_SS4200
413 tristate "LED driver for Intel NAS SS4200 series" 413 tristate "LED driver for Intel NAS SS4200 series"
414 depends on LEDS_CLASS 414 depends on LEDS_CLASS
415 depends on PCI && DMI 415 depends on PCI && DMI
416 depends on X86
416 help 417 help
417 This option enables support for the Intel SS4200 series of 418 This option enables support for the Intel SS4200 series of
418 Network Attached Storage servers. You may control the hard 419 Network Attached Storage servers. You may control the hard
419 drive or power LEDs on the front panel. Using this driver 420 drive or power LEDs on the front panel. Using this driver
420 can stop the front LED from blinking after startup. 421 can stop the front LED from blinking after startup.
421 422
422config LEDS_LT3593 423config LEDS_LT3593
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 2181581795d3..55fa65e1ae03 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -26,7 +26,7 @@
26 * Nests outside led_cdev->trigger_lock 26 * Nests outside led_cdev->trigger_lock
27 */ 27 */
28static DECLARE_RWSEM(triggers_list_lock); 28static DECLARE_RWSEM(triggers_list_lock);
29static LIST_HEAD(trigger_list); 29LIST_HEAD(trigger_list);
30 30
31 /* Used by LED Class */ 31 /* Used by LED Class */
32 32
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 61143f55597e..8229f063b483 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -127,6 +127,8 @@ static int create_gpio_led(const struct gpio_led *template,
127 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; 127 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
128 if (!template->retain_state_suspended) 128 if (!template->retain_state_suspended)
129 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 129 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
130 if (template->panic_indicator)
131 led_dat->cdev.flags |= LED_PANIC_INDICATOR;
130 132
131 ret = gpiod_direction_output(led_dat->gpiod, state); 133 ret = gpiod_direction_output(led_dat->gpiod, state);
132 if (ret < 0) 134 if (ret < 0)
@@ -200,6 +202,8 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
200 202
201 if (fwnode_property_present(child, "retain-state-suspended")) 203 if (fwnode_property_present(child, "retain-state-suspended"))
202 led.retain_state_suspended = 1; 204 led.retain_state_suspended = 1;
205 if (fwnode_property_present(child, "panic-indicator"))
206 led.panic_indicator = 1;
203 207
204 ret = create_gpio_led(&led, &priv->leds[priv->num_leds], 208 ret = create_gpio_led(&led, &priv->leds[priv->num_leds],
205 dev, NULL); 209 dev, NULL);
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 046cb7008745..732eb86bc1a5 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -101,6 +101,19 @@ static struct dmi_system_id nas_led_whitelist[] __initdata = {
101 DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") 101 DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
102 } 102 }
103 }, 103 },
104 {
105 /*
106 * FUJITSU SIEMENS SCALEO Home Server/SS4200-E
107 * BIOS V090L 12/19/2007
108 */
109 .callback = ss4200_led_dmi_callback,
110 .ident = "Fujitsu Siemens SCALEO Home Server",
111 .matches = {
112 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
113 DMI_MATCH(DMI_PRODUCT_NAME, "SCALEO Home Server"),
114 DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
115 }
116 },
104 {} 117 {}
105}; 118};
106 119
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index c548ea10f0f0..45222a7f4f75 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -327,6 +327,8 @@ static void set_times(struct tca6507_chip *tca, int bank)
327 int result; 327 int result;
328 328
329 result = choose_times(tca->bank[bank].ontime, &c1, &c2); 329 result = choose_times(tca->bank[bank].ontime, &c1, &c2);
330 if (result < 0)
331 return;
330 dev_dbg(&tca->client->dev, 332 dev_dbg(&tca->client->dev,
331 "Chose on times %d(%d) %d(%d) for %dms\n", 333 "Chose on times %d(%d) %d(%d) for %dms\n",
332 c1, time_codes[c1], 334 c1, time_codes[c1],
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index db3f20da7221..7d38e6b9a740 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -30,5 +30,6 @@ void led_set_brightness_nosleep(struct led_classdev *led_cdev,
30 30
31extern struct rw_semaphore leds_list_lock; 31extern struct rw_semaphore leds_list_lock;
32extern struct list_head leds_list; 32extern struct list_head leds_list;
33extern struct list_head trigger_list;
33 34
34#endif /* __LEDS_H_INCLUDED */ 35#endif /* __LEDS_H_INCLUDED */
diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig
index 5bda6a9b56bb..9893d911390d 100644
--- a/drivers/leds/trigger/Kconfig
+++ b/drivers/leds/trigger/Kconfig
@@ -41,6 +41,14 @@ config LEDS_TRIGGER_IDE_DISK
41 This allows LEDs to be controlled by IDE disk activity. 41 This allows LEDs to be controlled by IDE disk activity.
42 If unsure, say Y. 42 If unsure, say Y.
43 43
44config LEDS_TRIGGER_MTD
45 bool "LED MTD (NAND/NOR) Trigger"
46 depends on MTD
47 depends on LEDS_TRIGGERS
48 help
49 This allows LEDs to be controlled by MTD activity.
50 If unsure, say N.
51
44config LEDS_TRIGGER_HEARTBEAT 52config LEDS_TRIGGER_HEARTBEAT
45 tristate "LED Heartbeat Trigger" 53 tristate "LED Heartbeat Trigger"
46 depends on LEDS_TRIGGERS 54 depends on LEDS_TRIGGERS
@@ -108,4 +116,14 @@ config LEDS_TRIGGER_CAMERA
108 This enables direct flash/torch on/off by the driver, kernel space. 116 This enables direct flash/torch on/off by the driver, kernel space.
109 If unsure, say Y. 117 If unsure, say Y.
110 118
119config LEDS_TRIGGER_PANIC
120 bool "LED Panic Trigger"
121 depends on LEDS_TRIGGERS
122 help
123 This allows LEDs to be configured to blink on a kernel panic.
124 Enabling this option will allow to mark certain LEDs as panic indicators,
125 allowing to blink them on a kernel panic, even if they are set to
126 a different trigger.
127 If unsure, say Y.
128
111endif # LEDS_TRIGGERS 129endif # LEDS_TRIGGERS
diff --git a/drivers/leds/trigger/Makefile b/drivers/leds/trigger/Makefile
index 1abf48dacf7e..8cc64a4f4e25 100644
--- a/drivers/leds/trigger/Makefile
+++ b/drivers/leds/trigger/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 1obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
2obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o 2obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
3obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o 3obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
4obj-$(CONFIG_LEDS_TRIGGER_MTD) += ledtrig-mtd.o
4obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o 5obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
5obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o 6obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
6obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o 7obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
@@ -8,3 +9,4 @@ obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
8obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o 9obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
9obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o 10obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
10obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o 11obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o
12obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o
diff --git a/drivers/leds/trigger/ledtrig-ide-disk.c b/drivers/leds/trigger/ledtrig-ide-disk.c
index c02a3ac3cd2b..15123d389240 100644
--- a/drivers/leds/trigger/ledtrig-ide-disk.c
+++ b/drivers/leds/trigger/ledtrig-ide-disk.c
@@ -18,10 +18,11 @@
18#define BLINK_DELAY 30 18#define BLINK_DELAY 30
19 19
20DEFINE_LED_TRIGGER(ledtrig_ide); 20DEFINE_LED_TRIGGER(ledtrig_ide);
21static unsigned long ide_blink_delay = BLINK_DELAY;
22 21
23void ledtrig_ide_activity(void) 22void ledtrig_ide_activity(void)
24{ 23{
24 unsigned long ide_blink_delay = BLINK_DELAY;
25
25 led_trigger_blink_oneshot(ledtrig_ide, 26 led_trigger_blink_oneshot(ledtrig_ide,
26 &ide_blink_delay, &ide_blink_delay, 0); 27 &ide_blink_delay, &ide_blink_delay, 0);
27} 28}
diff --git a/drivers/leds/trigger/ledtrig-mtd.c b/drivers/leds/trigger/ledtrig-mtd.c
new file mode 100644
index 000000000000..99b5b0a4d826
--- /dev/null
+++ b/drivers/leds/trigger/ledtrig-mtd.c
@@ -0,0 +1,45 @@
1/*
2 * LED MTD trigger
3 *
4 * Copyright 2016 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
5 *
6 * Based on LED IDE-Disk Activity Trigger
7 *
8 * Copyright 2006 Openedhand Ltd.
9 *
10 * Author: Richard Purdie <rpurdie@openedhand.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/leds.h>
21
22#define BLINK_DELAY 30
23
24DEFINE_LED_TRIGGER(ledtrig_mtd);
25DEFINE_LED_TRIGGER(ledtrig_nand);
26
27void ledtrig_mtd_activity(void)
28{
29 unsigned long blink_delay = BLINK_DELAY;
30
31 led_trigger_blink_oneshot(ledtrig_mtd,
32 &blink_delay, &blink_delay, 0);
33 led_trigger_blink_oneshot(ledtrig_nand,
34 &blink_delay, &blink_delay, 0);
35}
36EXPORT_SYMBOL(ledtrig_mtd_activity);
37
38static int __init ledtrig_mtd_init(void)
39{
40 led_trigger_register_simple("mtd", &ledtrig_mtd);
41 led_trigger_register_simple("nand-disk", &ledtrig_nand);
42
43 return 0;
44}
45device_initcall(ledtrig_mtd_init);
diff --git a/drivers/leds/trigger/ledtrig-panic.c b/drivers/leds/trigger/ledtrig-panic.c
new file mode 100644
index 000000000000..d735526b9db4
--- /dev/null
+++ b/drivers/leds/trigger/ledtrig-panic.c
@@ -0,0 +1,77 @@
1/*
2 * Kernel Panic LED Trigger
3 *
4 * Copyright 2016 Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/notifier.h>
15#include <linux/leds.h>
16#include "../leds.h"
17
18static struct led_trigger *trigger;
19
20/*
21 * This is called in a special context by the atomic panic
22 * notifier. This means the trigger can be changed without
23 * worrying about locking.
24 */
25static void led_trigger_set_panic(struct led_classdev *led_cdev)
26{
27 struct led_trigger *trig;
28
29 list_for_each_entry(trig, &trigger_list, next_trig) {
30 if (strcmp("panic", trig->name))
31 continue;
32 if (led_cdev->trigger)
33 list_del(&led_cdev->trig_list);
34 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
35
36 /* Avoid the delayed blink path */
37 led_cdev->blink_delay_on = 0;
38 led_cdev->blink_delay_off = 0;
39
40 led_cdev->trigger = trig;
41 if (trig->activate)
42 trig->activate(led_cdev);
43 break;
44 }
45}
46
47static int led_trigger_panic_notifier(struct notifier_block *nb,
48 unsigned long code, void *unused)
49{
50 struct led_classdev *led_cdev;
51
52 list_for_each_entry(led_cdev, &leds_list, node)
53 if (led_cdev->flags & LED_PANIC_INDICATOR)
54 led_trigger_set_panic(led_cdev);
55 return NOTIFY_DONE;
56}
57
58static struct notifier_block led_trigger_panic_nb = {
59 .notifier_call = led_trigger_panic_notifier,
60};
61
62static long led_panic_blink(int state)
63{
64 led_trigger_event(trigger, state ? LED_FULL : LED_OFF);
65 return 0;
66}
67
68static int __init ledtrig_panic_init(void)
69{
70 atomic_notifier_chain_register(&panic_notifier_list,
71 &led_trigger_panic_nb);
72
73 led_trigger_register_simple("panic", &trigger);
74 panic_blink = led_panic_blink;
75 return 0;
76}
77device_initcall(ledtrig_panic_init);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 309625130b21..bee180bd11e7 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -40,6 +40,7 @@
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/reboot.h> 41#include <linux/reboot.h>
42#include <linux/kconfig.h> 42#include <linux/kconfig.h>
43#include <linux/leds.h>
43 44
44#include <linux/mtd/mtd.h> 45#include <linux/mtd/mtd.h>
45#include <linux/mtd/partitions.h> 46#include <linux/mtd/partitions.h>
@@ -862,6 +863,7 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
862 mtd_erase_callback(instr); 863 mtd_erase_callback(instr);
863 return 0; 864 return 0;
864 } 865 }
866 ledtrig_mtd_activity();
865 return mtd->_erase(mtd, instr); 867 return mtd->_erase(mtd, instr);
866} 868}
867EXPORT_SYMBOL_GPL(mtd_erase); 869EXPORT_SYMBOL_GPL(mtd_erase);
@@ -925,6 +927,7 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
925 if (!len) 927 if (!len)
926 return 0; 928 return 0;
927 929
930 ledtrig_mtd_activity();
928 /* 931 /*
929 * In the absence of an error, drivers return a non-negative integer 932 * In the absence of an error, drivers return a non-negative integer
930 * representing the maximum number of bitflips that were corrected on 933 * representing the maximum number of bitflips that were corrected on
@@ -949,6 +952,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
949 return -EROFS; 952 return -EROFS;
950 if (!len) 953 if (!len)
951 return 0; 954 return 0;
955 ledtrig_mtd_activity();
952 return mtd->_write(mtd, to, len, retlen, buf); 956 return mtd->_write(mtd, to, len, retlen, buf);
953} 957}
954EXPORT_SYMBOL_GPL(mtd_write); 958EXPORT_SYMBOL_GPL(mtd_write);
@@ -982,6 +986,8 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
982 ops->retlen = ops->oobretlen = 0; 986 ops->retlen = ops->oobretlen = 0;
983 if (!mtd->_read_oob) 987 if (!mtd->_read_oob)
984 return -EOPNOTSUPP; 988 return -EOPNOTSUPP;
989
990 ledtrig_mtd_activity();
985 /* 991 /*
986 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics 992 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
987 * similar to mtd->_read(), returning a non-negative integer 993 * similar to mtd->_read(), returning a non-negative integer
@@ -997,6 +1003,19 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
997} 1003}
998EXPORT_SYMBOL_GPL(mtd_read_oob); 1004EXPORT_SYMBOL_GPL(mtd_read_oob);
999 1005
1006int mtd_write_oob(struct mtd_info *mtd, loff_t to,
1007 struct mtd_oob_ops *ops)
1008{
1009 ops->retlen = ops->oobretlen = 0;
1010 if (!mtd->_write_oob)
1011 return -EOPNOTSUPP;
1012 if (!(mtd->flags & MTD_WRITEABLE))
1013 return -EROFS;
1014 ledtrig_mtd_activity();
1015 return mtd->_write_oob(mtd, to, ops);
1016}
1017EXPORT_SYMBOL_GPL(mtd_write_oob);
1018
1000/* 1019/*
1001 * Method to access the protection register area, present in some flash 1020 * Method to access the protection register area, present in some flash
1002 * devices. The user data is one time programmable but the factory data is read 1021 * devices. The user data is one time programmable but the factory data is read
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 557b8462f55e..ba4f603e0537 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -43,7 +43,6 @@
43#include <linux/mtd/nand_bch.h> 43#include <linux/mtd/nand_bch.h>
44#include <linux/interrupt.h> 44#include <linux/interrupt.h>
45#include <linux/bitops.h> 45#include <linux/bitops.h>
46#include <linux/leds.h>
47#include <linux/io.h> 46#include <linux/io.h>
48#include <linux/mtd/partitions.h> 47#include <linux/mtd/partitions.h>
49#include <linux/of_mtd.h> 48#include <linux/of_mtd.h>
@@ -97,12 +96,6 @@ static int nand_get_device(struct mtd_info *mtd, int new_state);
97static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, 96static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
98 struct mtd_oob_ops *ops); 97 struct mtd_oob_ops *ops);
99 98
100/*
101 * For devices which display every fart in the system on a separate LED. Is
102 * compiled away when LED support is disabled.
103 */
104DEFINE_LED_TRIGGER(nand_led_trigger);
105
106static int check_offs_len(struct mtd_info *mtd, 99static int check_offs_len(struct mtd_info *mtd,
107 loff_t ofs, uint64_t len) 100 loff_t ofs, uint64_t len)
108{ 101{
@@ -540,19 +533,16 @@ void nand_wait_ready(struct mtd_info *mtd)
540 if (in_interrupt() || oops_in_progress) 533 if (in_interrupt() || oops_in_progress)
541 return panic_nand_wait_ready(mtd, timeo); 534 return panic_nand_wait_ready(mtd, timeo);
542 535
543 led_trigger_event(nand_led_trigger, LED_FULL);
544 /* Wait until command is processed or timeout occurs */ 536 /* Wait until command is processed or timeout occurs */
545 timeo = jiffies + msecs_to_jiffies(timeo); 537 timeo = jiffies + msecs_to_jiffies(timeo);
546 do { 538 do {
547 if (chip->dev_ready(mtd)) 539 if (chip->dev_ready(mtd))
548 goto out; 540 return;
549 cond_resched(); 541 cond_resched();
550 } while (time_before(jiffies, timeo)); 542 } while (time_before(jiffies, timeo));
551 543
552 if (!chip->dev_ready(mtd)) 544 if (!chip->dev_ready(mtd))
553 pr_warn_ratelimited("timeout while waiting for chip to become ready\n"); 545 pr_warn_ratelimited("timeout while waiting for chip to become ready\n");
554out:
555 led_trigger_event(nand_led_trigger, LED_OFF);
556} 546}
557EXPORT_SYMBOL_GPL(nand_wait_ready); 547EXPORT_SYMBOL_GPL(nand_wait_ready);
558 548
@@ -885,8 +875,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
885 int status; 875 int status;
886 unsigned long timeo = 400; 876 unsigned long timeo = 400;
887 877
888 led_trigger_event(nand_led_trigger, LED_FULL);
889
890 /* 878 /*
891 * Apply this short delay always to ensure that we do wait tWB in any 879 * Apply this short delay always to ensure that we do wait tWB in any
892 * case on any machine. 880 * case on any machine.
@@ -910,7 +898,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
910 cond_resched(); 898 cond_resched();
911 } while (time_before(jiffies, timeo)); 899 } while (time_before(jiffies, timeo));
912 } 900 }
913 led_trigger_event(nand_led_trigger, LED_OFF);
914 901
915 status = (int)chip->read_byte(mtd); 902 status = (int)chip->read_byte(mtd);
916 /* This can happen if in case of timeout or buggy dev_ready */ 903 /* This can happen if in case of timeout or buggy dev_ready */
@@ -4466,20 +4453,6 @@ void nand_release(struct mtd_info *mtd)
4466} 4453}
4467EXPORT_SYMBOL_GPL(nand_release); 4454EXPORT_SYMBOL_GPL(nand_release);
4468 4455
4469static int __init nand_base_init(void)
4470{
4471 led_trigger_register_simple("nand-disk", &nand_led_trigger);
4472 return 0;
4473}
4474
4475static void __exit nand_base_exit(void)
4476{
4477 led_trigger_unregister_simple(nand_led_trigger);
4478}
4479
4480module_init(nand_base_init);
4481module_exit(nand_base_exit);
4482
4483MODULE_LICENSE("GPL"); 4456MODULE_LICENSE("GPL");
4484MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>"); 4457MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
4485MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); 4458MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
diff --git a/include/linux/leds.h b/include/linux/leds.h
index f203a8f89d30..d2b13066e781 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -50,6 +50,7 @@ struct led_classdev {
50#define LED_SYSFS_DISABLE (1 << 22) 50#define LED_SYSFS_DISABLE (1 << 22)
51#define LED_DEV_CAP_FLASH (1 << 23) 51#define LED_DEV_CAP_FLASH (1 << 23)
52#define LED_HW_PLUGGABLE (1 << 24) 52#define LED_HW_PLUGGABLE (1 << 24)
53#define LED_PANIC_INDICATOR (1 << 25)
53 54
54 /* Set LED brightness level 55 /* Set LED brightness level
55 * Must not sleep. Use brightness_set_blocking for drivers 56 * Must not sleep. Use brightness_set_blocking for drivers
@@ -329,6 +330,12 @@ extern void ledtrig_ide_activity(void);
329static inline void ledtrig_ide_activity(void) {} 330static inline void ledtrig_ide_activity(void) {}
330#endif 331#endif
331 332
333#ifdef CONFIG_LEDS_TRIGGER_MTD
334extern void ledtrig_mtd_activity(void);
335#else
336static inline void ledtrig_mtd_activity(void) {}
337#endif
338
332#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE) 339#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE)
333extern void ledtrig_flash_ctrl(bool on); 340extern void ledtrig_flash_ctrl(bool on);
334extern void ledtrig_torch_ctrl(bool on); 341extern void ledtrig_torch_ctrl(bool on);
@@ -358,6 +365,7 @@ struct gpio_led {
358 unsigned gpio; 365 unsigned gpio;
359 unsigned active_low : 1; 366 unsigned active_low : 1;
360 unsigned retain_state_suspended : 1; 367 unsigned retain_state_suspended : 1;
368 unsigned panic_indicator : 1;
361 unsigned default_state : 2; 369 unsigned default_state : 2;
362 /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ 370 /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */
363 struct gpio_desc *gpiod; 371 struct gpio_desc *gpiod;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 771272187316..ef9fea4fc400 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -283,17 +283,7 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
283 const u_char *buf); 283 const u_char *buf);
284 284
285int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); 285int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
286 286int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
287static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
288 struct mtd_oob_ops *ops)
289{
290 ops->retlen = ops->oobretlen = 0;
291 if (!mtd->_write_oob)
292 return -EOPNOTSUPP;
293 if (!(mtd->flags & MTD_WRITEABLE))
294 return -EROFS;
295 return mtd->_write_oob(mtd, to, ops);
296}
297 287
298int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen, 288int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
299 struct otp_info *buf); 289 struct otp_info *buf);