Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
psw.c
Go to the documentation of this file.
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/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/platform_device.h>
16 #include <mach/highlander.h>
17 #include <asm/push-switch.h>
18 
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 l, mask;
25  int ret = 0;
26 
27  l = __raw_readw(PA_DBSW);
28 
29  /* Nothing to do if there's no state change */
30  if (psw->state) {
31  ret = 1;
32  goto out;
33  }
34 
35  mask = l & 0x70;
36  /* Figure out who raised it */
37  if (mask & (1 << psw_info->bit)) {
38  psw->state = !!(mask & (1 << psw_info->bit));
39  if (psw->state) /* debounce */
40  mod_timer(&psw->debounce, jiffies + 50);
41 
42  ret = 1;
43  }
44 
45 out:
46  /* Clear the switch IRQs */
47  l |= (0x7 << 12);
48  __raw_writew(l, PA_DBSW);
49 
50  return IRQ_RETVAL(ret);
51 }
52 
53 static struct resource psw_resources[] = {
54  [0] = {
55  .start = IRQ_PSW,
56  .flags = IORESOURCE_IRQ,
57  },
58 };
59 
60 static struct push_switch_platform_info s2_platform_data = {
61  .name = "s2",
62  .bit = 6,
65  .irq_handler = psw_irq_handler,
66 };
67 
68 static struct platform_device s2_switch_device = {
69  .name = "push-switch",
70  .id = 0,
71  .num_resources = ARRAY_SIZE(psw_resources),
72  .resource = psw_resources,
73  .dev = {
74  .platform_data = &s2_platform_data,
75  },
76 };
77 
78 static struct push_switch_platform_info s3_platform_data = {
79  .name = "s3",
80  .bit = 5,
83  .irq_handler = psw_irq_handler,
84 };
85 
86 static struct platform_device s3_switch_device = {
87  .name = "push-switch",
88  .id = 1,
89  .num_resources = ARRAY_SIZE(psw_resources),
90  .resource = psw_resources,
91  .dev = {
92  .platform_data = &s3_platform_data,
93  },
94 };
95 
96 static struct push_switch_platform_info s4_platform_data = {
97  .name = "s4",
98  .bit = 4,
100  IRQF_SHARED,
101  .irq_handler = psw_irq_handler,
102 };
103 
104 static struct platform_device s4_switch_device = {
105  .name = "push-switch",
106  .id = 2,
107  .num_resources = ARRAY_SIZE(psw_resources),
108  .resource = psw_resources,
109  .dev = {
110  .platform_data = &s4_platform_data,
111  },
112 };
113 
114 static struct platform_device *psw_devices[] = {
115  &s2_switch_device, &s3_switch_device, &s4_switch_device,
116 };
117 
118 static int __init psw_init(void)
119 {
120  return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
121 }
122 module_init(psw_init);