sh: Convert IPR-IRQ to IRQ chip.

One more initial conversion..

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+28 -76
+28 -76
arch/sh/kernel/cpu/irq/ipr.c
··· 1 1 /* 2 - * arch/sh/kernel/cpu/irq/ipr.c 2 + * Interrupt handling for IPR-based IRQ. 3 3 * 4 4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi 5 5 * Copyright (C) 2000 Kazumoto Kojima 6 - * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> 7 - * 8 - * Interrupt handling for IPR-based IRQ. 6 + * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> 7 + * Copyright (C) 2006 Paul Mundt 9 8 * 10 9 * Supported system: 11 10 * On-chip supporting modules (TMU, RTC, etc.). ··· 12 13 * Hitachi SolutionEngine external I/O: 13 14 * MS7709SE01, MS7709ASE01, and MS7750SE01 14 15 * 16 + * This file is subject to the terms and conditions of the GNU General Public 17 + * License. See the file "COPYING" in the main directory of this archive 18 + * for more details. 15 19 */ 16 - 17 20 #include <linux/init.h> 18 21 #include <linux/irq.h> 19 22 #include <linux/module.h> 20 - 21 23 #include <asm/system.h> 22 24 #include <asm/io.h> 23 25 #include <asm/machvec.h> ··· 28 28 int shift; /* Shifts of the 16-bit data */ 29 29 int priority; /* The priority */ 30 30 }; 31 - static struct ipr_data ipr_data[NR_IRQS]; 32 - 33 - static void enable_ipr_irq(unsigned int irq); 34 - static void disable_ipr_irq(unsigned int irq); 35 - 36 - /* shutdown is same as "disable" */ 37 - #define shutdown_ipr_irq disable_ipr_irq 38 - 39 - static void mask_and_ack_ipr(unsigned int); 40 - static void end_ipr_irq(unsigned int irq); 41 - 42 - static unsigned int startup_ipr_irq(unsigned int irq) 43 - { 44 - enable_ipr_irq(irq); 45 - return 0; /* never anything pending */ 46 - } 47 - 48 - static struct hw_interrupt_type ipr_irq_type = { 49 - .typename = "IPR-IRQ", 50 - .startup = startup_ipr_irq, 51 - .shutdown = shutdown_ipr_irq, 52 - .enable = enable_ipr_irq, 53 - .disable = disable_ipr_irq, 54 - .ack = mask_and_ack_ipr, 55 - .end = end_ipr_irq 56 - }; 57 31 58 32 static void disable_ipr_irq(unsigned int irq) 59 33 { 60 - unsigned long val; 61 - unsigned int addr = ipr_data[irq].addr; 62 - unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); 63 - 34 + struct ipr_data *p = get_irq_chip_data(irq); 64 35 /* Set the priority in IPR to 0 */ 65 - val = ctrl_inw(addr); 66 - val &= mask; 67 - ctrl_outw(val, addr); 36 + ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); 68 37 } 69 38 70 39 static void enable_ipr_irq(unsigned int irq) 71 40 { 72 - unsigned long val; 73 - unsigned int addr = ipr_data[irq].addr; 74 - int priority = ipr_data[irq].priority; 75 - unsigned short value = (priority << ipr_data[irq].shift); 76 - 41 + struct ipr_data *p = get_irq_chip_data(irq); 77 42 /* Set priority in IPR back to original value */ 78 - val = ctrl_inw(addr); 79 - val |= value; 80 - ctrl_outw(val, addr); 43 + ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); 81 44 } 82 45 83 - static void mask_and_ack_ipr(unsigned int irq) 84 - { 85 - disable_ipr_irq(irq); 86 - 87 - #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 88 - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ 89 - defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 90 - /* This is needed when we use edge triggered setting */ 91 - /* XXX: Is it really needed? */ 92 - if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { 93 - /* Clear external interrupt request */ 94 - int a = ctrl_inb(INTC_IRR0); 95 - a &= ~(1 << (irq - IRQ0_IRQ)); 96 - ctrl_outb(a, INTC_IRR0); 97 - } 98 - #endif 99 - } 100 - 101 - static void end_ipr_irq(unsigned int irq) 102 - { 103 - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 104 - enable_ipr_irq(irq); 105 - } 46 + static struct irq_chip ipr_irq_chip = { 47 + .name = "ipr", 48 + .mask = disable_ipr_irq, 49 + .unmask = enable_ipr_irq, 50 + .mask_ack = disable_ipr_irq, 51 + }; 106 52 107 53 void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) 108 54 { 109 - disable_irq_nosync(irq); 110 - ipr_data[irq].addr = addr; 111 - ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ 112 - ipr_data[irq].priority = priority; 55 + struct ipr_data ipr_data; 113 56 114 - irq_desc[irq].chip = &ipr_irq_type; 115 - disable_ipr_irq(irq); 57 + disable_irq_nosync(irq); 58 + 59 + ipr_data.addr = addr; 60 + ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */ 61 + ipr_data.priority = priority; 62 + 63 + set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq); 64 + set_irq_chip_data(irq, &ipr_data); 65 + 66 + enable_ipr_irq(irq); 116 67 } 117 68 69 + /* XXX: This needs to die a horrible death.. */ 118 70 void __init init_IRQ(void) 119 71 { 120 72 #ifndef CONFIG_CPU_SUBTYPE_SH7780