kernel: switch 3.19 from -rc5 to release .0
[openwrt.git] / target / linux / generic / patches-3.19 / 834-ledtrig-libata.patch
1 From 52cfd51cdf6a6e14d4fb270c6343abac3bac00f4 Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Fri, 12 Dec 2014 13:38:33 +0100
4 Subject: [PATCH] libata: add ledtrig support
5 To: linux-ide@vger.kernel.org,
6     Tejun Heo <tj@kernel.org>
7
8 This adds a LED trigger for each ATA port indicating disk activity.
9
10 As this is needed only on specific platforms (NAS SoCs and such),
11 these platforms should define ARCH_WANTS_LIBATA_LEDS if there
12 are boards with LED(s) intended to indicate ATA disk activity and
13 need the OS to take care of that.
14 In that way, if not selected, LED trigger support not will be
15 included in libata-core and both, codepaths and structures remain
16 untouched.
17
18 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
19 ---
20  drivers/ata/Kconfig       | 16 ++++++++++++++++
21  drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++
22  include/linux/libata.h    |  9 +++++++++
23  3 files changed, 66 insertions(+)
24
25 --- a/drivers/ata/Kconfig
26 +++ b/drivers/ata/Kconfig
27 @@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR
28  
29           If unsure, say Y.
30  
31 +config ARCH_WANT_LIBATA_LEDS
32 +       bool
33 +
34 +config ATA_LEDS
35 +       bool "support ATA port LED triggers"
36 +       depends on ARCH_WANT_LIBATA_LEDS
37 +       select NEW_LEDS
38 +       select LEDS_CLASS
39 +       select LEDS_TRIGGERS
40 +       default y
41 +       help
42 +         This option adds a LED trigger for each registered ATA port.
43 +         It is used to drive disk activity leds connected via GPIO.
44 +
45 +         If unsure, say N.
46 +
47  config ATA_ACPI
48         bool "ATA ACPI Support"
49         depends on ACPI && PCI
50 --- a/drivers/ata/libata-core.c
51 +++ b/drivers/ata/libata-core.c
52 @@ -725,6 +725,19 @@ u64 ata_tf_read_block(struct ata_taskfil
53         return block;
54  }
55  
56 +#ifdef CONFIG_ATA_LEDS
57 +#define LIBATA_BLINK_DELAY 20 /* ms */
58 +static inline void ata_led_act(struct ata_port *ap)
59 +{
60 +       unsigned long led_delay = LIBATA_BLINK_DELAY;
61 +
62 +       if (unlikely(!ap->ledtrig))
63 +               return;
64 +
65 +       led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
66 +}
67 +#endif
68 +
69  /**
70   *     ata_build_rw_tf - Build ATA taskfile for given read/write request
71   *     @tf: Target ATA taskfile
72 @@ -4787,6 +4800,9 @@ static struct ata_queued_cmd *ata_qc_new
73                         break;
74                 }
75         }
76 +#ifdef CONFIG_ATA_LEDS
77 +       ata_led_act(ap);
78 +#endif
79  
80         return qc;
81  }
82 @@ -5697,6 +5713,9 @@ struct ata_port *ata_port_alloc(struct a
83         ap->stats.unhandled_irq = 1;
84         ap->stats.idle_irq = 1;
85  #endif
86 +#ifdef CONFIG_ATA_LEDS
87 +       ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
88 +#endif
89         ata_sff_port_init(ap);
90  
91         return ap;
92 @@ -5718,6 +5737,12 @@ static void ata_host_release(struct devi
93  
94                 kfree(ap->pmp_link);
95                 kfree(ap->slave_link);
96 +#ifdef CONFIG_ATA_LEDS
97 +               if (ap->ledtrig) {
98 +                       led_trigger_unregister(ap->ledtrig);
99 +                       kfree(ap->ledtrig);
100 +               };
101 +#endif
102                 kfree(ap);
103                 host->ports[i] = NULL;
104         }
105 @@ -6164,7 +6189,23 @@ int ata_host_register(struct ata_host *h
106                 host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
107                 host->ports[i]->local_port_no = i + 1;
108         }
109 +#ifdef CONFIG_ATA_LEDS
110 +       for (i = 0; i < host->n_ports; i++) {
111 +               if (unlikely(!host->ports[i]->ledtrig))
112 +                       continue;
113  
114 +               snprintf(host->ports[i]->ledtrig_name,
115 +                       sizeof(host->ports[i]->ledtrig_name), "ata%u",
116 +                       host->ports[i]->print_id);
117 +
118 +               host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
119 +
120 +               if (led_trigger_register(host->ports[i]->ledtrig)) {
121 +                       kfree(host->ports[i]->ledtrig);
122 +                       host->ports[i]->ledtrig = NULL;
123 +               }
124 +       }
125 +#endif
126         /* Create associated sysfs transport objects  */
127         for (i = 0; i < host->n_ports; i++) {
128                 rc = ata_tport_add(host->dev,host->ports[i]);
129 --- a/include/linux/libata.h
130 +++ b/include/linux/libata.h
131 @@ -38,6 +38,9 @@
132  #include <linux/acpi.h>
133  #include <linux/cdrom.h>
134  #include <linux/sched.h>
135 +#ifdef CONFIG_ATA_LEDS
136 +#include <linux/leds.h>
137 +#endif
138  
139  /*
140   * Define if arch has non-standard setup.  This is a _PCI_ standard
141 @@ -864,6 +867,12 @@ struct ata_port {
142  #ifdef CONFIG_ATA_ACPI
143         struct ata_acpi_gtm     __acpi_init_gtm; /* use ata_acpi_init_gtm() */
144  #endif
145 +
146 +#ifdef CONFIG_ATA_LEDS
147 +       struct led_trigger      *ledtrig;
148 +       char                    ledtrig_name[8];
149 +#endif
150 +
151         /* owned by EH */
152         u8                      sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
153  };