PageRenderTime 19ms CodeModel.GetById 14ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/sh/boards/mach-se/7722/irq.c

https://bitbucket.org/ndreys/linux-sunxi
C | 83 lines | 54 code | 15 blank | 14 comment | 4 complexity | 04bc7cf381510938497d722036bd47a4 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
 1/*
 2 * linux/arch/sh/boards/se/7722/irq.c
 3 *
 4 * Copyright (C) 2007  Nobuhiro Iwamatsu
 5 *
 6 * Hitachi UL SolutionEngine 7722 Support.
 7 *
 8 * This file is subject to the terms and conditions of the GNU General Public
 9 * License.  See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15#include <asm/irq.h>
16#include <asm/io.h>
17#include <mach-se/mach/se7722.h>
18
19unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, };
20
21static void disable_se7722_irq(struct irq_data *data)
22{
23	unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
24	__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK);
25}
26
27static void enable_se7722_irq(struct irq_data *data)
28{
29	unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data);
30	__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK);
31}
32
33static struct irq_chip se7722_irq_chip __read_mostly = {
34	.name		= "SE7722-FPGA",
35	.irq_mask	= disable_se7722_irq,
36	.irq_unmask	= enable_se7722_irq,
37};
38
39static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc)
40{
41	unsigned short intv = __raw_readw(IRQ01_STS);
42	unsigned int ext_irq = 0;
43
44	intv &= (1 << SE7722_FPGA_IRQ_NR) - 1;
45
46	for (; intv; intv >>= 1, ext_irq++) {
47		if (!(intv & 1))
48			continue;
49
50		generic_handle_irq(se7722_fpga_irq[ext_irq]);
51	}
52}
53
54/*
55 * Initialize IRQ setting
56 */
57void __init init_se7722_IRQ(void)
58{
59	int i, irq;
60
61	__raw_writew(0, IRQ01_MASK);       /* disable all irqs */
62	__raw_writew(0x2000, 0xb03fffec);  /* mrshpc irq enable */
63
64	for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
65		irq = create_irq();
66		if (irq < 0)
67			return;
68		se7722_fpga_irq[i] = irq;
69
70		irq_set_chip_and_handler_name(se7722_fpga_irq[i],
71					      &se7722_irq_chip,
72					      handle_level_irq,
73					      "level");
74
75		irq_set_chip_data(se7722_fpga_irq[i], (void *)i);
76	}
77
78	irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux);
79	irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
80
81	irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux);
82	irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
83}