psw.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * arch/sh/boards/renesas/r7780rp/psw.c
  4. *
  5. * push switch support for RDBRP-1/RDBREVRP-1 debug boards.
  6. *
  7. * Copyright (C) 2006 Paul Mundt
  8. */
  9. #include <linux/io.h>
  10. #include <linux/module.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/platform_device.h>
  13. #include <mach/highlander.h>
  14. #include <asm/push-switch.h>
  15. static irqreturn_t psw_irq_handler(int irq, void *arg)
  16. {
  17. struct platform_device *pdev = arg;
  18. struct push_switch *psw = platform_get_drvdata(pdev);
  19. struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
  20. unsigned int l, mask;
  21. int ret = 0;
  22. l = __raw_readw(PA_DBSW);
  23. /* Nothing to do if there's no state change */
  24. if (psw->state) {
  25. ret = 1;
  26. goto out;
  27. }
  28. mask = l & 0x70;
  29. /* Figure out who raised it */
  30. if (mask & (1 << psw_info->bit)) {
  31. psw->state = !!(mask & (1 << psw_info->bit));
  32. if (psw->state) /* debounce */
  33. mod_timer(&psw->debounce, jiffies + 50);
  34. ret = 1;
  35. }
  36. out:
  37. /* Clear the switch IRQs */
  38. l |= (0x7 << 12);
  39. __raw_writew(l, PA_DBSW);
  40. return IRQ_RETVAL(ret);
  41. }
  42. static struct resource psw_resources[] = {
  43. [0] = {
  44. .start = IRQ_PSW,
  45. .flags = IORESOURCE_IRQ,
  46. },
  47. };
  48. static struct push_switch_platform_info s2_platform_data = {
  49. .name = "s2",
  50. .bit = 6,
  51. .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  52. IRQF_SHARED,
  53. .irq_handler = psw_irq_handler,
  54. };
  55. static struct platform_device s2_switch_device = {
  56. .name = "push-switch",
  57. .id = 0,
  58. .num_resources = ARRAY_SIZE(psw_resources),
  59. .resource = psw_resources,
  60. .dev = {
  61. .platform_data = &s2_platform_data,
  62. },
  63. };
  64. static struct push_switch_platform_info s3_platform_data = {
  65. .name = "s3",
  66. .bit = 5,
  67. .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  68. IRQF_SHARED,
  69. .irq_handler = psw_irq_handler,
  70. };
  71. static struct platform_device s3_switch_device = {
  72. .name = "push-switch",
  73. .id = 1,
  74. .num_resources = ARRAY_SIZE(psw_resources),
  75. .resource = psw_resources,
  76. .dev = {
  77. .platform_data = &s3_platform_data,
  78. },
  79. };
  80. static struct push_switch_platform_info s4_platform_data = {
  81. .name = "s4",
  82. .bit = 4,
  83. .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  84. IRQF_SHARED,
  85. .irq_handler = psw_irq_handler,
  86. };
  87. static struct platform_device s4_switch_device = {
  88. .name = "push-switch",
  89. .id = 2,
  90. .num_resources = ARRAY_SIZE(psw_resources),
  91. .resource = psw_resources,
  92. .dev = {
  93. .platform_data = &s4_platform_data,
  94. },
  95. };
  96. static struct platform_device *psw_devices[] = {
  97. &s2_switch_device, &s3_switch_device, &s4_switch_device,
  98. };
  99. static int __init psw_init(void)
  100. {
  101. return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
  102. }
  103. module_init(psw_init);