Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-drm-fsl-dcu.git] / arch / sh / boards / se / 7722 / irq.c
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 <asm/se7722.h>
18
19 #define INTC_INTMSK0             0xFFD00044
20 #define INTC_INTMSKCLR0          0xFFD00064
21
22 static void disable_se7722_irq(unsigned int irq)
23 {
24         struct ipr_data *p = get_irq_chip_data(irq);
25         ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
26 }
27
28 static void enable_se7722_irq(unsigned int irq)
29 {
30         struct ipr_data *p = get_irq_chip_data(irq);
31         ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
32 }
33
34 static struct irq_chip se7722_irq_chip __read_mostly = {
35         .name           = "SE7722",
36         .mask           = disable_se7722_irq,
37         .unmask         = enable_se7722_irq,
38         .mask_ack       = disable_se7722_irq,
39 };
40
41 static struct ipr_data ipr_irq_table[] = {
42         /* irq        ,idx,sft, priority     , addr   */
43         { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
44         { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
45         { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
46         { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
47         { SMC_IRQ     , 0 , 0 , SMC_BIT     , IRQ01_MASK } ,
48         { EXT_IRQ     , 0 , 0 , EXT_BIT     , IRQ01_MASK } ,
49 };
50
51 int se7722_irq_demux(int irq)
52 {
53
54         if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) {
55                 volatile unsigned short intv =
56                         *(volatile unsigned short *)IRQ01_STS;
57                 if (irq == IRQ0_IRQ){
58                         if(intv & SMC_BIT ) {
59                                 return SMC_IRQ;
60                         } else if(intv & USB_BIT) {
61                                 return USB_IRQ;
62                         } else {
63                                 printk("intv =%04x\n", intv);
64                                 return SMC_IRQ;
65                         }
66                 } else if(irq == IRQ1_IRQ){
67                         if(intv & MRSHPC_BIT0) {
68                                 return MRSHPC_IRQ0;
69                         } else if(intv & MRSHPC_BIT1) {
70                                 return MRSHPC_IRQ1;
71                         } else if(intv & MRSHPC_BIT2) {
72                                 return MRSHPC_IRQ2;
73                         } else if(intv & MRSHPC_BIT3) {
74                                 return MRSHPC_IRQ3;
75                         } else {
76                                 printk("BIT_EXTENTION =%04x\n", intv);
77                                 return EXT_IRQ;
78                         }
79                 }
80         }
81         return irq;
82
83 }
84 /*
85  * Initialize IRQ setting
86  */
87 void __init init_se7722_IRQ(void)
88 {
89         int i = 0;
90         ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
91         ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0);     /* irq0 pri=3,irq1,pri=3 */
92         ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1);        /* irq0,1 low-level irq */
93
94         for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) {
95                 disable_irq_nosync(ipr_irq_table[i].irq);
96                 set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip,
97                         handle_level_irq, "level");
98                 set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] );
99                 disable_se7722_irq(ipr_irq_table[i].irq);
100         }
101 }