Linux Audio

Check our new training course

Loading...
v6.13.7
 1// SPDX-License-Identifier: GPL-2.0-only
 2/*
 3 * arch/arm/mach-dove/irq.c
 4 *
 5 * Dove IRQ handling.
 
 
 
 
 6 */
 
 
 7#include <linux/init.h>
 8#include <linux/irq.h>
 
 9#include <linux/io.h>
10#include <asm/exception.h>
11
12#include <plat/irq.h>
13#include <plat/orion-gpio.h>
14
15#include "pm.h"
16#include "bridge-regs.h"
17#include "common.h"
18
19static int __initdata gpio0_irqs[4] = {
20	IRQ_DOVE_GPIO_0_7,
21	IRQ_DOVE_GPIO_8_15,
22	IRQ_DOVE_GPIO_16_23,
23	IRQ_DOVE_GPIO_24_31,
24};
25
26static int __initdata gpio1_irqs[4] = {
27	IRQ_DOVE_HIGH_GPIO,
28	0,
29	0,
30	0,
31};
32
33static int __initdata gpio2_irqs[4] = {
34	0,
35	0,
36	0,
37	0,
38};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
40static void __iomem *dove_irq_base = IRQ_VIRT_BASE;
 
 
 
 
 
41
42static asmlinkage void
43__exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs)
44{
45	u32 stat;
46
47	stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_LOW_OFF);
48	stat &= readl_relaxed(dove_irq_base + IRQ_MASK_LOW_OFF);
49	if (stat) {
50		unsigned int hwirq = 1 + __fls(stat);
51		handle_IRQ(hwirq, regs);
52		return;
53	}
54	stat = readl_relaxed(dove_irq_base + IRQ_CAUSE_HIGH_OFF);
55	stat &= readl_relaxed(dove_irq_base + IRQ_MASK_HIGH_OFF);
56	if (stat) {
57		unsigned int hwirq = 33 + __fls(stat);
58		handle_IRQ(hwirq, regs);
59		return;
60	}
61}
62
63void __init dove_init_irq(void)
64{
65	orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
66	orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
67
68	set_handle_irq(dove_legacy_handle_irq);
 
69
70	/*
71	 * Initialize gpiolib for GPIOs 0-71.
72	 */
73	orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
74			IRQ_DOVE_GPIO_START, gpio0_irqs);
 
 
 
 
75
76	orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
77			IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
 
78
79	orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
80			IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
 
 
 
 
 
 
 
 
 
 
 
 
 
81}
v3.1
 
  1/*
  2 * arch/arm/mach-dove/irq.c
  3 *
  4 * Dove IRQ handling.
  5 *
  6 * This file is licensed under the terms of the GNU General Public
  7 * License version 2.  This program is licensed "as is" without any
  8 * warranty of any kind, whether express or implied.
  9 */
 10
 11#include <linux/kernel.h>
 12#include <linux/init.h>
 13#include <linux/irq.h>
 14#include <linux/gpio.h>
 15#include <linux/io.h>
 16#include <asm/mach/arch.h>
 
 17#include <plat/irq.h>
 18#include <asm/mach/irq.h>
 19#include <mach/pm.h>
 20#include <mach/bridge-regs.h>
 
 21#include "common.h"
 22
 23static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 24{
 25	int irqoff;
 26	BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
 
 
 27
 28	irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
 29		3 + irq - IRQ_DOVE_GPIO_24_31;
 
 
 
 
 30
 31	orion_gpio_irq_handler(irqoff << 3);
 32	if (irq == IRQ_DOVE_HIGH_GPIO) {
 33		orion_gpio_irq_handler(40);
 34		orion_gpio_irq_handler(48);
 35		orion_gpio_irq_handler(56);
 36	}
 37}
 38
 39static void pmu_irq_mask(struct irq_data *d)
 40{
 41	int pin = irq_to_pmu(d->irq);
 42	u32 u;
 43
 44	u = readl(PMU_INTERRUPT_MASK);
 45	u &= ~(1 << (pin & 31));
 46	writel(u, PMU_INTERRUPT_MASK);
 47}
 48
 49static void pmu_irq_unmask(struct irq_data *d)
 50{
 51	int pin = irq_to_pmu(d->irq);
 52	u32 u;
 53
 54	u = readl(PMU_INTERRUPT_MASK);
 55	u |= 1 << (pin & 31);
 56	writel(u, PMU_INTERRUPT_MASK);
 57}
 58
 59static void pmu_irq_ack(struct irq_data *d)
 60{
 61	int pin = irq_to_pmu(d->irq);
 62	u32 u;
 63
 64	u = ~(1 << (pin & 31));
 65	writel(u, PMU_INTERRUPT_CAUSE);
 66}
 67
 68static struct irq_chip pmu_irq_chip = {
 69	.name		= "pmu_irq",
 70	.irq_mask	= pmu_irq_mask,
 71	.irq_unmask	= pmu_irq_unmask,
 72	.irq_ack	= pmu_irq_ack,
 73};
 74
 75static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
 
 76{
 77	unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
 78
 79	cause &= readl(PMU_INTERRUPT_MASK);
 80	if (cause == 0) {
 81		do_bad_IRQ(irq, desc);
 
 
 82		return;
 83	}
 84
 85	for (irq = 0; irq < NR_PMU_IRQS; irq++) {
 86		if (!(cause & (1 << irq)))
 87			continue;
 88		irq = pmu_to_irq(irq);
 89		generic_handle_irq(irq);
 90	}
 91}
 92
 93void __init dove_init_irq(void)
 94{
 95	int i;
 
 96
 97	orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
 98	orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
 99
100	/*
101	 * Initialize gpiolib for GPIOs 0-71.
102	 */
103	orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
104			IRQ_DOVE_GPIO_START);
105	irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
106	irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
107	irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
108	irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
109
110	orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
111			IRQ_DOVE_GPIO_START + 32);
112	irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
113
114	orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
115			IRQ_DOVE_GPIO_START + 64);
116
117	/*
118	 * Mask and clear PMU interrupts
119	 */
120	writel(0, PMU_INTERRUPT_MASK);
121	writel(0, PMU_INTERRUPT_CAUSE);
122
123	for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
124		irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq);
125		irq_set_status_flags(i, IRQ_LEVEL);
126		set_irq_flags(i, IRQF_VALID);
127	}
128	irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
129}