psw.c 2.8 KB

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