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