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