psw.c 3.2 KB

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