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 20 static irqreturn_t psw_irq_handler(int irq, void *arg) 21 { 22 struct platform_device *pdev = arg; 23 struct push_switch *psw = platform_get_drvdata(pdev); 24 struct push_switch_platform_info *psw_info = pdev->dev.platform_data; 25 unsigned int sw_value; 26 int ret = 0; 27 28 sw_value = (0x0ff & (~__raw_readb(PA_STATUS))); 29 30 /* Nothing to do if there's no state change */ 31 if (psw->state) { 32 ret = 1; 33 goto out; 34 } 35 36 /* Figure out who raised it */ 37 if (sw_value & (1 << psw_info->bit)) { 38 psw->state = 1; 39 mod_timer(&psw->debounce, jiffies + 50); 40 ret = 1; 41 } 42 43 out: 44 /* Clear the switch IRQs */ 45 __raw_writeb(0x00, PA_PWRINT_CLR); 46 47 return IRQ_RETVAL(ret); 48 } 49 50 static struct resource psw_power_resources[] = { 51 [0] = { 52 .start = IRQ_POWER, 53 .flags = IORESOURCE_IRQ, 54 }, 55 }; 56 57 static struct resource psw_usl5p_resources[] = { 58 [0] = { 59 .start = IRQ_BUTTON, 60 .flags = IORESOURCE_IRQ, 61 }, 62 }; 63 64 static struct push_switch_platform_info psw_power_platform_data = { 65 .name = "psw_power", 66 .bit = 4, 67 .irq_flags = IRQF_SHARED, 68 .irq_handler = psw_irq_handler, 69 }; 70 71 static struct push_switch_platform_info psw1_platform_data = { 72 .name = "psw1", 73 .bit = 0, 74 .irq_flags = IRQF_SHARED, 75 .irq_handler = psw_irq_handler, 76 }; 77 78 static struct push_switch_platform_info psw2_platform_data = { 79 .name = "psw2", 80 .bit = 2, 81 .irq_flags = IRQF_SHARED, 82 .irq_handler = psw_irq_handler, 83 }; 84 85 static struct push_switch_platform_info psw3_platform_data = { 86 .name = "psw3", 87 .bit = 1, 88 .irq_flags = IRQF_SHARED, 89 .irq_handler = psw_irq_handler, 90 }; 91 92 static struct platform_device psw_power_switch_device = { 93 .name = "push-switch", 94 .id = 0, 95 .num_resources = ARRAY_SIZE(psw_power_resources), 96 .resource = psw_power_resources, 97 .dev = { 98 .platform_data = &psw_power_platform_data, 99 }, 100 }; 101 102 static struct platform_device psw1_switch_device = { 103 .name = "push-switch", 104 .id = 1, 105 .num_resources = ARRAY_SIZE(psw_usl5p_resources), 106 .resource = psw_usl5p_resources, 107 .dev = { 108 .platform_data = &psw1_platform_data, 109 }, 110 }; 111 112 static struct platform_device psw2_switch_device = { 113 .name = "push-switch", 114 .id = 2, 115 .num_resources = ARRAY_SIZE(psw_usl5p_resources), 116 .resource = psw_usl5p_resources, 117 .dev = { 118 .platform_data = &psw2_platform_data, 119 }, 120 }; 121 122 static struct platform_device psw3_switch_device = { 123 .name = "push-switch", 124 .id = 3, 125 .num_resources = ARRAY_SIZE(psw_usl5p_resources), 126 .resource = psw_usl5p_resources, 127 .dev = { 128 .platform_data = &psw3_platform_data, 129 }, 130 }; 131 132 static struct platform_device *psw_devices[] = { 133 &psw_power_switch_device, 134 &psw1_switch_device, 135 &psw2_switch_device, 136 &psw3_switch_device, 137 }; 138 139 static int __init psw_init(void) 140 { 141 return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); 142 } 143 module_init(psw_init); 144