leds.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * LED support code, ripped out of arch/arm/kernel/time.c
  3. *
  4. * Copyright (C) 1994-2001 Russell King
  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. #include <linux/export.h>
  11. #include <linux/init.h>
  12. #include <linux/device.h>
  13. #include <linux/syscore_ops.h>
  14. #include <linux/string.h>
  15. #include <asm/leds.h>
  16. static void dummy_leds_event(led_event_t evt)
  17. {
  18. }
  19. void (*leds_event)(led_event_t) = dummy_leds_event;
  20. struct leds_evt_name {
  21. const char name[8];
  22. int on;
  23. int off;
  24. };
  25. static const struct leds_evt_name evt_names[] = {
  26. { "amber", led_amber_on, led_amber_off },
  27. { "blue", led_blue_on, led_blue_off },
  28. { "green", led_green_on, led_green_off },
  29. { "red", led_red_on, led_red_off },
  30. };
  31. static ssize_t leds_store(struct device *dev,
  32. struct device_attribute *attr,
  33. const char *buf, size_t size)
  34. {
  35. int ret = -EINVAL, len = strcspn(buf, " ");
  36. if (len > 0 && buf[len] == '\0')
  37. len--;
  38. if (strncmp(buf, "claim", len) == 0) {
  39. leds_event(led_claim);
  40. ret = size;
  41. } else if (strncmp(buf, "release", len) == 0) {
  42. leds_event(led_release);
  43. ret = size;
  44. } else {
  45. int i;
  46. for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
  47. if (strlen(evt_names[i].name) != len ||
  48. strncmp(buf, evt_names[i].name, len) != 0)
  49. continue;
  50. if (strncmp(buf+len, " on", 3) == 0) {
  51. leds_event(evt_names[i].on);
  52. ret = size;
  53. } else if (strncmp(buf+len, " off", 4) == 0) {
  54. leds_event(evt_names[i].off);
  55. ret = size;
  56. }
  57. break;
  58. }
  59. }
  60. return ret;
  61. }
  62. static DEVICE_ATTR(event, 0200, NULL, leds_store);
  63. static struct bus_type leds_subsys = {
  64. .name = "leds",
  65. .dev_name = "leds",
  66. };
  67. static struct device leds_device = {
  68. .id = 0,
  69. .bus = &leds_subsys,
  70. };
  71. static int leds_suspend(void)
  72. {
  73. leds_event(led_stop);
  74. return 0;
  75. }
  76. static void leds_resume(void)
  77. {
  78. leds_event(led_start);
  79. }
  80. static void leds_shutdown(void)
  81. {
  82. leds_event(led_halted);
  83. }
  84. static struct syscore_ops leds_syscore_ops = {
  85. .shutdown = leds_shutdown,
  86. .suspend = leds_suspend,
  87. .resume = leds_resume,
  88. };
  89. static int __init leds_init(void)
  90. {
  91. int ret;
  92. ret = subsys_system_register(&leds_subsys, NULL);
  93. if (ret == 0)
  94. ret = device_register(&leds_device);
  95. if (ret == 0)
  96. ret = device_create_file(&leds_device, &dev_attr_event);
  97. if (ret == 0)
  98. register_syscore_ops(&leds_syscore_ops);
  99. return ret;
  100. }
  101. device_initcall(leds_init);
  102. EXPORT_SYMBOL(leds_event);