Linux Audio

Check our new training course

Loading...
v3.5.6
 
  1#include <linux/init.h>
  2#include <linux/list.h>
  3#include <linux/io.h>
  4
  5#include <asm/mach/irq.h>
  6#include <asm/hardware/iomd.h>
  7#include <asm/irq.h>
  8#include <asm/fiq.h>
  9
 10static void iomd_ack_irq_a(struct irq_data *d)
 11{
 12	unsigned int val, mask;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 13
 14	mask = 1 << d->irq;
 15	val = iomd_readb(IOMD_IRQMASKA);
 16	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
 17	iomd_writeb(mask, IOMD_IRQCLRA);
 18}
 
 
 
 
 
 
 
 
 
 
 
 
 
 19
 20static void iomd_mask_irq_a(struct irq_data *d)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 21{
 22	unsigned int val, mask;
 
 23
 24	mask = 1 << d->irq;
 25	val = iomd_readb(IOMD_IRQMASKA);
 26	iomd_writeb(val & ~mask, IOMD_IRQMASKA);
 27}
 
 28
 29static void iomd_unmask_irq_a(struct irq_data *d)
 30{
 31	unsigned int val, mask;
 
 
 32
 33	mask = 1 << d->irq;
 34	val = iomd_readb(IOMD_IRQMASKA);
 35	iomd_writeb(val | mask, IOMD_IRQMASKA);
 
 
 
 36}
 37
 38static struct irq_chip iomd_a_chip = {
 39	.irq_ack	= iomd_ack_irq_a,
 40	.irq_mask	= iomd_mask_irq_a,
 41	.irq_unmask	= iomd_unmask_irq_a,
 42};
 43
 44static void iomd_mask_irq_b(struct irq_data *d)
 45{
 46	unsigned int val, mask;
 47
 48	mask = 1 << (d->irq & 7);
 49	val = iomd_readb(IOMD_IRQMASKB);
 50	iomd_writeb(val & ~mask, IOMD_IRQMASKB);
 
 
 51}
 52
 53static void iomd_unmask_irq_b(struct irq_data *d)
 54{
 55	unsigned int val, mask;
 56
 57	mask = 1 << (d->irq & 7);
 58	val = iomd_readb(IOMD_IRQMASKB);
 59	iomd_writeb(val | mask, IOMD_IRQMASKB);
 60}
 61
 62static struct irq_chip iomd_b_chip = {
 63	.irq_ack	= iomd_mask_irq_b,
 64	.irq_mask	= iomd_mask_irq_b,
 65	.irq_unmask	= iomd_unmask_irq_b,
 66};
 67
 68static void iomd_mask_irq_dma(struct irq_data *d)
 69{
 70	unsigned int val, mask;
 71
 72	mask = 1 << (d->irq & 7);
 73	val = iomd_readb(IOMD_DMAMASK);
 74	iomd_writeb(val & ~mask, IOMD_DMAMASK);
 75}
 76
 77static void iomd_unmask_irq_dma(struct irq_data *d)
 78{
 79	unsigned int val, mask;
 
 80
 81	mask = 1 << (d->irq & 7);
 82	val = iomd_readb(IOMD_DMAMASK);
 83	iomd_writeb(val | mask, IOMD_DMAMASK);
 84}
 85
 86static struct irq_chip iomd_dma_chip = {
 87	.irq_ack	= iomd_mask_irq_dma,
 88	.irq_mask	= iomd_mask_irq_dma,
 89	.irq_unmask	= iomd_unmask_irq_dma,
 90};
 91
 92static void iomd_mask_irq_fiq(struct irq_data *d)
 93{
 94	unsigned int val, mask;
 
 95
 96	mask = 1 << (d->irq & 7);
 97	val = iomd_readb(IOMD_FIQMASK);
 98	iomd_writeb(val & ~mask, IOMD_FIQMASK);
 99}
100
101static void iomd_unmask_irq_fiq(struct irq_data *d)
102{
103	unsigned int val, mask;
 
104
105	mask = 1 << (d->irq & 7);
106	val = iomd_readb(IOMD_FIQMASK);
107	iomd_writeb(val | mask, IOMD_FIQMASK);
108}
109
110static struct irq_chip iomd_fiq_chip = {
111	.irq_ack	= iomd_mask_irq_fiq,
112	.irq_mask	= iomd_mask_irq_fiq,
113	.irq_unmask	= iomd_unmask_irq_fiq,
 
 
 
 
 
114};
115
116extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
117
118void __init rpc_init_irq(void)
119{
120	unsigned int irq, flags;
121
122	iomd_writeb(0, IOMD_IRQMASKA);
123	iomd_writeb(0, IOMD_IRQMASKB);
124	iomd_writeb(0, IOMD_FIQMASK);
125	iomd_writeb(0, IOMD_DMAMASK);
126
127	set_fiq_handler(&rpc_default_fiq_start,
128		&rpc_default_fiq_end - &rpc_default_fiq_start);
129
 
 
130	for (irq = 0; irq < NR_IRQS; irq++) {
131		flags = IRQF_VALID;
 
132
133		if (irq <= 6 || (irq >= 9 && irq <= 15))
134			flags |= IRQF_PROBE;
135
136		if (irq == 21 || (irq >= 16 && irq <= 19) ||
137		    irq == IRQ_KEYBOARDTX)
138			flags |= IRQF_NOAUTOEN;
139
140		switch (irq) {
141		case 0 ... 7:
142			irq_set_chip_and_handler(irq, &iomd_a_chip,
143						 handle_level_irq);
144			set_irq_flags(irq, flags);
 
 
145			break;
146
147		case 8 ... 15:
148			irq_set_chip_and_handler(irq, &iomd_b_chip,
149						 handle_level_irq);
150			set_irq_flags(irq, flags);
 
 
151			break;
152
153		case 16 ... 21:
154			irq_set_chip_and_handler(irq, &iomd_dma_chip,
155						 handle_level_irq);
156			set_irq_flags(irq, flags);
 
 
157			break;
158
159		case 64 ... 71:
160			irq_set_chip(irq, &iomd_fiq_chip);
161			set_irq_flags(irq, IRQF_VALID);
 
 
162			break;
163		}
164	}
165
166	init_FIQ();
167}
168
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/init.h>
  3#include <linux/list.h>
  4#include <linux/io.h>
  5
  6#include <asm/mach/irq.h>
  7#include <asm/hardware/iomd.h>
  8#include <asm/irq.h>
  9#include <asm/fiq.h>
 10
 11// These are offsets from the stat register for each IRQ bank
 12#define STAT	0x00
 13#define REQ	0x04
 14#define CLR	0x04
 15#define MASK	0x08
 16
 17static const u8 irq_prio_h[256] = {
 18	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
 19	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
 20	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 21	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 22	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
 23	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
 24	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 25	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 26	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 27	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 28	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 29	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 30	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 31	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
 32	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 33	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
 34};
 35
 36static const u8 irq_prio_d[256] = {
 37	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 38	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 39	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 40	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 41	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 42	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 43	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 44	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 45	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 46	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 47	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 48	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 49	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 50	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 51	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 52	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
 53};
 54
 55static const u8 irq_prio_l[256] = {
 56	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 57	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 58	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 59	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 60	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
 61	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
 62	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 63	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 64	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 65	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 66	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 67	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 68	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 69	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 70	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 71	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 72};
 73
 74static int iomd_get_irq_nr(void)
 75{
 76	int irq;
 77	u8 reg;
 78
 79	/* get highest priority first */
 80	reg = readb(IOC_BASE + IOMD_IRQREQB);
 81	irq = irq_prio_h[reg];
 82	if (irq)
 83		return irq;
 84
 85	/* get DMA  */
 86	reg = readb(IOC_BASE + IOMD_DMAREQ);
 87	irq = irq_prio_d[reg];
 88	if (irq)
 89		return irq;
 90
 91	/* get low priority */
 92	reg = readb(IOC_BASE + IOMD_IRQREQA);
 93	irq = irq_prio_l[reg];
 94	if (irq)
 95		return irq;
 96	return 0;
 97}
 98
 99static void iomd_handle_irq(struct pt_regs *regs)
 
 
 
 
 
 
100{
101	int irq;
102
103	do {
104		irq = iomd_get_irq_nr();
105		if (irq)
106			generic_handle_irq(irq);
107	} while (irq);
108}
109
110static void __iomem *iomd_get_base(struct irq_data *d)
111{
112	void *cd = irq_data_get_irq_chip_data(d);
113
114	return (void __iomem *)(unsigned long)cd;
 
 
115}
116
117static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask)
 
 
 
 
 
 
118{
119	struct irq_data *d = irq_get_irq_data(irq);
120
121	d->mask = mask;
122	irq_set_chip_data(irq, (void *)(unsigned long)base);
 
123}
124
125static void iomd_irq_mask_ack(struct irq_data *d)
126{
127	void __iomem *base = iomd_get_base(d);
128	unsigned int val, mask = d->mask;
129
130	val = readb(base + MASK);
131	writeb(val & ~mask, base + MASK);
132	writeb(mask, base + CLR);
133}
134
135static void iomd_irq_mask(struct irq_data *d)
 
 
 
 
 
 
136{
137	void __iomem *base = iomd_get_base(d);
138	unsigned int val, mask = d->mask;
139
140	val = readb(base + MASK);
141	writeb(val & ~mask, base + MASK);
 
142}
143
144static void iomd_irq_unmask(struct irq_data *d)
145{
146	void __iomem *base = iomd_get_base(d);
147	unsigned int val, mask = d->mask;
148
149	val = readb(base + MASK);
150	writeb(val | mask, base + MASK);
 
151}
152
153static struct irq_chip iomd_chip_clr = {
154	.irq_mask_ack	= iomd_irq_mask_ack,
155	.irq_mask	= iomd_irq_mask,
156	.irq_unmask	= iomd_irq_unmask,
157};
158
159static struct irq_chip iomd_chip_noclr = {
160	.irq_mask	= iomd_irq_mask,
161	.irq_unmask	= iomd_irq_unmask,
162};
163
164extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
165
166void __init rpc_init_irq(void)
167{
168	unsigned int irq, clr, set;
169
170	iomd_writeb(0, IOMD_IRQMASKA);
171	iomd_writeb(0, IOMD_IRQMASKB);
172	iomd_writeb(0, IOMD_FIQMASK);
173	iomd_writeb(0, IOMD_DMAMASK);
174
175	set_fiq_handler(&rpc_default_fiq_start,
176		&rpc_default_fiq_end - &rpc_default_fiq_start);
177
178	set_handle_irq(iomd_handle_irq);
179
180	for (irq = 0; irq < NR_IRQS; irq++) {
181		clr = IRQ_NOREQUEST;
182		set = 0;
183
184		if (irq <= 6 || (irq >= 9 && irq <= 15))
185			clr |= IRQ_NOPROBE;
186
187		if (irq == 21 || (irq >= 16 && irq <= 19) ||
188		    irq == IRQ_KEYBOARDTX)
189			set |= IRQ_NOAUTOEN;
190
191		switch (irq) {
192		case 0 ... 7:
193			irq_set_chip_and_handler(irq, &iomd_chip_clr,
194						 handle_level_irq);
195			irq_modify_status(irq, clr, set);
196			iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA,
197					   BIT(irq));
198			break;
199
200		case 8 ... 15:
201			irq_set_chip_and_handler(irq, &iomd_chip_noclr,
202						 handle_level_irq);
203			irq_modify_status(irq, clr, set);
204			iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB,
205					   BIT(irq - 8));
206			break;
207
208		case 16 ... 21:
209			irq_set_chip_and_handler(irq, &iomd_chip_noclr,
210						 handle_level_irq);
211			irq_modify_status(irq, clr, set);
212			iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT,
213					   BIT(irq - 16));
214			break;
215
216		case 64 ... 71:
217			irq_set_chip(irq, &iomd_chip_noclr);
218			irq_modify_status(irq, clr, set);
219			iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT,
220					   BIT(irq - 64));
221			break;
222		}
223	}
224
225	init_FIQ(FIQ_START);
226}