162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/sh/boards/landisk/psw.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * push switch support for LANDISK and USL-5P
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2006-2007  Paul Mundt
862306a36Sopenharmony_ci * Copyright (C) 2007  kogiidena
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#include <linux/io.h>
1162306a36Sopenharmony_ci#include <linux/init.h>
1262306a36Sopenharmony_ci#include <linux/interrupt.h>
1362306a36Sopenharmony_ci#include <linux/platform_device.h>
1462306a36Sopenharmony_ci#include <mach-landisk/mach/iodata_landisk.h>
1562306a36Sopenharmony_ci#include <asm/push-switch.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic irqreturn_t psw_irq_handler(int irq, void *arg)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	struct platform_device *pdev = arg;
2062306a36Sopenharmony_ci	struct push_switch *psw = platform_get_drvdata(pdev);
2162306a36Sopenharmony_ci	struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
2262306a36Sopenharmony_ci	unsigned int sw_value;
2362306a36Sopenharmony_ci	int ret = 0;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	sw_value = (0x0ff & (~__raw_readb(PA_STATUS)));
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* Nothing to do if there's no state change */
2862306a36Sopenharmony_ci	if (psw->state) {
2962306a36Sopenharmony_ci		ret = 1;
3062306a36Sopenharmony_ci		goto out;
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	/* Figure out who raised it */
3462306a36Sopenharmony_ci	if (sw_value & (1 << psw_info->bit)) {
3562306a36Sopenharmony_ci		psw->state = 1;
3662306a36Sopenharmony_ci		mod_timer(&psw->debounce, jiffies + 50);
3762306a36Sopenharmony_ci		ret = 1;
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciout:
4162306a36Sopenharmony_ci	/* Clear the switch IRQs */
4262306a36Sopenharmony_ci	__raw_writeb(0x00, PA_PWRINT_CLR);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	return IRQ_RETVAL(ret);
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic struct resource psw_power_resources[] = {
4862306a36Sopenharmony_ci	[0] = {
4962306a36Sopenharmony_ci		.start = IRQ_POWER,
5062306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
5162306a36Sopenharmony_ci       },
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic struct resource psw_usl5p_resources[] = {
5562306a36Sopenharmony_ci	[0] = {
5662306a36Sopenharmony_ci		.start = IRQ_BUTTON,
5762306a36Sopenharmony_ci		.flags = IORESOURCE_IRQ,
5862306a36Sopenharmony_ci	},
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic struct push_switch_platform_info psw_power_platform_data = {
6262306a36Sopenharmony_ci	.name		= "psw_power",
6362306a36Sopenharmony_ci	.bit		= 4,
6462306a36Sopenharmony_ci	.irq_flags	= IRQF_SHARED,
6562306a36Sopenharmony_ci	.irq_handler	= psw_irq_handler,
6662306a36Sopenharmony_ci};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic struct push_switch_platform_info psw1_platform_data = {
6962306a36Sopenharmony_ci	.name		= "psw1",
7062306a36Sopenharmony_ci	.bit		= 0,
7162306a36Sopenharmony_ci	.irq_flags	= IRQF_SHARED,
7262306a36Sopenharmony_ci	.irq_handler	= psw_irq_handler,
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic struct push_switch_platform_info psw2_platform_data = {
7662306a36Sopenharmony_ci	.name		= "psw2",
7762306a36Sopenharmony_ci	.bit		= 2,
7862306a36Sopenharmony_ci	.irq_flags	= IRQF_SHARED,
7962306a36Sopenharmony_ci	.irq_handler	= psw_irq_handler,
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic struct push_switch_platform_info psw3_platform_data = {
8362306a36Sopenharmony_ci	.name		= "psw3",
8462306a36Sopenharmony_ci	.bit		= 1,
8562306a36Sopenharmony_ci	.irq_flags	= IRQF_SHARED,
8662306a36Sopenharmony_ci	.irq_handler	= psw_irq_handler,
8762306a36Sopenharmony_ci};
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic struct platform_device psw_power_switch_device = {
9062306a36Sopenharmony_ci	.name		= "push-switch",
9162306a36Sopenharmony_ci	.id		= 0,
9262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(psw_power_resources),
9362306a36Sopenharmony_ci	.resource	= psw_power_resources,
9462306a36Sopenharmony_ci	.dev		= {
9562306a36Sopenharmony_ci		.platform_data = &psw_power_platform_data,
9662306a36Sopenharmony_ci	},
9762306a36Sopenharmony_ci};
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_cistatic struct platform_device psw1_switch_device = {
10062306a36Sopenharmony_ci	.name		= "push-switch",
10162306a36Sopenharmony_ci	.id		= 1,
10262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
10362306a36Sopenharmony_ci	.resource	= psw_usl5p_resources,
10462306a36Sopenharmony_ci	.dev		= {
10562306a36Sopenharmony_ci		.platform_data = &psw1_platform_data,
10662306a36Sopenharmony_ci	},
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistatic struct platform_device psw2_switch_device = {
11062306a36Sopenharmony_ci	.name		= "push-switch",
11162306a36Sopenharmony_ci	.id		= 2,
11262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
11362306a36Sopenharmony_ci	.resource	= psw_usl5p_resources,
11462306a36Sopenharmony_ci	.dev		= {
11562306a36Sopenharmony_ci		.platform_data = &psw2_platform_data,
11662306a36Sopenharmony_ci	},
11762306a36Sopenharmony_ci};
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistatic struct platform_device psw3_switch_device = {
12062306a36Sopenharmony_ci	.name		= "push-switch",
12162306a36Sopenharmony_ci	.id		= 3,
12262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(psw_usl5p_resources),
12362306a36Sopenharmony_ci	.resource	= psw_usl5p_resources,
12462306a36Sopenharmony_ci	.dev = {
12562306a36Sopenharmony_ci		.platform_data = &psw3_platform_data,
12662306a36Sopenharmony_ci	},
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic struct platform_device *psw_devices[] = {
13062306a36Sopenharmony_ci	&psw_power_switch_device,
13162306a36Sopenharmony_ci	&psw1_switch_device,
13262306a36Sopenharmony_ci	&psw2_switch_device,
13362306a36Sopenharmony_ci	&psw3_switch_device,
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic int __init psw_init(void)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
13962306a36Sopenharmony_ci}
14062306a36Sopenharmony_cidevice_initcall(psw_init);
141