psw.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * arch/sh/boards/landisk/psw.c
  4. *
  5. * push switch support for LANDISK and USL-5P
  6. *
  7. * Copyright (C) 2006-2007 Paul Mundt
  8. * Copyright (C) 2007 kogiidena
  9. */
  10. #include <linux/io.h>
  11. #include <linux/init.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/platform_device.h>
  14. #include <mach-landisk/mach/iodata_landisk.h>
  15. #include <asm/push-switch.h>
  16. static irqreturn_t psw_irq_handler(int irq, void *arg)
  17. {
  18. struct platform_device *pdev = arg;
  19. struct push_switch *psw = platform_get_drvdata(pdev);
  20. struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
  21. unsigned int sw_value;
  22. int ret = 0;
  23. sw_value = (0x0ff & (~__raw_readb(PA_STATUS)));
  24. /* Nothing to do if there's no state change */
  25. if (psw->state) {
  26. ret = 1;
  27. goto out;
  28. }
  29. /* Figure out who raised it */
  30. if (sw_value & (1 << psw_info->bit)) {
  31. psw->state = 1;
  32. mod_timer(&psw->debounce, jiffies + 50);
  33. ret = 1;
  34. }
  35. out:
  36. /* Clear the switch IRQs */
  37. __raw_writeb(0x00, PA_PWRINT_CLR);
  38. return IRQ_RETVAL(ret);
  39. }
  40. static struct resource psw_power_resources[] = {
  41. [0] = {
  42. .start = IRQ_POWER,
  43. .flags = IORESOURCE_IRQ,
  44. },
  45. };
  46. static struct resource psw_usl5p_resources[] = {
  47. [0] = {
  48. .start = IRQ_BUTTON,
  49. .flags = IORESOURCE_IRQ,
  50. },
  51. };
  52. static struct push_switch_platform_info psw_power_platform_data = {
  53. .name = "psw_power",
  54. .bit = 4,
  55. .irq_flags = IRQF_SHARED,
  56. .irq_handler = psw_irq_handler,
  57. };
  58. static struct push_switch_platform_info psw1_platform_data = {
  59. .name = "psw1",
  60. .bit = 0,
  61. .irq_flags = IRQF_SHARED,
  62. .irq_handler = psw_irq_handler,
  63. };
  64. static struct push_switch_platform_info psw2_platform_data = {
  65. .name = "psw2",
  66. .bit = 2,
  67. .irq_flags = IRQF_SHARED,
  68. .irq_handler = psw_irq_handler,
  69. };
  70. static struct push_switch_platform_info psw3_platform_data = {
  71. .name = "psw3",
  72. .bit = 1,
  73. .irq_flags = IRQF_SHARED,
  74. .irq_handler = psw_irq_handler,
  75. };
  76. static struct platform_device psw_power_switch_device = {
  77. .name = "push-switch",
  78. .id = 0,
  79. .num_resources = ARRAY_SIZE(psw_power_resources),
  80. .resource = psw_power_resources,
  81. .dev = {
  82. .platform_data = &psw_power_platform_data,
  83. },
  84. };
  85. static struct platform_device psw1_switch_device = {
  86. .name = "push-switch",
  87. .id = 1,
  88. .num_resources = ARRAY_SIZE(psw_usl5p_resources),
  89. .resource = psw_usl5p_resources,
  90. .dev = {
  91. .platform_data = &psw1_platform_data,
  92. },
  93. };
  94. static struct platform_device psw2_switch_device = {
  95. .name = "push-switch",
  96. .id = 2,
  97. .num_resources = ARRAY_SIZE(psw_usl5p_resources),
  98. .resource = psw_usl5p_resources,
  99. .dev = {
  100. .platform_data = &psw2_platform_data,
  101. },
  102. };
  103. static struct platform_device psw3_switch_device = {
  104. .name = "push-switch",
  105. .id = 3,
  106. .num_resources = ARRAY_SIZE(psw_usl5p_resources),
  107. .resource = psw_usl5p_resources,
  108. .dev = {
  109. .platform_data = &psw3_platform_data,
  110. },
  111. };
  112. static struct platform_device *psw_devices[] = {
  113. &psw_power_switch_device,
  114. &psw1_switch_device,
  115. &psw2_switch_device,
  116. &psw3_switch_device,
  117. };
  118. static int __init psw_init(void)
  119. {
  120. return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
  121. }
  122. device_initcall(psw_init);