Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | // SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/renesas/rts7751r2d/irq.c * * Copyright (C) 2007 Magnus Damm * Copyright (C) 2000 Kazumoto Kojima * * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1. * * Modified for RTS7751R2D by * Atom Create Engineering Co., Ltd. 2002. */ #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/io.h> #include <mach/r2d.h> #define R2D_NR_IRL 13 enum { UNUSED = 0, /* board specific interrupt sources (R2D-1 and R2D-PLUS) */ EXT, /* EXT_INT0-3 */ RTC_T, RTC_A, /* Real Time Clock */ AX88796, /* Ethernet controller (R2D-1 board) */ KEY, /* Key input (R2D-PLUS board) */ SDCARD, /* SD Card */ CF_CD, CF_IDE, /* CF Card Detect + CF IDE */ SM501, /* SM501 aka Voyager */ PCI_INTD_RTL8139, /* Ethernet controller */ PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */ PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */ PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */ PCI_INTA_SLOT, /* PCI Slot 3.3v */ TP, /* Touch Panel */ }; #ifdef CONFIG_RTS7751R2D_1 /* Vectors for R2D-1 */ static struct intc_vect vectors_r2d_1[] __initdata = { INTC_IRQ(EXT, IRQ_EXT), INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD), INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */ INTC_IRQ(SM501, IRQ_VOYAGER), INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB), INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), INTC_IRQ(TP, IRQ_TP), }; /* IRLMSK mask register layout for R2D-1 */ static struct intc_mask_reg mask_registers_r2d_1[] __initdata = { { 0xa4000000, 0, 16, /* IRLMSK */ { TP, PCI_INTA_SLOT, PCI_INTB_SLOT, PCI_INTC_PCI1520, PCI_INTD_RTL8139, SM501, CF_IDE, CF_CD, SDCARD, AX88796, RTC_A, RTC_T, 0, 0, 0, EXT } }, }; /* IRLn to IRQ table for R2D-1 */ static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = { IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T, IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, IRQ_TP, }; static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, NULL, mask_registers_r2d_1, NULL, NULL); #endif /* CONFIG_RTS7751R2D_1 */ #ifdef CONFIG_RTS7751R2D_PLUS /* Vectors for R2D-PLUS */ static struct intc_vect vectors_r2d_plus[] __initdata = { INTC_IRQ(EXT, IRQ_EXT), INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD), INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), INTC_IRQ(SM501, IRQ_VOYAGER), INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB), INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), INTC_IRQ(TP, IRQ_TP), }; /* IRLMSK mask register layout for R2D-PLUS */ static struct intc_mask_reg mask_registers_r2d_plus[] __initdata = { { 0xa4000000, 0, 16, /* IRLMSK */ { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139, PCI_INTC_PCI1520, PCI_INTD_RTL8139, SM501, CF_IDE, CF_CD, SDCARD, KEY, RTC_A, RTC_T, 0, 0, 0, EXT } }, }; /* IRLn to IRQ table for R2D-PLUS */ static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = { IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T, IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, IRQ_TP, }; static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, NULL, mask_registers_r2d_plus, NULL, NULL); #endif /* CONFIG_RTS7751R2D_PLUS */ static unsigned char irl2irq[R2D_NR_IRL]; int rts7751r2d_irq_demux(int irq) { if (irq >= R2D_NR_IRL + 16 || irq < 16 || !irl2irq[irq - 16]) return irq; return irl2irq[irq - 16]; } /* * Initialize IRQ setting */ void __init init_rts7751r2d_IRQ(void) { struct intc_desc *d; switch (__raw_readw(PA_VERREG) & 0xf0) { #ifdef CONFIG_RTS7751R2D_PLUS case 0x10: printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); d = &intc_desc_r2d_plus; memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL); break; #endif #ifdef CONFIG_RTS7751R2D_1 case 0x00: /* according to manual */ case 0x30: /* in reality */ printk(KERN_INFO "Using R2D-1 interrupt controller.\n"); d = &intc_desc_r2d_1; memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL); break; #endif default: printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n", __raw_readw(PA_VERREG)); return; } register_intc_controller(d); } |