Merge branch 'akpm'
[linux-2.6/next.git] / arch / sh / boards / mach-highlander / psw.c
blob522786318d36c4f5dbee20c8cbdee94009bbf201
1 /*
2 * arch/sh/boards/renesas/r7780rp/psw.c
4 * push switch support for RDBRP-1/RDBREVRP-1 debug boards.
6 * Copyright (C) 2006 Paul Mundt
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.
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>
19 static irqreturn_t psw_irq_handler(int irq, void *arg)
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;
27 l = __raw_readw(PA_DBSW);
29 /* Nothing to do if there's no state change */
30 if (psw->state) {
31 ret = 1;
32 goto out;
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);
42 ret = 1;
45 out:
46 /* Clear the switch IRQs */
47 l |= (0x7 << 12);
48 __raw_writew(l, PA_DBSW);
50 return IRQ_RETVAL(ret);
53 static struct resource psw_resources[] = {
54 [0] = {
55 .start = IRQ_PSW,
56 .flags = IORESOURCE_IRQ,
60 static struct push_switch_platform_info s2_platform_data = {
61 .name = "s2",
62 .bit = 6,
63 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
64 IRQF_SHARED,
65 .irq_handler = psw_irq_handler,
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,
78 static struct push_switch_platform_info s3_platform_data = {
79 .name = "s3",
80 .bit = 5,
81 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
82 IRQF_SHARED,
83 .irq_handler = psw_irq_handler,
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,
96 static struct push_switch_platform_info s4_platform_data = {
97 .name = "s4",
98 .bit = 4,
99 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
100 IRQF_SHARED,
101 .irq_handler = psw_irq_handler,
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,
114 static struct platform_device *psw_devices[] = {
115 &s2_switch_device, &s3_switch_device, &s4_switch_device,
118 static int __init psw_init(void)
120 return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
122 module_init(psw_init);