led-triggers.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * LED Triggers Core
  4. *
  5. * Copyright 2005-2007 Openedhand Ltd.
  6. *
  7. * Author: Richard Purdie <rpurdie@openedhand.com>
  8. */
  9. #include <linux/export.h>
  10. #include <linux/kernel.h>
  11. #include <linux/list.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/device.h>
  14. #include <linux/timer.h>
  15. #include <linux/rwsem.h>
  16. #include <linux/leds.h>
  17. #include <linux/slab.h>
  18. #include <linux/mm.h>
  19. #include "leds.h"
  20. /*
  21. * Nests outside led_cdev->trigger_lock
  22. */
  23. static DECLARE_RWSEM(triggers_list_lock);
  24. static LIST_HEAD(trigger_list);
  25. /* Used by LED Class */
  26. static inline bool
  27. trigger_relevant(struct led_classdev *led_cdev, struct led_trigger *trig)
  28. {
  29. return !trig->trigger_type || trig->trigger_type == led_cdev->trigger_type;
  30. }
  31. ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
  32. const struct bin_attribute *bin_attr, char *buf,
  33. loff_t pos, size_t count)
  34. {
  35. struct device *dev = kobj_to_dev(kobj);
  36. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  37. struct led_trigger *trig;
  38. int ret = count;
  39. mutex_lock(&led_cdev->led_access);
  40. if (led_sysfs_is_disabled(led_cdev)) {
  41. ret = -EBUSY;
  42. goto unlock;
  43. }
  44. if (sysfs_streq(buf, "none")) {
  45. led_trigger_remove(led_cdev);
  46. goto unlock;
  47. }
  48. if (sysfs_streq(buf, "default")) {
  49. led_trigger_set_default(led_cdev);
  50. goto unlock;
  51. }
  52. down_read(&triggers_list_lock);
  53. list_for_each_entry(trig, &trigger_list, next_trig) {
  54. if (sysfs_streq(buf, trig->name) && trigger_relevant(led_cdev, trig)) {
  55. down_write(&led_cdev->trigger_lock);
  56. led_trigger_set(led_cdev, trig);
  57. up_write(&led_cdev->trigger_lock);
  58. up_read(&triggers_list_lock);
  59. goto unlock;
  60. }
  61. }
  62. /* we come here only if buf matches no trigger */
  63. ret = -EINVAL;
  64. up_read(&triggers_list_lock);
  65. unlock:
  66. mutex_unlock(&led_cdev->led_access);
  67. return ret;
  68. }
  69. EXPORT_SYMBOL_GPL(led_trigger_write);
  70. __printf(3, 4)
  71. static int led_trigger_snprintf(char *buf, ssize_t size, const char *fmt, ...)
  72. {
  73. va_list args;
  74. int i;
  75. va_start(args, fmt);
  76. if (size <= 0)
  77. i = vsnprintf(NULL, 0, fmt, args);
  78. else
  79. i = vscnprintf(buf, size, fmt, args);
  80. va_end(args);
  81. return i;
  82. }
  83. static int led_trigger_format(char *buf, size_t size,
  84. struct led_classdev *led_cdev)
  85. {
  86. struct led_trigger *trig;
  87. int len = led_trigger_snprintf(buf, size, "%s",
  88. led_cdev->trigger ? "none" : "[none]");
  89. if (led_cdev->default_trigger)
  90. len += led_trigger_snprintf(buf + len, size - len, " default");
  91. list_for_each_entry(trig, &trigger_list, next_trig) {
  92. bool hit;
  93. if (!trigger_relevant(led_cdev, trig))
  94. continue;
  95. hit = led_cdev->trigger && !strcmp(led_cdev->trigger->name, trig->name);
  96. len += led_trigger_snprintf(buf + len, size - len,
  97. " %s%s%s", hit ? "[" : "",
  98. trig->name, hit ? "]" : "");
  99. }
  100. len += led_trigger_snprintf(buf + len, size - len, "\n");
  101. return len;
  102. }
  103. /*
  104. * It was stupid to create 10000 cpu triggers, but we are stuck with it now.
  105. * Don't make that mistake again. We work around it here by creating binary
  106. * attribute, which is not limited by length. This is _not_ good design, do not
  107. * copy it.
  108. */
  109. ssize_t led_trigger_read(struct file *filp, struct kobject *kobj,
  110. const struct bin_attribute *attr, char *buf,
  111. loff_t pos, size_t count)
  112. {
  113. struct device *dev = kobj_to_dev(kobj);
  114. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  115. void *data;
  116. int len;
  117. down_read(&triggers_list_lock);
  118. down_read(&led_cdev->trigger_lock);
  119. len = led_trigger_format(NULL, 0, led_cdev);
  120. data = kvmalloc(len + 1, GFP_KERNEL);
  121. if (!data) {
  122. up_read(&led_cdev->trigger_lock);
  123. up_read(&triggers_list_lock);
  124. return -ENOMEM;
  125. }
  126. len = led_trigger_format(data, len + 1, led_cdev);
  127. up_read(&led_cdev->trigger_lock);
  128. up_read(&triggers_list_lock);
  129. len = memory_read_from_buffer(buf, count, &pos, data, len);
  130. kvfree(data);
  131. return len;
  132. }
  133. EXPORT_SYMBOL_GPL(led_trigger_read);
  134. /* Caller must ensure led_cdev->trigger_lock held */
  135. int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
  136. {
  137. char *event = NULL;
  138. char *envp[2];
  139. const char *name;
  140. int ret;
  141. if (!led_cdev->trigger && !trig)
  142. return 0;
  143. name = trig ? trig->name : "none";
  144. event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
  145. /* Remove any existing trigger */
  146. if (led_cdev->trigger) {
  147. spin_lock(&led_cdev->trigger->leddev_list_lock);
  148. list_del_rcu(&led_cdev->trig_list);
  149. spin_unlock(&led_cdev->trigger->leddev_list_lock);
  150. /* ensure it's no longer visible on the led_cdevs list */
  151. synchronize_rcu();
  152. cancel_work_sync(&led_cdev->set_brightness_work);
  153. led_stop_software_blink(led_cdev);
  154. device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
  155. if (led_cdev->trigger->deactivate)
  156. led_cdev->trigger->deactivate(led_cdev);
  157. led_cdev->trigger = NULL;
  158. led_cdev->trigger_data = NULL;
  159. led_cdev->activated = false;
  160. led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
  161. led_set_brightness(led_cdev, LED_OFF);
  162. }
  163. if (trig) {
  164. spin_lock(&trig->leddev_list_lock);
  165. list_add_tail_rcu(&led_cdev->trig_list, &trig->led_cdevs);
  166. spin_unlock(&trig->leddev_list_lock);
  167. led_cdev->trigger = trig;
  168. /*
  169. * Some activate() calls use led_trigger_event() to initialize
  170. * the brightness of the LED for which the trigger is being set.
  171. * Ensure the led_cdev is visible on trig->led_cdevs for this.
  172. */
  173. synchronize_rcu();
  174. /*
  175. * If "set brightness to 0" is pending in workqueue,
  176. * we don't want that to be reordered after ->activate()
  177. */
  178. flush_work(&led_cdev->set_brightness_work);
  179. ret = 0;
  180. if (trig->activate)
  181. ret = trig->activate(led_cdev);
  182. else
  183. led_set_brightness(led_cdev, trig->brightness);
  184. if (ret)
  185. goto err_activate;
  186. ret = device_add_groups(led_cdev->dev, trig->groups);
  187. if (ret) {
  188. dev_err(led_cdev->dev, "Failed to add trigger attributes\n");
  189. goto err_add_groups;
  190. }
  191. }
  192. if (event) {
  193. envp[0] = event;
  194. envp[1] = NULL;
  195. if (kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp))
  196. dev_err(led_cdev->dev,
  197. "%s: Error sending uevent\n", __func__);
  198. kfree(event);
  199. }
  200. return 0;
  201. err_add_groups:
  202. if (trig->deactivate)
  203. trig->deactivate(led_cdev);
  204. err_activate:
  205. spin_lock(&led_cdev->trigger->leddev_list_lock);
  206. list_del_rcu(&led_cdev->trig_list);
  207. spin_unlock(&led_cdev->trigger->leddev_list_lock);
  208. synchronize_rcu();
  209. led_cdev->trigger = NULL;
  210. led_cdev->trigger_data = NULL;
  211. led_set_brightness(led_cdev, LED_OFF);
  212. kfree(event);
  213. return ret;
  214. }
  215. EXPORT_SYMBOL_GPL(led_trigger_set);
  216. void led_trigger_remove(struct led_classdev *led_cdev)
  217. {
  218. down_write(&led_cdev->trigger_lock);
  219. led_trigger_set(led_cdev, NULL);
  220. up_write(&led_cdev->trigger_lock);
  221. }
  222. EXPORT_SYMBOL_GPL(led_trigger_remove);
  223. static bool led_match_default_trigger(struct led_classdev *led_cdev,
  224. struct led_trigger *trig)
  225. {
  226. if (!strcmp(led_cdev->default_trigger, trig->name) &&
  227. trigger_relevant(led_cdev, trig)) {
  228. led_cdev->flags |= LED_INIT_DEFAULT_TRIGGER;
  229. led_trigger_set(led_cdev, trig);
  230. return true;
  231. }
  232. return false;
  233. }
  234. void led_trigger_set_default(struct led_classdev *led_cdev)
  235. {
  236. struct led_trigger *trig;
  237. bool found = false;
  238. if (!led_cdev->default_trigger)
  239. return;
  240. if (!strcmp(led_cdev->default_trigger, "none")) {
  241. led_trigger_remove(led_cdev);
  242. return;
  243. }
  244. down_read(&triggers_list_lock);
  245. down_write(&led_cdev->trigger_lock);
  246. list_for_each_entry(trig, &trigger_list, next_trig) {
  247. found = led_match_default_trigger(led_cdev, trig);
  248. if (found)
  249. break;
  250. }
  251. up_write(&led_cdev->trigger_lock);
  252. up_read(&triggers_list_lock);
  253. /*
  254. * If default trigger wasn't found, maybe trigger module isn't loaded yet.
  255. * Once loaded it will re-probe with all led_cdev's.
  256. */
  257. if (!found)
  258. request_module_nowait("ledtrig:%s", led_cdev->default_trigger);
  259. }
  260. EXPORT_SYMBOL_GPL(led_trigger_set_default);
  261. /* LED Trigger Interface */
  262. int led_trigger_register(struct led_trigger *trig)
  263. {
  264. struct led_classdev *led_cdev;
  265. struct led_trigger *_trig;
  266. spin_lock_init(&trig->leddev_list_lock);
  267. INIT_LIST_HEAD(&trig->led_cdevs);
  268. down_write(&triggers_list_lock);
  269. /* Make sure the trigger's name isn't already in use */
  270. list_for_each_entry(_trig, &trigger_list, next_trig) {
  271. if (!strcmp(_trig->name, trig->name) &&
  272. (trig->trigger_type == _trig->trigger_type ||
  273. !trig->trigger_type || !_trig->trigger_type)) {
  274. up_write(&triggers_list_lock);
  275. return -EEXIST;
  276. }
  277. }
  278. /* Add to the list of led triggers */
  279. list_add_tail(&trig->next_trig, &trigger_list);
  280. up_write(&triggers_list_lock);
  281. /* Register with any LEDs that have this as a default trigger */
  282. down_read(&leds_list_lock);
  283. list_for_each_entry(led_cdev, &leds_list, node) {
  284. down_write(&led_cdev->trigger_lock);
  285. if (!led_cdev->trigger && led_cdev->default_trigger)
  286. led_match_default_trigger(led_cdev, trig);
  287. up_write(&led_cdev->trigger_lock);
  288. }
  289. up_read(&leds_list_lock);
  290. return 0;
  291. }
  292. EXPORT_SYMBOL_GPL(led_trigger_register);
  293. void led_trigger_unregister(struct led_trigger *trig)
  294. {
  295. struct led_classdev *led_cdev;
  296. if (list_empty_careful(&trig->next_trig))
  297. return;
  298. /* Remove from the list of led triggers */
  299. down_write(&triggers_list_lock);
  300. list_del_init(&trig->next_trig);
  301. up_write(&triggers_list_lock);
  302. /* Remove anyone actively using this trigger */
  303. down_read(&leds_list_lock);
  304. list_for_each_entry(led_cdev, &leds_list, node) {
  305. down_write(&led_cdev->trigger_lock);
  306. if (led_cdev->trigger == trig)
  307. led_trigger_set(led_cdev, NULL);
  308. up_write(&led_cdev->trigger_lock);
  309. }
  310. up_read(&leds_list_lock);
  311. }
  312. EXPORT_SYMBOL_GPL(led_trigger_unregister);
  313. static void devm_led_trigger_release(struct device *dev, void *res)
  314. {
  315. led_trigger_unregister(*(struct led_trigger **)res);
  316. }
  317. int devm_led_trigger_register(struct device *dev,
  318. struct led_trigger *trig)
  319. {
  320. struct led_trigger **dr;
  321. int rc;
  322. dr = devres_alloc(devm_led_trigger_release, sizeof(*dr),
  323. GFP_KERNEL);
  324. if (!dr)
  325. return -ENOMEM;
  326. *dr = trig;
  327. rc = led_trigger_register(trig);
  328. if (rc)
  329. devres_free(dr);
  330. else
  331. devres_add(dev, dr);
  332. return rc;
  333. }
  334. EXPORT_SYMBOL_GPL(devm_led_trigger_register);
  335. /* Simple LED Trigger Interface */
  336. void led_trigger_event(struct led_trigger *trig,
  337. enum led_brightness brightness)
  338. {
  339. struct led_classdev *led_cdev;
  340. if (!trig)
  341. return;
  342. trig->brightness = brightness;
  343. rcu_read_lock();
  344. list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list)
  345. led_set_brightness(led_cdev, brightness);
  346. rcu_read_unlock();
  347. }
  348. EXPORT_SYMBOL_GPL(led_trigger_event);
  349. void led_mc_trigger_event(struct led_trigger *trig,
  350. unsigned int *intensity_value, unsigned int num_colors,
  351. enum led_brightness brightness)
  352. {
  353. struct led_classdev *led_cdev;
  354. if (!trig)
  355. return;
  356. rcu_read_lock();
  357. list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) {
  358. if (!(led_cdev->flags & LED_MULTI_COLOR))
  359. continue;
  360. led_mc_set_brightness(led_cdev, intensity_value, num_colors, brightness);
  361. }
  362. rcu_read_unlock();
  363. }
  364. EXPORT_SYMBOL_GPL(led_mc_trigger_event);
  365. static void led_trigger_blink_setup(struct led_trigger *trig,
  366. unsigned long delay_on,
  367. unsigned long delay_off,
  368. int oneshot,
  369. int invert)
  370. {
  371. struct led_classdev *led_cdev;
  372. if (!trig)
  373. return;
  374. rcu_read_lock();
  375. list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) {
  376. if (oneshot)
  377. led_blink_set_oneshot(led_cdev, &delay_on, &delay_off,
  378. invert);
  379. else
  380. led_blink_set_nosleep(led_cdev, delay_on, delay_off);
  381. }
  382. rcu_read_unlock();
  383. }
  384. void led_trigger_blink(struct led_trigger *trig,
  385. unsigned long delay_on,
  386. unsigned long delay_off)
  387. {
  388. led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
  389. }
  390. EXPORT_SYMBOL_GPL(led_trigger_blink);
  391. void led_trigger_blink_oneshot(struct led_trigger *trig,
  392. unsigned long delay_on,
  393. unsigned long delay_off,
  394. int invert)
  395. {
  396. led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
  397. }
  398. EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
  399. void led_trigger_register_simple(const char *name, struct led_trigger **tp)
  400. {
  401. struct led_trigger *trig;
  402. int err;
  403. trig = kzalloc_obj(struct led_trigger);
  404. if (trig) {
  405. trig->name = name;
  406. err = led_trigger_register(trig);
  407. if (err < 0) {
  408. kfree(trig);
  409. trig = NULL;
  410. pr_warn("LED trigger %s failed to register (%d)\n",
  411. name, err);
  412. }
  413. } else {
  414. pr_warn("LED trigger %s failed to register (no memory)\n",
  415. name);
  416. }
  417. *tp = trig;
  418. }
  419. EXPORT_SYMBOL_GPL(led_trigger_register_simple);
  420. void led_trigger_unregister_simple(struct led_trigger *trig)
  421. {
  422. if (trig)
  423. led_trigger_unregister(trig);
  424. kfree(trig);
  425. }
  426. EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);