834-ledtrig-libata.patch 4.1 KB

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