]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - arch/arm/mach-ks8695/irq.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156
[mirror_ubuntu-hirsute-kernel.git] / arch / arm / mach-ks8695 / irq.c
CommitLineData
1a59d1b8 1// SPDX-License-Identifier: GPL-2.0-or-later
c53c9cf6
AV
2/*
3 * arch/arm/mach-ks8695/irq.c
4 *
5 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
6 * Copyright (C) 2006 Simtec Electronics
c53c9cf6
AV
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/interrupt.h>
12#include <linux/ioport.h>
edbaa603 13#include <linux/device.h>
fced80c7 14#include <linux/io.h>
c53c9cf6 15
a09e64fb 16#include <mach/hardware.h>
c53c9cf6 17#include <asm/irq.h>
c53c9cf6
AV
18
19#include <asm/mach/irq.h>
20
a09e64fb
RK
21#include <mach/regs-irq.h>
22#include <mach/regs-gpio.h>
c53c9cf6 23
3cdb791b 24static void ks8695_irq_mask(struct irq_data *d)
c53c9cf6
AV
25{
26 unsigned long inten;
27
28 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
3cdb791b 29 inten &= ~(1 << d->irq);
c53c9cf6
AV
30
31 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
32}
33
3cdb791b 34static void ks8695_irq_unmask(struct irq_data *d)
c53c9cf6
AV
35{
36 unsigned long inten;
37
38 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
3cdb791b 39 inten |= (1 << d->irq);
c53c9cf6
AV
40
41 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
42}
43
3cdb791b 44static void ks8695_irq_ack(struct irq_data *d)
c53c9cf6 45{
3cdb791b 46 __raw_writel((1 << d->irq), KS8695_IRQ_VA + KS8695_INTST);
c53c9cf6
AV
47}
48
49
50static struct irq_chip ks8695_irq_level_chip;
51static struct irq_chip ks8695_irq_edge_chip;
52
53
3cdb791b 54static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
c53c9cf6
AV
55{
56 unsigned long ctrl, mode;
57 unsigned short level_triggered = 0;
58
59 ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
60
61 switch (type) {
6cab4860 62 case IRQ_TYPE_LEVEL_HIGH:
c53c9cf6
AV
63 mode = IOPC_TM_HIGH;
64 level_triggered = 1;
65 break;
6cab4860 66 case IRQ_TYPE_LEVEL_LOW:
c53c9cf6
AV
67 mode = IOPC_TM_LOW;
68 level_triggered = 1;
69 break;
6cab4860 70 case IRQ_TYPE_EDGE_RISING:
c53c9cf6
AV
71 mode = IOPC_TM_RISING;
72 break;
6cab4860 73 case IRQ_TYPE_EDGE_FALLING:
c53c9cf6
AV
74 mode = IOPC_TM_FALLING;
75 break;
6cab4860 76 case IRQ_TYPE_EDGE_BOTH:
c53c9cf6
AV
77 mode = IOPC_TM_EDGE;
78 break;
79 default:
80 return -EINVAL;
81 }
82
3cdb791b 83 switch (d->irq) {
c53c9cf6
AV
84 case KS8695_IRQ_EXTERN0:
85 ctrl &= ~IOPC_IOEINT0TM;
86 ctrl |= IOPC_IOEINT0_MODE(mode);
87 break;
88 case KS8695_IRQ_EXTERN1:
89 ctrl &= ~IOPC_IOEINT1TM;
90 ctrl |= IOPC_IOEINT1_MODE(mode);
91 break;
92 case KS8695_IRQ_EXTERN2:
93 ctrl &= ~IOPC_IOEINT2TM;
94 ctrl |= IOPC_IOEINT2_MODE(mode);
95 break;
96 case KS8695_IRQ_EXTERN3:
97 ctrl &= ~IOPC_IOEINT3TM;
98 ctrl |= IOPC_IOEINT3_MODE(mode);
99 break;
100 default:
101 return -EINVAL;
102 }
103
104 if (level_triggered) {
f38c02f3
TG
105 irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
106 handle_level_irq);
c53c9cf6
AV
107 }
108 else {
f38c02f3
TG
109 irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
110 handle_edge_irq);
c53c9cf6
AV
111 }
112
113 __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
114 return 0;
115}
116
117static struct irq_chip ks8695_irq_level_chip = {
3cdb791b
LB
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,
c53c9cf6
AV
122};
123
124static struct irq_chip ks8695_irq_edge_chip = {
3cdb791b
LB
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,
c53c9cf6
AV
129};
130
131void __init ks8695_init_irq(void)
132{
133 unsigned int irq;
134
135 /* Disable all interrupts initially */
136 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
137 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);
138
139 for (irq = 0; irq < NR_IRQS; irq++) {
140 switch (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:
f38c02f3
TG
148 irq_set_chip_and_handler(irq,
149 &ks8695_irq_level_chip,
150 handle_level_irq);
c53c9cf6
AV
151 break;
152
153 /* Edge-triggered interrupts */
154 default:
3cdb791b
LB
155 /* clear pending bit */
156 ks8695_irq_ack(irq_get_irq_data(irq));
f38c02f3
TG
157 irq_set_chip_and_handler(irq,
158 &ks8695_irq_edge_chip,
159 handle_edge_irq);
c53c9cf6
AV
160 }
161
e8d36d5d 162 irq_clear_status_flags(irq, IRQ_NOREQUEST);
c53c9cf6
AV
163 }
164}