18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/sh/boards/landisk/psw.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * push switch support for LANDISK and USL-5P 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2006-2007 Paul Mundt 88c2ecf20Sopenharmony_ci * Copyright (C) 2007 kogiidena 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/init.h> 128c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 138c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 148c2ecf20Sopenharmony_ci#include <mach-landisk/mach/iodata_landisk.h> 158c2ecf20Sopenharmony_ci#include <asm/push-switch.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic irqreturn_t psw_irq_handler(int irq, void *arg) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci struct platform_device *pdev = arg; 208c2ecf20Sopenharmony_ci struct push_switch *psw = platform_get_drvdata(pdev); 218c2ecf20Sopenharmony_ci struct push_switch_platform_info *psw_info = pdev->dev.platform_data; 228c2ecf20Sopenharmony_ci unsigned int sw_value; 238c2ecf20Sopenharmony_ci int ret = 0; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci sw_value = (0x0ff & (~__raw_readb(PA_STATUS))); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* Nothing to do if there's no state change */ 288c2ecf20Sopenharmony_ci if (psw->state) { 298c2ecf20Sopenharmony_ci ret = 1; 308c2ecf20Sopenharmony_ci goto out; 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci /* Figure out who raised it */ 348c2ecf20Sopenharmony_ci if (sw_value & (1 << psw_info->bit)) { 358c2ecf20Sopenharmony_ci psw->state = 1; 368c2ecf20Sopenharmony_ci mod_timer(&psw->debounce, jiffies + 50); 378c2ecf20Sopenharmony_ci ret = 1; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciout: 418c2ecf20Sopenharmony_ci /* Clear the switch IRQs */ 428c2ecf20Sopenharmony_ci __raw_writeb(0x00, PA_PWRINT_CLR); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci return IRQ_RETVAL(ret); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic struct resource psw_power_resources[] = { 488c2ecf20Sopenharmony_ci [0] = { 498c2ecf20Sopenharmony_ci .start = IRQ_POWER, 508c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 518c2ecf20Sopenharmony_ci }, 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic struct resource psw_usl5p_resources[] = { 558c2ecf20Sopenharmony_ci [0] = { 568c2ecf20Sopenharmony_ci .start = IRQ_BUTTON, 578c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 588c2ecf20Sopenharmony_ci }, 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic struct push_switch_platform_info psw_power_platform_data = { 628c2ecf20Sopenharmony_ci .name = "psw_power", 638c2ecf20Sopenharmony_ci .bit = 4, 648c2ecf20Sopenharmony_ci .irq_flags = IRQF_SHARED, 658c2ecf20Sopenharmony_ci .irq_handler = psw_irq_handler, 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic struct push_switch_platform_info psw1_platform_data = { 698c2ecf20Sopenharmony_ci .name = "psw1", 708c2ecf20Sopenharmony_ci .bit = 0, 718c2ecf20Sopenharmony_ci .irq_flags = IRQF_SHARED, 728c2ecf20Sopenharmony_ci .irq_handler = psw_irq_handler, 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic struct push_switch_platform_info psw2_platform_data = { 768c2ecf20Sopenharmony_ci .name = "psw2", 778c2ecf20Sopenharmony_ci .bit = 2, 788c2ecf20Sopenharmony_ci .irq_flags = IRQF_SHARED, 798c2ecf20Sopenharmony_ci .irq_handler = psw_irq_handler, 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic struct push_switch_platform_info psw3_platform_data = { 838c2ecf20Sopenharmony_ci .name = "psw3", 848c2ecf20Sopenharmony_ci .bit = 1, 858c2ecf20Sopenharmony_ci .irq_flags = IRQF_SHARED, 868c2ecf20Sopenharmony_ci .irq_handler = psw_irq_handler, 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic struct platform_device psw_power_switch_device = { 908c2ecf20Sopenharmony_ci .name = "push-switch", 918c2ecf20Sopenharmony_ci .id = 0, 928c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(psw_power_resources), 938c2ecf20Sopenharmony_ci .resource = psw_power_resources, 948c2ecf20Sopenharmony_ci .dev = { 958c2ecf20Sopenharmony_ci .platform_data = &psw_power_platform_data, 968c2ecf20Sopenharmony_ci }, 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic struct platform_device psw1_switch_device = { 1008c2ecf20Sopenharmony_ci .name = "push-switch", 1018c2ecf20Sopenharmony_ci .id = 1, 1028c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(psw_usl5p_resources), 1038c2ecf20Sopenharmony_ci .resource = psw_usl5p_resources, 1048c2ecf20Sopenharmony_ci .dev = { 1058c2ecf20Sopenharmony_ci .platform_data = &psw1_platform_data, 1068c2ecf20Sopenharmony_ci }, 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic struct platform_device psw2_switch_device = { 1108c2ecf20Sopenharmony_ci .name = "push-switch", 1118c2ecf20Sopenharmony_ci .id = 2, 1128c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(psw_usl5p_resources), 1138c2ecf20Sopenharmony_ci .resource = psw_usl5p_resources, 1148c2ecf20Sopenharmony_ci .dev = { 1158c2ecf20Sopenharmony_ci .platform_data = &psw2_platform_data, 1168c2ecf20Sopenharmony_ci }, 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic struct platform_device psw3_switch_device = { 1208c2ecf20Sopenharmony_ci .name = "push-switch", 1218c2ecf20Sopenharmony_ci .id = 3, 1228c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(psw_usl5p_resources), 1238c2ecf20Sopenharmony_ci .resource = psw_usl5p_resources, 1248c2ecf20Sopenharmony_ci .dev = { 1258c2ecf20Sopenharmony_ci .platform_data = &psw3_platform_data, 1268c2ecf20Sopenharmony_ci }, 1278c2ecf20Sopenharmony_ci}; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistatic struct platform_device *psw_devices[] = { 1308c2ecf20Sopenharmony_ci &psw_power_switch_device, 1318c2ecf20Sopenharmony_ci &psw1_switch_device, 1328c2ecf20Sopenharmony_ci &psw2_switch_device, 1338c2ecf20Sopenharmony_ci &psw3_switch_device, 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic int __init psw_init(void) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_cidevice_initcall(psw_init); 141