1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * arch/arm/mach-ks8695/irq.c
5 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
6 * Copyright (C) 2006 Simtec Electronics
9 #include <linux/init.h>
10 #include <linux/module.h>
11 #include <linux/interrupt.h>
12 #include <linux/ioport.h>
13 #include <linux/device.h>
16 #include <mach/hardware.h>
19 #include <asm/mach/irq.h>
21 #include <mach/regs-irq.h>
22 #include <mach/regs-gpio.h>
24 static void ks8695_irq_mask(struct irq_data *d)
28 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
29 inten &= ~(1 << d->irq);
31 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
34 static void ks8695_irq_unmask(struct irq_data *d)
38 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
39 inten |= (1 << d->irq);
41 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
44 static void ks8695_irq_ack(struct irq_data *d)
46 __raw_writel((1 << d->irq), KS8695_IRQ_VA + KS8695_INTST);
50 static struct irq_chip ks8695_irq_level_chip;
51 static struct irq_chip ks8695_irq_edge_chip;
54 static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
56 unsigned long ctrl, mode;
57 unsigned short level_triggered = 0;
59 ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
62 case IRQ_TYPE_LEVEL_HIGH:
66 case IRQ_TYPE_LEVEL_LOW:
70 case IRQ_TYPE_EDGE_RISING:
71 mode = IOPC_TM_RISING;
73 case IRQ_TYPE_EDGE_FALLING:
74 mode = IOPC_TM_FALLING;
76 case IRQ_TYPE_EDGE_BOTH:
84 case KS8695_IRQ_EXTERN0:
85 ctrl &= ~IOPC_IOEINT0TM;
86 ctrl |= IOPC_IOEINT0_MODE(mode);
88 case KS8695_IRQ_EXTERN1:
89 ctrl &= ~IOPC_IOEINT1TM;
90 ctrl |= IOPC_IOEINT1_MODE(mode);
92 case KS8695_IRQ_EXTERN2:
93 ctrl &= ~IOPC_IOEINT2TM;
94 ctrl |= IOPC_IOEINT2_MODE(mode);
96 case KS8695_IRQ_EXTERN3:
97 ctrl &= ~IOPC_IOEINT3TM;
98 ctrl |= IOPC_IOEINT3_MODE(mode);
104 if (level_triggered) {
105 irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
109 irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
113 __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
117 static struct irq_chip ks8695_irq_level_chip = {
118 .irq_ack = ks8695_irq_mask,
119 .irq_mask = ks8695_irq_mask,
120 .irq_unmask = ks8695_irq_unmask,
121 .irq_set_type = ks8695_irq_set_type,
124 static struct irq_chip ks8695_irq_edge_chip = {
125 .irq_ack = ks8695_irq_ack,
126 .irq_mask = ks8695_irq_mask,
127 .irq_unmask = ks8695_irq_unmask,
128 .irq_set_type = ks8695_irq_set_type,
131 void __init ks8695_init_irq(void)
135 /* Disable all interrupts initially */
136 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
137 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);
139 for (irq = 0; irq < NR_IRQS; irq++) {
141 /* Level-triggered interrupts */
142 case KS8695_IRQ_BUS_ERROR:
143 case KS8695_IRQ_UART_MODEM_STATUS:
144 case KS8695_IRQ_UART_LINE_STATUS:
145 case KS8695_IRQ_UART_RX:
146 case KS8695_IRQ_COMM_TX:
147 case KS8695_IRQ_COMM_RX:
148 irq_set_chip_and_handler(irq,
149 &ks8695_irq_level_chip,
153 /* Edge-triggered interrupts */
155 /* clear pending bit */
156 ks8695_irq_ack(irq_get_irq_data(irq));
157 irq_set_chip_and_handler(irq,
158 &ks8695_irq_edge_chip,
162 irq_clear_status_flags(irq, IRQ_NOREQUEST);