1/* 2 * linux/arch/sh/boards/se/770x/irq.c 3 * 4 * Copyright (C) 2000 Kazumoto Kojima 5 * Copyright (C) 2006 Nobuhiro Iwamatsu 6 * 7 * Hitachi SolutionEngine Support. 8 * 9 */ 10 11#include <linux/init.h> 12#include <linux/interrupt.h> 13#include <linux/irq.h> 14#include <asm/irq.h> 15#include <asm/io.h> 16#include <asm/se.h> 17 18/* 19 * If the problem of make_ipr_irq is solved, 20 * this code will become unnecessary. :-) 21 */ 22static void se770x_disable_ipr_irq(unsigned int irq) 23{ 24 struct ipr_data *p = get_irq_chip_data(irq); 25 26 ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); 27} 28 29static void se770x_enable_ipr_irq(unsigned int irq) 30{ 31 struct ipr_data *p = get_irq_chip_data(irq); 32 33 ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); 34} 35 36static struct irq_chip se770x_irq_chip = { 37 .name = "MS770xSE-FPGA", 38 .mask = se770x_disable_ipr_irq, 39 .unmask = se770x_enable_ipr_irq, 40 .mask_ack = se770x_disable_ipr_irq, 41}; 42 43void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs) 44{ 45 int i; 46 47 for (i = 0; i < nr_irqs; i++) { 48 unsigned int irq = table[i].irq; 49 disable_irq_nosync(irq); 50 set_irq_chip_and_handler_name(irq, &se770x_irq_chip, 51 handle_level_irq, "level"); 52 set_irq_chip_data(irq, &table[i]); 53 se770x_enable_ipr_irq(irq); 54 } 55} 56 57static struct ipr_data se770x_ipr_map[] = { 58 /* 59 * Super I/O (Just mimic PC): 60 * 1: keyboard 61 * 3: serial 0 62 * 4: serial 1 63 * 5: printer 64 * 6: floppy 65 * 8: rtc 66 * 12: mouse 67 * 14: ide0 68 */ 69#if defined(CONFIG_CPU_SUBTYPE_SH7705) 70 /* This is default value */ 71 { 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, 72 { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, 73 { 10, 0, 0, 0x0f-10, BCR_ILCRB}, 74 { 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, 75 { 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, 76 { 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, 77 { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ 78 { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ 79 { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ 80 { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ 81 { 0 , 0, 12, 0x0f , BCR_ILCRF}, 82 { 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, 83 { 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, 84 { 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, 85 { 11, 0, 4, 0x0f-11, BCR_ILCRG}, 86#else 87 { 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, 88 { 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, 89 { 8, 0, 4, 0x0f- 8 ,BCR_ILCRB}, 90 { 6, 0, 12, 0x0f- 6 ,BCR_ILCRC}, 91 { 5, 0, 8, 0x0f- 5 ,BCR_ILCRC}, 92 { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, 93 { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, 94 { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, 95#if defined(CONFIG_STNIC) 96 /* ST NIC */ 97 { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ 98#endif 99 /* MRSHPC IRQs setting */ 100 { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ 101 { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ 102 { 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */ 103 { 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */ 104 /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ 105 /* NOTE: #2 and #13 are not used on PC */ 106 { 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */ 107 { 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */ 108#endif 109}; 110 111/* 112 * Initialize IRQ setting 113 */ 114void __init init_se_IRQ(void) 115{ 116 /* Disable all interrupts */ 117 ctrl_outw(0, BCR_ILCRA); 118 ctrl_outw(0, BCR_ILCRB); 119 ctrl_outw(0, BCR_ILCRC); 120 ctrl_outw(0, BCR_ILCRD); 121 ctrl_outw(0, BCR_ILCRE); 122 ctrl_outw(0, BCR_ILCRF); 123 ctrl_outw(0, BCR_ILCRG); 124 125 make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); 126} 127