gpio-button-hotplug.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. * GPIO Button Hotplug driver
  3. *
  4. * Copyright (C) 2012 Felix Fietkau <[email protected]>
  5. * Copyright (C) 2008-2010 Gabor Juhos <[email protected]>
  6. *
  7. * Based on the diag.c - GPIO interface driver for Broadcom boards
  8. * Copyright (C) 2006 Mike Baker <[email protected]>,
  9. * Copyright (C) 2006-2007 Felix Fietkau <[email protected]>
  10. * Copyright (C) 2008 Andy Boyett <[email protected]>
  11. *
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU General Public License version 2 as published
  14. * by the Free Software Foundation.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/version.h>
  18. #include <linux/kmod.h>
  19. #include <linux/workqueue.h>
  20. #include <linux/skbuff.h>
  21. #include <linux/netlink.h>
  22. #include <linux/kobject.h>
  23. #include <linux/input.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/of_irq.h>
  27. #include <linux/gpio.h>
  28. #include <linux/gpio_keys.h>
  29. #include <linux/gpio/consumer.h>
  30. #define BH_SKB_SIZE 2048
  31. #define DRV_NAME "gpio-keys"
  32. #define PFX DRV_NAME ": "
  33. struct bh_event {
  34. const char *name;
  35. unsigned int type;
  36. char *action;
  37. unsigned long seen;
  38. struct sk_buff *skb;
  39. struct work_struct work;
  40. };
  41. struct bh_map {
  42. unsigned int code;
  43. const char *name;
  44. };
  45. struct gpio_keys_button_data {
  46. struct delayed_work work;
  47. unsigned long seen;
  48. int map_entry;
  49. int last_state;
  50. int count;
  51. int threshold;
  52. int can_sleep;
  53. int irq;
  54. unsigned int software_debounce;
  55. struct gpio_desc *gpiod;
  56. const struct gpio_keys_button *b;
  57. };
  58. extern u64 uevent_next_seqnum(void);
  59. #define BH_MAP(_code, _name) \
  60. { \
  61. .code = (_code), \
  62. .name = (_name), \
  63. }
  64. static const struct bh_map button_map[] = {
  65. BH_MAP(BTN_0, "BTN_0"),
  66. BH_MAP(BTN_1, "BTN_1"),
  67. BH_MAP(BTN_2, "BTN_2"),
  68. BH_MAP(BTN_3, "BTN_3"),
  69. BH_MAP(BTN_4, "BTN_4"),
  70. BH_MAP(BTN_5, "BTN_5"),
  71. BH_MAP(BTN_6, "BTN_6"),
  72. BH_MAP(BTN_7, "BTN_7"),
  73. BH_MAP(BTN_8, "BTN_8"),
  74. BH_MAP(BTN_9, "BTN_9"),
  75. BH_MAP(KEY_BRIGHTNESS_ZERO, "brightness_zero"),
  76. BH_MAP(KEY_CONFIG, "config"),
  77. BH_MAP(KEY_COPY, "copy"),
  78. BH_MAP(KEY_EJECTCD, "eject"),
  79. BH_MAP(KEY_HELP, "help"),
  80. BH_MAP(KEY_LIGHTS_TOGGLE, "lights_toggle"),
  81. BH_MAP(KEY_PHONE, "phone"),
  82. BH_MAP(KEY_POWER, "power"),
  83. BH_MAP(KEY_POWER2, "reboot"),
  84. BH_MAP(KEY_RESTART, "reset"),
  85. BH_MAP(KEY_RFKILL, "rfkill"),
  86. BH_MAP(KEY_VIDEO, "video"),
  87. BH_MAP(KEY_VOLUMEDOWN, "volume_down"),
  88. BH_MAP(KEY_VOLUMEUP, "volume_up"),
  89. BH_MAP(KEY_WIMAX, "wwan"),
  90. BH_MAP(KEY_WLAN, "wlan"),
  91. BH_MAP(KEY_WPS_BUTTON, "wps"),
  92. BH_MAP(KEY_VENDOR, "vendor"),
  93. };
  94. /* -------------------------------------------------------------------------*/
  95. static __printf(3, 4)
  96. int bh_event_add_var(struct bh_event *event, int argv, const char *format, ...)
  97. {
  98. char buf[128];
  99. char *s;
  100. va_list args;
  101. int len;
  102. if (argv)
  103. return 0;
  104. va_start(args, format);
  105. len = vsnprintf(buf, sizeof(buf), format, args);
  106. va_end(args);
  107. if (len >= sizeof(buf)) {
  108. WARN(1, "buffer size too small");
  109. return -ENOMEM;
  110. }
  111. s = skb_put(event->skb, len + 1);
  112. strcpy(s, buf);
  113. pr_debug(PFX "added variable '%s'\n", s);
  114. return 0;
  115. }
  116. static int button_hotplug_fill_event(struct bh_event *event)
  117. {
  118. int ret;
  119. ret = bh_event_add_var(event, 0, "HOME=%s", "/");
  120. if (ret)
  121. return ret;
  122. ret = bh_event_add_var(event, 0, "PATH=%s",
  123. "/sbin:/bin:/usr/sbin:/usr/bin");
  124. if (ret)
  125. return ret;
  126. ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
  127. if (ret)
  128. return ret;
  129. ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
  130. if (ret)
  131. return ret;
  132. ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
  133. if (ret)
  134. return ret;
  135. if (event->type == EV_SW) {
  136. ret = bh_event_add_var(event, 0, "TYPE=%s", "switch");
  137. if (ret)
  138. return ret;
  139. }
  140. ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
  141. if (ret)
  142. return ret;
  143. ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
  144. return ret;
  145. }
  146. static void button_hotplug_work(struct work_struct *work)
  147. {
  148. struct bh_event *event = container_of(work, struct bh_event, work);
  149. int ret = 0;
  150. event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
  151. if (!event->skb)
  152. goto out_free_event;
  153. ret = bh_event_add_var(event, 0, "%s@", event->action);
  154. if (ret)
  155. goto out_free_skb;
  156. ret = button_hotplug_fill_event(event);
  157. if (ret)
  158. goto out_free_skb;
  159. NETLINK_CB(event->skb).dst_group = 1;
  160. broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
  161. out_free_skb:
  162. if (ret) {
  163. pr_err(PFX "work error %d\n", ret);
  164. kfree_skb(event->skb);
  165. }
  166. out_free_event:
  167. kfree(event);
  168. }
  169. static int button_hotplug_create_event(const char *name, unsigned int type,
  170. unsigned long seen, int pressed)
  171. {
  172. struct bh_event *event;
  173. pr_debug(PFX "create event, name=%s, seen=%lu, pressed=%d\n",
  174. name, seen, pressed);
  175. event = kzalloc(sizeof(*event), GFP_KERNEL);
  176. if (!event)
  177. return -ENOMEM;
  178. event->name = name;
  179. event->type = type;
  180. event->seen = seen;
  181. event->action = pressed ? "pressed" : "released";
  182. INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
  183. schedule_work(&event->work);
  184. return 0;
  185. }
  186. /* -------------------------------------------------------------------------*/
  187. static int button_get_index(unsigned int code)
  188. {
  189. int i;
  190. for (i = 0; i < ARRAY_SIZE(button_map); i++)
  191. if (button_map[i].code == code)
  192. return i;
  193. return -1;
  194. }
  195. static int gpio_button_get_value(struct gpio_keys_button_data *bdata)
  196. {
  197. int val;
  198. if (bdata->can_sleep)
  199. val = !!gpiod_get_value_cansleep(bdata->gpiod);
  200. else
  201. val = !!gpiod_get_value(bdata->gpiod);
  202. return val;
  203. }
  204. static void gpio_keys_handle_button(struct gpio_keys_button_data *bdata)
  205. {
  206. unsigned int type = bdata->b->type ?: EV_KEY;
  207. int state = gpio_button_get_value(bdata);
  208. unsigned long seen = jiffies;
  209. pr_debug(PFX "event type=%u, code=%u, pressed=%d\n",
  210. type, bdata->b->code, state);
  211. /* is this the initialization state? */
  212. if (bdata->last_state == -1) {
  213. /*
  214. * Don't advertise unpressed buttons on initialization.
  215. * Just save their state and continue otherwise this
  216. * can cause OpenWrt to enter failsafe.
  217. */
  218. if (type == EV_KEY && state == 0)
  219. goto set_state;
  220. /*
  221. * But we are very interested in pressed buttons and
  222. * initial switch state. These will be reported to
  223. * userland.
  224. */
  225. } else if (bdata->last_state == state) {
  226. /* reset asserted counter (only relevant for polled keys) */
  227. bdata->count = 0;
  228. return;
  229. }
  230. if (bdata->count < bdata->threshold) {
  231. bdata->count++;
  232. return;
  233. }
  234. if (bdata->seen == 0)
  235. bdata->seen = seen;
  236. button_hotplug_create_event(button_map[bdata->map_entry].name, type,
  237. (seen - bdata->seen) / HZ, state);
  238. bdata->seen = seen;
  239. set_state:
  240. bdata->last_state = state;
  241. bdata->count = 0;
  242. }
  243. struct gpio_keys_button_dev {
  244. int polled;
  245. struct delayed_work work;
  246. struct device *dev;
  247. struct gpio_keys_platform_data *pdata;
  248. struct gpio_keys_button_data data[];
  249. };
  250. static void gpio_keys_polled_queue_work(struct gpio_keys_button_dev *bdev)
  251. {
  252. struct gpio_keys_platform_data *pdata = bdev->pdata;
  253. unsigned long delay = msecs_to_jiffies(pdata->poll_interval);
  254. if (delay >= HZ)
  255. delay = round_jiffies_relative(delay);
  256. schedule_delayed_work(&bdev->work, delay);
  257. }
  258. static void gpio_keys_polled_poll(struct work_struct *work)
  259. {
  260. struct gpio_keys_button_dev *bdev =
  261. container_of(work, struct gpio_keys_button_dev, work.work);
  262. int i;
  263. for (i = 0; i < bdev->pdata->nbuttons; i++) {
  264. struct gpio_keys_button_data *bdata = &bdev->data[i];
  265. if (bdata->gpiod)
  266. gpio_keys_handle_button(bdata);
  267. }
  268. gpio_keys_polled_queue_work(bdev);
  269. }
  270. static void gpio_keys_polled_close(struct gpio_keys_button_dev *bdev)
  271. {
  272. struct gpio_keys_platform_data *pdata = bdev->pdata;
  273. cancel_delayed_work_sync(&bdev->work);
  274. if (pdata->disable)
  275. pdata->disable(bdev->dev);
  276. }
  277. static void gpio_keys_irq_work_func(struct work_struct *work)
  278. {
  279. struct gpio_keys_button_data *bdata = container_of(work,
  280. struct gpio_keys_button_data, work.work);
  281. gpio_keys_handle_button(bdata);
  282. }
  283. static irqreturn_t button_handle_irq(int irq, void *_bdata)
  284. {
  285. struct gpio_keys_button_data *bdata =
  286. (struct gpio_keys_button_data *) _bdata;
  287. mod_delayed_work(system_wq, &bdata->work,
  288. msecs_to_jiffies(bdata->software_debounce));
  289. return IRQ_HANDLED;
  290. }
  291. #ifdef CONFIG_OF
  292. static struct gpio_keys_platform_data *
  293. gpio_keys_get_devtree_pdata(struct device *dev)
  294. {
  295. struct device_node *node = dev->of_node;
  296. struct gpio_keys_platform_data *pdata;
  297. int nbuttons;
  298. int i = 0;
  299. nbuttons = of_get_available_child_count(node);
  300. if (nbuttons == 0)
  301. return ERR_PTR(-EINVAL);
  302. pdata = devm_kzalloc(dev, sizeof(struct gpio_keys_platform_data), GFP_KERNEL);
  303. if (!pdata)
  304. return ERR_PTR(-ENOMEM);
  305. pdata->buttons = devm_kmalloc_array(dev, nbuttons, sizeof(struct gpio_keys_button), GFP_KERNEL);
  306. if (!pdata->buttons)
  307. return ERR_PTR(-ENOMEM);
  308. pdata->nbuttons = nbuttons;
  309. pdata->rep = of_property_present(node, "autorepeat");
  310. of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
  311. for_each_available_child_of_node_scoped(node, pp) {
  312. struct gpio_keys_button *button = (struct gpio_keys_button *)&pdata->buttons[i++];
  313. if (of_property_read_u32(pp, "linux,code", &button->code)) {
  314. dev_err(dev, "Button node '%s' without keycode\n",
  315. pp->full_name);
  316. return ERR_PTR(-EINVAL);
  317. }
  318. button->desc = of_get_property(pp, "label", NULL);
  319. if (of_property_read_u32(pp, "linux,input-type", &button->type))
  320. button->type = EV_KEY;
  321. button->wakeup = of_property_present(pp, "gpio-key,wakeup");
  322. if (of_property_read_u32(pp, "debounce-interval",
  323. &button->debounce_interval))
  324. button->debounce_interval = 5;
  325. button->irq = irq_of_parse_and_map(pp, 0);
  326. button->gpio = -ENOENT; /* mark this as device-tree */
  327. }
  328. return pdata;
  329. }
  330. static const struct of_device_id gpio_keys_of_match[] = {
  331. { .compatible = "gpio-keys", },
  332. { },
  333. };
  334. MODULE_DEVICE_TABLE(of, gpio_keys_of_match);
  335. static const struct of_device_id gpio_keys_polled_of_match[] = {
  336. { .compatible = "gpio-keys-polled", },
  337. { },
  338. };
  339. MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
  340. #else
  341. static inline struct gpio_keys_platform_data *
  342. gpio_keys_get_devtree_pdata(struct device *dev)
  343. {
  344. return NULL;
  345. }
  346. #endif
  347. static int gpio_keys_button_probe(struct platform_device *pdev,
  348. struct gpio_keys_button_dev **_bdev, int polled)
  349. {
  350. struct device *dev = &pdev->dev;
  351. struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
  352. struct gpio_keys_button_dev *bdev;
  353. struct gpio_keys_button *buttons;
  354. struct device_node *prev = NULL;
  355. int error = 0;
  356. int i;
  357. if (!pdata) {
  358. pdata = gpio_keys_get_devtree_pdata(dev);
  359. if (IS_ERR(pdata))
  360. return PTR_ERR(pdata);
  361. if (!pdata) {
  362. dev_err(dev, "missing platform data\n");
  363. return -EINVAL;
  364. }
  365. }
  366. if (polled && !pdata->poll_interval) {
  367. dev_err(dev, "missing poll_interval value\n");
  368. return -EINVAL;
  369. }
  370. buttons = devm_kmemdup_array(dev, pdata->buttons, pdata->nbuttons, sizeof(struct gpio_keys_button),
  371. GFP_KERNEL);
  372. if (!buttons) {
  373. dev_err(dev, "no memory for button data\n");
  374. return -ENOMEM;
  375. }
  376. bdev = devm_kzalloc(dev, struct_size(bdev, data, pdata->nbuttons), GFP_KERNEL);
  377. if (!bdev) {
  378. dev_err(dev, "no memory for private data\n");
  379. return -ENOMEM;
  380. }
  381. bdev->polled = polled;
  382. for (i = 0; i < pdata->nbuttons; i++) {
  383. struct gpio_keys_button *button = &buttons[i];
  384. struct gpio_keys_button_data *bdata = &bdev->data[i];
  385. const char *desc = button->desc ? button->desc : DRV_NAME;
  386. if (button->wakeup) {
  387. dev_err(dev, "does not support wakeup\n");
  388. error = -EINVAL;
  389. goto out;
  390. }
  391. bdata->map_entry = button_get_index(button->code);
  392. if (bdata->map_entry < 0) {
  393. dev_err(dev, "does not support key code:%u\n",
  394. button->code);
  395. error = -EINVAL;
  396. goto out;
  397. }
  398. if (!(button->type == 0 || button->type == EV_KEY ||
  399. button->type == EV_SW)) {
  400. dev_err(dev, "only supports buttons or switches\n");
  401. error = -EINVAL;
  402. goto out;
  403. }
  404. if (button->irq) {
  405. dev_err(dev, "skipping button %s (only gpio buttons supported)\n",
  406. button->desc);
  407. bdata->b = &pdata->buttons[i];
  408. continue;
  409. }
  410. if (gpio_is_valid(button->gpio)) {
  411. /* legacy platform data... but is it the lookup table? */
  412. bdata->gpiod = devm_gpiod_get_index(dev, desc, i,
  413. GPIOD_IN);
  414. if (IS_ERR(bdata->gpiod)) {
  415. /* or the legacy (button->gpio is good) way? */
  416. error = devm_gpio_request_one(dev,
  417. button->gpio, GPIOF_IN | (
  418. button->active_low ? GPIOF_ACTIVE_LOW :
  419. 0), desc);
  420. if (error) {
  421. dev_err_probe(dev, error,
  422. "unable to claim gpio %d",
  423. button->gpio);
  424. goto out;
  425. }
  426. bdata->gpiod = gpio_to_desc(button->gpio);
  427. }
  428. } else {
  429. /* Device-tree */
  430. struct device_node *child =
  431. of_get_next_child(dev->of_node, prev);
  432. bdata->gpiod = devm_fwnode_gpiod_get(dev,
  433. of_fwnode_handle(child), NULL, GPIOD_IN,
  434. desc);
  435. prev = child;
  436. }
  437. if (IS_ERR_OR_NULL(bdata->gpiod)) {
  438. error = IS_ERR(bdata->gpiod) ? PTR_ERR(bdata->gpiod) :
  439. -EINVAL;
  440. goto out;
  441. }
  442. bdata->can_sleep = gpiod_cansleep(bdata->gpiod);
  443. bdata->last_state = -1; /* Unknown state on boot */
  444. if (bdev->polled) {
  445. bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
  446. pdata->poll_interval);
  447. } else {
  448. /* bdata->threshold = 0; already initialized */
  449. if (button->debounce_interval) {
  450. error = gpiod_set_debounce(bdata->gpiod,
  451. button->debounce_interval * 1000);
  452. /*
  453. * use timer if gpiolib doesn't provide
  454. * debounce.
  455. */
  456. if (error < 0) {
  457. bdata->software_debounce =
  458. button->debounce_interval;
  459. }
  460. }
  461. }
  462. bdata->b = &pdata->buttons[i];
  463. }
  464. bdev->dev = &pdev->dev;
  465. bdev->pdata = pdata;
  466. platform_set_drvdata(pdev, bdev);
  467. *_bdev = bdev;
  468. error = 0;
  469. out:
  470. of_node_put(prev);
  471. return error;
  472. }
  473. static int gpio_keys_probe(struct platform_device *pdev)
  474. {
  475. struct gpio_keys_platform_data *pdata;
  476. struct gpio_keys_button_dev *bdev;
  477. int ret, i;
  478. ret = gpio_keys_button_probe(pdev, &bdev, 0);
  479. if (ret)
  480. return ret;
  481. pdata = bdev->pdata;
  482. for (i = 0; i < pdata->nbuttons; i++) {
  483. const struct gpio_keys_button *button = &pdata->buttons[i];
  484. struct gpio_keys_button_data *bdata = &bdev->data[i];
  485. unsigned long irqflags = IRQF_ONESHOT;
  486. INIT_DELAYED_WORK(&bdata->work, gpio_keys_irq_work_func);
  487. if (!button->irq) {
  488. bdata->irq = gpiod_to_irq(bdata->gpiod);
  489. if (bdata->irq < 0) {
  490. dev_err(&pdev->dev, "failed to get irq for gpio:%d\n",
  491. button->gpio);
  492. continue;
  493. }
  494. irqflags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
  495. } else {
  496. bdata->irq = button->irq;
  497. }
  498. schedule_delayed_work(&bdata->work,
  499. msecs_to_jiffies(bdata->software_debounce));
  500. ret = devm_request_threaded_irq(&pdev->dev,
  501. bdata->irq, NULL, button_handle_irq,
  502. irqflags, dev_name(&pdev->dev), bdata);
  503. if (ret < 0) {
  504. bdata->irq = 0;
  505. dev_err(&pdev->dev, "failed to request irq:%d for gpio:%d\n",
  506. bdata->irq, button->gpio);
  507. continue;
  508. } else {
  509. dev_dbg(&pdev->dev, "gpio:%d has irq:%d\n",
  510. button->gpio, bdata->irq);
  511. }
  512. }
  513. return 0;
  514. }
  515. static int gpio_keys_polled_probe(struct platform_device *pdev)
  516. {
  517. struct gpio_keys_platform_data *pdata;
  518. struct gpio_keys_button_dev *bdev;
  519. int ret;
  520. ret = gpio_keys_button_probe(pdev, &bdev, 1);
  521. if (ret)
  522. return ret;
  523. INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
  524. pdata = bdev->pdata;
  525. if (pdata->enable)
  526. pdata->enable(bdev->dev);
  527. gpio_keys_polled_queue_work(bdev);
  528. return ret;
  529. }
  530. static void gpio_keys_irq_close(struct gpio_keys_button_dev *bdev)
  531. {
  532. struct gpio_keys_platform_data *pdata = bdev->pdata;
  533. size_t i;
  534. for (i = 0; i < pdata->nbuttons; i++) {
  535. struct gpio_keys_button_data *bdata = &bdev->data[i];
  536. disable_irq(bdata->irq);
  537. cancel_delayed_work_sync(&bdata->work);
  538. }
  539. }
  540. static void gpio_keys_remove(struct platform_device *pdev)
  541. {
  542. struct gpio_keys_button_dev *bdev = platform_get_drvdata(pdev);
  543. platform_set_drvdata(pdev, NULL);
  544. if (bdev->polled)
  545. gpio_keys_polled_close(bdev);
  546. else
  547. gpio_keys_irq_close(bdev);
  548. }
  549. static struct platform_driver gpio_keys_driver = {
  550. .probe = gpio_keys_probe,
  551. .remove_new = gpio_keys_remove,
  552. .driver = {
  553. .name = "gpio-keys",
  554. .of_match_table = of_match_ptr(gpio_keys_of_match),
  555. },
  556. };
  557. static struct platform_driver gpio_keys_polled_driver = {
  558. .probe = gpio_keys_polled_probe,
  559. .remove_new = gpio_keys_remove,
  560. .driver = {
  561. .name = "gpio-keys-polled",
  562. .of_match_table = of_match_ptr(gpio_keys_polled_of_match),
  563. },
  564. };
  565. static int __init gpio_button_init(void)
  566. {
  567. int ret;
  568. ret = platform_driver_register(&gpio_keys_driver);
  569. if (ret)
  570. return ret;
  571. ret = platform_driver_register(&gpio_keys_polled_driver);
  572. if (ret)
  573. platform_driver_unregister(&gpio_keys_driver);
  574. return ret;
  575. }
  576. static void __exit gpio_button_exit(void)
  577. {
  578. platform_driver_unregister(&gpio_keys_driver);
  579. platform_driver_unregister(&gpio_keys_polled_driver);
  580. }
  581. module_init(gpio_button_init);
  582. module_exit(gpio_button_exit);
  583. MODULE_AUTHOR("Gabor Juhos <[email protected]>");
  584. MODULE_AUTHOR("Felix Fietkau <[email protected]>");
  585. MODULE_DESCRIPTION("Polled GPIO Buttons hotplug driver");
  586. MODULE_LICENSE("GPL v2");
  587. MODULE_ALIAS("platform:" DRV_NAME);