1 // SPDX-License-Identifier: GPL-2.0-only
3 * arch/arm/mach-netx/generic.c
5 * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
8 #include <linux/device.h>
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
14 #include <linux/irqchip/arm-vic.h>
15 #include <linux/reboot.h>
16 #include <mach/hardware.h>
17 #include <asm/mach/map.h>
18 #include <mach/netx-regs.h>
19 #include <asm/mach/irq.h>
21 static struct map_desc netx_io_desc[] __initdata = {
23 .virtual = NETX_IO_VIRT,
24 .pfn = __phys_to_pfn(NETX_IO_PHYS),
25 .length = NETX_IO_SIZE,
30 void __init netx_map_io(void)
32 iotable_init(netx_io_desc, ARRAY_SIZE(netx_io_desc));
35 static struct resource netx_rtc_resources[] = {
39 .flags = IORESOURCE_MEM,
43 static struct platform_device netx_rtc_device = {
46 .num_resources = ARRAY_SIZE(netx_rtc_resources),
47 .resource = netx_rtc_resources,
50 static struct platform_device *devices[] __initdata = {
55 #define DEBUG_IRQ(fmt...) printk(fmt)
57 #define DEBUG_IRQ(fmt...) while (0) {}
60 static void netx_hif_demux_handler(struct irq_desc *desc)
62 unsigned int irq = NETX_IRQ_HIF_CHAINED(0);
65 stat = ((readl(NETX_DPMAS_INT_EN) &
66 readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;
70 DEBUG_IRQ("handling irq %d\n", irq);
71 generic_handle_irq(irq);
79 netx_hif_irq_type(struct irq_data *d, unsigned int type)
81 unsigned int val, irq;
83 val = readl(NETX_DPMAS_IF_CONF1);
85 irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
87 if (type & IRQ_TYPE_EDGE_RISING) {
88 DEBUG_IRQ("rising edges\n");
89 val |= (1 << 26) << irq;
91 if (type & IRQ_TYPE_EDGE_FALLING) {
92 DEBUG_IRQ("falling edges\n");
93 val &= ~((1 << 26) << irq);
95 if (type & IRQ_TYPE_LEVEL_LOW) {
96 DEBUG_IRQ("low level\n");
97 val &= ~((1 << 26) << irq);
99 if (type & IRQ_TYPE_LEVEL_HIGH) {
100 DEBUG_IRQ("high level\n");
101 val |= (1 << 26) << irq;
104 writel(val, NETX_DPMAS_IF_CONF1);
110 netx_hif_ack_irq(struct irq_data *d)
112 unsigned int val, irq;
114 irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
115 writel((1 << 24) << irq, NETX_DPMAS_INT_STAT);
117 val = readl(NETX_DPMAS_INT_EN);
118 val &= ~((1 << 24) << irq);
119 writel(val, NETX_DPMAS_INT_EN);
121 DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
125 netx_hif_mask_irq(struct irq_data *d)
127 unsigned int val, irq;
129 irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
130 val = readl(NETX_DPMAS_INT_EN);
131 val &= ~((1 << 24) << irq);
132 writel(val, NETX_DPMAS_INT_EN);
133 DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
137 netx_hif_unmask_irq(struct irq_data *d)
139 unsigned int val, irq;
141 irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
142 val = readl(NETX_DPMAS_INT_EN);
143 val |= (1 << 24) << irq;
144 writel(val, NETX_DPMAS_INT_EN);
145 DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
148 static struct irq_chip netx_hif_chip = {
149 .irq_ack = netx_hif_ack_irq,
150 .irq_mask = netx_hif_mask_irq,
151 .irq_unmask = netx_hif_unmask_irq,
152 .irq_set_type = netx_hif_irq_type,
155 void __init netx_init_irq(void)
159 vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~0, 0);
161 for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
162 irq_set_chip_and_handler(irq, &netx_hif_chip,
164 irq_clear_status_flags(irq, IRQ_NOREQUEST);
167 writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN);
168 irq_set_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
171 static int __init netx_init(void)
173 return platform_add_devices(devices, ARRAY_SIZE(devices));
176 subsys_initcall(netx_init);
178 void netx_restart(enum reboot_mode mode, const char *cmd)
180 writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,