1da2014a2SPaul Mundt /* 2da2014a2SPaul Mundt * linux/arch/sh/boards/se/7206/irq.c 3da2014a2SPaul Mundt * 4da2014a2SPaul Mundt * Copyright (C) 2005,2006 Yoshinori Sato 5da2014a2SPaul Mundt * 6da2014a2SPaul Mundt * Hitachi SolutionEngine Support. 7da2014a2SPaul Mundt * 8da2014a2SPaul Mundt */ 9da2014a2SPaul Mundt #include <linux/init.h> 10da2014a2SPaul Mundt #include <linux/irq.h> 11da2014a2SPaul Mundt #include <linux/io.h> 12da2014a2SPaul Mundt #include <linux/interrupt.h> 13da2014a2SPaul Mundt #include <asm/se7206.h> 14da2014a2SPaul Mundt 15da2014a2SPaul Mundt #define INTSTS0 0x31800000 16da2014a2SPaul Mundt #define INTSTS1 0x31800002 17da2014a2SPaul Mundt #define INTMSK0 0x31800004 18da2014a2SPaul Mundt #define INTMSK1 0x31800006 19da2014a2SPaul Mundt #define INTSEL 0x31800008 20da2014a2SPaul Mundt 21da2014a2SPaul Mundt #define IRQ0_IRQ 64 22da2014a2SPaul Mundt #define IRQ1_IRQ 65 23da2014a2SPaul Mundt #define IRQ3_IRQ 67 24da2014a2SPaul Mundt 25da2014a2SPaul Mundt #define INTC_IPR01 0xfffe0818 26da2014a2SPaul Mundt #define INTC_ICR1 0xfffe0802 27da2014a2SPaul Mundt 28da2014a2SPaul Mundt static void disable_se7206_irq(unsigned int irq) 29da2014a2SPaul Mundt { 30da2014a2SPaul Mundt unsigned short val; 31da2014a2SPaul Mundt unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq))); 32da2014a2SPaul Mundt unsigned short msk0,msk1; 33da2014a2SPaul Mundt 34da2014a2SPaul Mundt /* Set the priority in IPR to 0 */ 35da2014a2SPaul Mundt val = ctrl_inw(INTC_IPR01); 36da2014a2SPaul Mundt val &= mask; 37da2014a2SPaul Mundt ctrl_outw(val, INTC_IPR01); 38da2014a2SPaul Mundt /* FPGA mask set */ 39da2014a2SPaul Mundt msk0 = ctrl_inw(INTMSK0); 40da2014a2SPaul Mundt msk1 = ctrl_inw(INTMSK1); 41da2014a2SPaul Mundt 42da2014a2SPaul Mundt switch (irq) { 43da2014a2SPaul Mundt case IRQ0_IRQ: 44da2014a2SPaul Mundt msk0 |= 0x0010; 45da2014a2SPaul Mundt break; 46da2014a2SPaul Mundt case IRQ1_IRQ: 47da2014a2SPaul Mundt msk0 |= 0x000f; 48da2014a2SPaul Mundt break; 49da2014a2SPaul Mundt case IRQ3_IRQ: 50da2014a2SPaul Mundt msk0 |= 0x0f00; 51da2014a2SPaul Mundt msk1 |= 0x00ff; 52da2014a2SPaul Mundt break; 53da2014a2SPaul Mundt } 54da2014a2SPaul Mundt ctrl_outw(msk0, INTMSK0); 55da2014a2SPaul Mundt ctrl_outw(msk1, INTMSK1); 56da2014a2SPaul Mundt } 57da2014a2SPaul Mundt 58da2014a2SPaul Mundt static void enable_se7206_irq(unsigned int irq) 59da2014a2SPaul Mundt { 60da2014a2SPaul Mundt unsigned short val; 61da2014a2SPaul Mundt unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq))); 62da2014a2SPaul Mundt unsigned short msk0,msk1; 63da2014a2SPaul Mundt 64da2014a2SPaul Mundt /* Set priority in IPR back to original value */ 65da2014a2SPaul Mundt val = ctrl_inw(INTC_IPR01); 66da2014a2SPaul Mundt val |= value; 67da2014a2SPaul Mundt ctrl_outw(val, INTC_IPR01); 68da2014a2SPaul Mundt 69da2014a2SPaul Mundt /* FPGA mask reset */ 70da2014a2SPaul Mundt msk0 = ctrl_inw(INTMSK0); 71da2014a2SPaul Mundt msk1 = ctrl_inw(INTMSK1); 72da2014a2SPaul Mundt 73da2014a2SPaul Mundt switch (irq) { 74da2014a2SPaul Mundt case IRQ0_IRQ: 75da2014a2SPaul Mundt msk0 &= ~0x0010; 76da2014a2SPaul Mundt break; 77da2014a2SPaul Mundt case IRQ1_IRQ: 78da2014a2SPaul Mundt msk0 &= ~0x000f; 79da2014a2SPaul Mundt break; 80da2014a2SPaul Mundt case IRQ3_IRQ: 81da2014a2SPaul Mundt msk0 &= ~0x0f00; 82da2014a2SPaul Mundt msk1 &= ~0x00ff; 83da2014a2SPaul Mundt break; 84da2014a2SPaul Mundt } 85da2014a2SPaul Mundt ctrl_outw(msk0, INTMSK0); 86da2014a2SPaul Mundt ctrl_outw(msk1, INTMSK1); 87da2014a2SPaul Mundt } 88da2014a2SPaul Mundt 89da2014a2SPaul Mundt static void eoi_se7206_irq(unsigned int irq) 90da2014a2SPaul Mundt { 91da2014a2SPaul Mundt unsigned short sts0,sts1; 92da2014a2SPaul Mundt 93da2014a2SPaul Mundt if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 94da2014a2SPaul Mundt enable_se7206_irq(irq); 95da2014a2SPaul Mundt /* FPGA isr clear */ 96da2014a2SPaul Mundt sts0 = ctrl_inw(INTSTS0); 97da2014a2SPaul Mundt sts1 = ctrl_inw(INTSTS1); 98da2014a2SPaul Mundt 99da2014a2SPaul Mundt switch (irq) { 100da2014a2SPaul Mundt case IRQ0_IRQ: 101da2014a2SPaul Mundt sts0 &= ~0x0010; 102da2014a2SPaul Mundt break; 103da2014a2SPaul Mundt case IRQ1_IRQ: 104da2014a2SPaul Mundt sts0 &= ~0x000f; 105da2014a2SPaul Mundt break; 106da2014a2SPaul Mundt case IRQ3_IRQ: 107da2014a2SPaul Mundt sts0 &= ~0x0f00; 108da2014a2SPaul Mundt sts1 &= ~0x00ff; 109da2014a2SPaul Mundt break; 110da2014a2SPaul Mundt } 111da2014a2SPaul Mundt ctrl_outw(sts0, INTSTS0); 112da2014a2SPaul Mundt ctrl_outw(sts1, INTSTS1); 113da2014a2SPaul Mundt } 114da2014a2SPaul Mundt 115da2014a2SPaul Mundt static struct irq_chip se7206_irq_chip __read_mostly = { 116da2014a2SPaul Mundt .name = "SE7206-FPGA", 117da2014a2SPaul Mundt .mask = disable_se7206_irq, 118da2014a2SPaul Mundt .unmask = enable_se7206_irq, 119da2014a2SPaul Mundt .mask_ack = disable_se7206_irq, 120da2014a2SPaul Mundt .eoi = eoi_se7206_irq, 121da2014a2SPaul Mundt }; 122da2014a2SPaul Mundt 123da2014a2SPaul Mundt static void make_se7206_irq(unsigned int irq) 124da2014a2SPaul Mundt { 125da2014a2SPaul Mundt disable_irq_nosync(irq); 126da2014a2SPaul Mundt set_irq_chip_and_handler_name(irq, &se7206_irq_chip, 127da2014a2SPaul Mundt handle_level_irq, "level"); 128da2014a2SPaul Mundt disable_se7206_irq(irq); 129da2014a2SPaul Mundt } 130da2014a2SPaul Mundt 131da2014a2SPaul Mundt /* 132da2014a2SPaul Mundt * Initialize IRQ setting 133da2014a2SPaul Mundt */ 134da2014a2SPaul Mundt void __init init_se7206_IRQ(void) 135da2014a2SPaul Mundt { 136da2014a2SPaul Mundt make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ 137da2014a2SPaul Mundt make_se7206_irq(IRQ1_IRQ); /* ATA */ 138da2014a2SPaul Mundt make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ 139da2014a2SPaul Mundt ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ 140da2014a2SPaul Mundt 141da2014a2SPaul Mundt /* FPGA System register setup*/ 142da2014a2SPaul Mundt ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */ 143da2014a2SPaul Mundt ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */ 144da2014a2SPaul Mundt /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ 145da2014a2SPaul Mundt ctrl_outw(0x0001,INTSEL); 146da2014a2SPaul Mundt } 147