[OpenWrt-Devel] [PATCH 1/2] kernel/generic: add ledtrig support to libata
Daniel Golle
daniel at makrotopia.org
Fri Dec 12 11:07:34 EST 2014
This adds a LED trigger for each SATA port if the kernel config option
CONFIG_ATA_LEDS is set.
In order not to cause any oldconfig confusion on targets, the option depends
on CONFIG_ARCH_WANTS_LIBATA_LEDS, so target maintainers have to opt-in in
order to use this (it could e.g. be useful on kirkwood, orion, ...)
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
.../generic/patches-3.14/834-ledtrig-libata.patch | 147 +++++++++++++++++++++
.../generic/patches-3.18/834-ledtrig-libata.patch | 147 +++++++++++++++++++++
2 files changed, 294 insertions(+)
create mode 100644 target/linux/generic/patches-3.14/834-ledtrig-libata.patch
create mode 100644 target/linux/generic/patches-3.18/834-ledtrig-libata.patch
diff --git a/target/linux/generic/patches-3.14/834-ledtrig-libata.patch b/target/linux/generic/patches-3.14/834-ledtrig-libata.patch
new file mode 100644
index 0000000..a09cb0a
--- /dev/null
+++ b/target/linux/generic/patches-3.14/834-ledtrig-libata.patch
@@ -0,0 +1,147 @@
+From c187610266765d05975a1d44cb3f6f0b81fee324 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel at makrotopia.org>
+Date: Fri, 12 Dec 2014 13:38:33 +0100
+Subject: [PATCH] libata: add ledtrig support
+
+Signed-off-by: Daniel Golle <daniel at makrotopia.org>
+---
+ drivers/ata/Kconfig | 15 +++++++++++++++
+ drivers/ata/libata-core.c | 39 +++++++++++++++++++++++++++++++++++++++
+ include/linux/libata.h | 9 +++++++++
+ 3 files changed, 63 insertions(+)
+
+diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
+index cd4cccb..3a92107 100644
+--- a/drivers/ata/Kconfig
++++ b/drivers/ata/Kconfig
+@@ -46,6 +46,21 @@ config ATA_VERBOSE_ERROR
+
+ If unsure, say Y.
+
++config ARCH_WANT_LIBATA_LEDS
++ bool
++
++config ATA_LEDS
++ bool "support ATA port LED triggers"
++ depends on ARCH_WANT_LIBATA_LEDS
++ select NEW_LEDS
++ select LEDS_CLASS
++ select LEDS_TRIGGERS
++ default y
++ help
++ This option adds a LED trigger for each registered ATA port.
++ It is used to drive disk activity leds connected via GPIO.
++
++
+ config ATA_ACPI
+ bool "ATA ACPI Support"
+ depends on ACPI && PCI
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index c5ba15a..bf97099 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -725,6 +725,17 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+ return block;
+ }
+
++#ifdef CONFIG_ATA_LEDS
++#define LIBATA_BLINK_DELAY 20 /* ms */
++static inline void ata_led_act(struct ata_port *ap)
++{
++ unsigned long led_delay = LIBATA_BLINK_DELAY;
++ if (likely(!ap->ledtrig))
++ return;
++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
++}
++#endif
++
+ /**
+ * ata_build_rw_tf - Build ATA taskfile for given read/write request
+ * @tf: Target ATA taskfile
+@@ -4753,6 +4764,9 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
+ break;
+ }
+ }
++#ifdef CONFIG_ATA_LEDS
++ ata_led_act(ap);
++#endif
+
+ return qc;
+ }
+@@ -5663,6 +5677,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
+ ap->stats.unhandled_irq = 1;
+ ap->stats.idle_irq = 1;
+ #endif
++#ifdef CONFIG_ATA_LEDS
++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
++#endif
+ ata_sff_port_init(ap);
+
+ return ap;
+@@ -5684,6 +5701,12 @@ static void ata_host_release(struct device *gendev, void *res)
+
+ kfree(ap->pmp_link);
+ kfree(ap->slave_link);
++#ifdef CONFIG_ATA_LEDS
++ if (ap->ledtrig) {
++ led_trigger_unregister(ap->ledtrig);
++ kfree(ap->ledtrig);
++ };
++#endif
+ kfree(ap);
+ host->ports[i] = NULL;
+ }
+@@ -6130,7 +6153,23 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
+ host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
+ host->ports[i]->local_port_no = i + 1;
+ }
++#ifdef CONFIG_ATA_LEDS
++ for (i = 0; i < host->n_ports; i++) {
++ if (unlikely(!host->ports[i]->ledtrig))
++ continue;
++
++ snprintf(host->ports[i]->ledtrig_name,
++ sizeof(host->ports[i]->ledtrig_name), "ata%u",
++ host->ports[i]->print_id);
++
++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
+
++ if (led_trigger_register(host->ports[i]->ledtrig)) {
++ kfree(host->ports[i]->ledtrig);
++ host->ports[i]->ledtrig = NULL;
++ }
++ }
++#endif
+ /* Create associated sysfs transport objects */
+ for (i = 0; i < host->n_ports; i++) {
+ rc = ata_tport_add(host->dev,host->ports[i]);
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index bd5fefe..9848876 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -38,6 +38,9 @@
+ #include <linux/acpi.h>
+ #include <linux/cdrom.h>
+ #include <linux/sched.h>
++#ifdef CONFIG_ATA_LEDS
++#include <linux/leds.h>
++#endif
+
+ /*
+ * Define if arch has non-standard setup. This is a _PCI_ standard
+@@ -861,6 +864,12 @@ struct ata_port {
+ #ifdef CONFIG_ATA_ACPI
+ struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
+ #endif
++
++#ifdef CONFIG_ATA_LEDS
++ struct led_trigger *ledtrig;
++ char ledtrig_name[8];
++#endif
++
+ /* owned by EH */
+ u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
+ };
+--
+2.1.3
+
diff --git a/target/linux/generic/patches-3.18/834-ledtrig-libata.patch b/target/linux/generic/patches-3.18/834-ledtrig-libata.patch
new file mode 100644
index 0000000..a09cb0a
--- /dev/null
+++ b/target/linux/generic/patches-3.18/834-ledtrig-libata.patch
@@ -0,0 +1,147 @@
+From c187610266765d05975a1d44cb3f6f0b81fee324 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel at makrotopia.org>
+Date: Fri, 12 Dec 2014 13:38:33 +0100
+Subject: [PATCH] libata: add ledtrig support
+
+Signed-off-by: Daniel Golle <daniel at makrotopia.org>
+---
+ drivers/ata/Kconfig | 15 +++++++++++++++
+ drivers/ata/libata-core.c | 39 +++++++++++++++++++++++++++++++++++++++
+ include/linux/libata.h | 9 +++++++++
+ 3 files changed, 63 insertions(+)
+
+diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
+index cd4cccb..3a92107 100644
+--- a/drivers/ata/Kconfig
++++ b/drivers/ata/Kconfig
+@@ -46,6 +46,21 @@ config ATA_VERBOSE_ERROR
+
+ If unsure, say Y.
+
++config ARCH_WANT_LIBATA_LEDS
++ bool
++
++config ATA_LEDS
++ bool "support ATA port LED triggers"
++ depends on ARCH_WANT_LIBATA_LEDS
++ select NEW_LEDS
++ select LEDS_CLASS
++ select LEDS_TRIGGERS
++ default y
++ help
++ This option adds a LED trigger for each registered ATA port.
++ It is used to drive disk activity leds connected via GPIO.
++
++
+ config ATA_ACPI
+ bool "ATA ACPI Support"
+ depends on ACPI && PCI
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index c5ba15a..bf97099 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -725,6 +725,17 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
+ return block;
+ }
+
++#ifdef CONFIG_ATA_LEDS
++#define LIBATA_BLINK_DELAY 20 /* ms */
++static inline void ata_led_act(struct ata_port *ap)
++{
++ unsigned long led_delay = LIBATA_BLINK_DELAY;
++ if (likely(!ap->ledtrig))
++ return;
++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
++}
++#endif
++
+ /**
+ * ata_build_rw_tf - Build ATA taskfile for given read/write request
+ * @tf: Target ATA taskfile
+@@ -4753,6 +4764,9 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
+ break;
+ }
+ }
++#ifdef CONFIG_ATA_LEDS
++ ata_led_act(ap);
++#endif
+
+ return qc;
+ }
+@@ -5663,6 +5677,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
+ ap->stats.unhandled_irq = 1;
+ ap->stats.idle_irq = 1;
+ #endif
++#ifdef CONFIG_ATA_LEDS
++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
++#endif
+ ata_sff_port_init(ap);
+
+ return ap;
+@@ -5684,6 +5701,12 @@ static void ata_host_release(struct device *gendev, void *res)
+
+ kfree(ap->pmp_link);
+ kfree(ap->slave_link);
++#ifdef CONFIG_ATA_LEDS
++ if (ap->ledtrig) {
++ led_trigger_unregister(ap->ledtrig);
++ kfree(ap->ledtrig);
++ };
++#endif
+ kfree(ap);
+ host->ports[i] = NULL;
+ }
+@@ -6130,7 +6153,23 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
+ host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
+ host->ports[i]->local_port_no = i + 1;
+ }
++#ifdef CONFIG_ATA_LEDS
++ for (i = 0; i < host->n_ports; i++) {
++ if (unlikely(!host->ports[i]->ledtrig))
++ continue;
++
++ snprintf(host->ports[i]->ledtrig_name,
++ sizeof(host->ports[i]->ledtrig_name), "ata%u",
++ host->ports[i]->print_id);
++
++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
+
++ if (led_trigger_register(host->ports[i]->ledtrig)) {
++ kfree(host->ports[i]->ledtrig);
++ host->ports[i]->ledtrig = NULL;
++ }
++ }
++#endif
+ /* Create associated sysfs transport objects */
+ for (i = 0; i < host->n_ports; i++) {
+ rc = ata_tport_add(host->dev,host->ports[i]);
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index bd5fefe..9848876 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -38,6 +38,9 @@
+ #include <linux/acpi.h>
+ #include <linux/cdrom.h>
+ #include <linux/sched.h>
++#ifdef CONFIG_ATA_LEDS
++#include <linux/leds.h>
++#endif
+
+ /*
+ * Define if arch has non-standard setup. This is a _PCI_ standard
+@@ -861,6 +864,12 @@ struct ata_port {
+ #ifdef CONFIG_ATA_ACPI
+ struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
+ #endif
++
++#ifdef CONFIG_ATA_LEDS
++ struct led_trigger *ledtrig;
++ char ledtrig_name[8];
++#endif
++
+ /* owned by EH */
+ u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
+ };
+--
+2.1.3
+
--
2.1.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list