[OpenWrt-Devel,1/2] kernel/generic: add ledtrig support to libata
diff mbox

Message ID 20141212160729.GA12461@makrotopia.org
State Superseded
Headers show

Commit Message

Daniel Golle Dec. 12, 2014, 4:07 p.m. UTC
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@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

Comments

John Crispin Dec. 12, 2014, 4:08 p.m. UTC | #1
... and i assume this is already en-route to upstream ?

	

On 12/12/2014 17:07, Daniel Golle wrote:
> 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@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@makrotopia.org> 
> +Date: Fri, 12 Dec 2014 13:38:33 +0100 +Subject: [PATCH] libata:
> add ledtrig support + +Signed-off-by: Daniel Golle
> <daniel@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@makrotopia.org> 
> +Date: Fri, 12 Dec 2014 13:38:33 +0100 +Subject: [PATCH] libata:
> add ledtrig support + +Signed-off-by: Daniel Golle
> <daniel@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 +
>
John Crispin Dec. 12, 2014, 4:17 p.m. UTC | #2
On 12/12/2014 17:07, Daniel Golle wrote:
> ++#ifdef CONFIG_ATA_LEDS
> ++	ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
> ++#endif


can you change all of these to the new IS_ENABLED() api

	John

Patch
diff mbox

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@makrotopia.org>
+Date: Fri, 12 Dec 2014 13:38:33 +0100
+Subject: [PATCH] libata: add ledtrig support
+
+Signed-off-by: Daniel Golle <daniel@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@makrotopia.org>
+Date: Fri, 12 Dec 2014 13:38:33 +0100
+Subject: [PATCH] libata: add ledtrig support
+
+Signed-off-by: Daniel Golle <daniel@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
+