Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.14-rc2 130 lines 3.3 kB view raw
1#include <linux/config.h> 2#include <linux/module.h> 3#include <linux/stddef.h> 4#include <linux/init.h> 5#include <linux/sched.h> 6#include <linux/signal.h> 7#include <linux/interrupt.h> 8#include <asm/irq.h> 9#include <asm/8xx_immap.h> 10#include <asm/mpc8xx.h> 11#include "ppc8xx_pic.h" 12 13extern int cpm_get_irq(struct pt_regs *regs); 14 15/* The 8xx internal interrupt controller. It is usually 16 * the only interrupt controller. Some boards, like the MBX and 17 * Sandpoint have the 8259 as a secondary controller. Depending 18 * upon the processor type, the internal controller can have as 19 * few as 16 interrups or as many as 64. We could use the 20 * "clear_bit()" and "set_bit()" functions like other platforms, 21 * but they are overkill for us. 22 */ 23 24static void m8xx_mask_irq(unsigned int irq_nr) 25{ 26 int bit, word; 27 28 bit = irq_nr & 0x1f; 29 word = irq_nr >> 5; 30 31 ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); 32 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 33 ppc_cached_irq_mask[word]; 34} 35 36static void m8xx_unmask_irq(unsigned int irq_nr) 37{ 38 int bit, word; 39 40 bit = irq_nr & 0x1f; 41 word = irq_nr >> 5; 42 43 ppc_cached_irq_mask[word] |= (1 << (31-bit)); 44 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 45 ppc_cached_irq_mask[word]; 46} 47 48static void m8xx_end_irq(unsigned int irq_nr) 49{ 50 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) 51 && irq_desc[irq_nr].action) { 52 int bit, word; 53 54 bit = irq_nr & 0x1f; 55 word = irq_nr >> 5; 56 57 ppc_cached_irq_mask[word] |= (1 << (31-bit)); 58 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 59 ppc_cached_irq_mask[word]; 60 } 61} 62 63 64static void m8xx_mask_and_ack(unsigned int irq_nr) 65{ 66 int bit, word; 67 68 bit = irq_nr & 0x1f; 69 word = irq_nr >> 5; 70 71 ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); 72 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 73 ppc_cached_irq_mask[word]; 74 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit); 75} 76 77struct hw_interrupt_type ppc8xx_pic = { 78 .typename = " 8xx SIU ", 79 .enable = m8xx_unmask_irq, 80 .disable = m8xx_mask_irq, 81 .ack = m8xx_mask_and_ack, 82 .end = m8xx_end_irq, 83}; 84 85/* 86 * We either return a valid interrupt or -1 if there is nothing pending 87 */ 88int 89m8xx_get_irq(struct pt_regs *regs) 90{ 91 int irq; 92 93 /* For MPC8xx, read the SIVEC register and shift the bits down 94 * to get the irq number. 95 */ 96 irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26; 97 98 /* 99 * When we read the sivec without an interrupt to process, we will 100 * get back SIU_LEVEL7. In this case, return -1 101 */ 102 if (irq == CPM_INTERRUPT) 103 irq = CPM_IRQ_OFFSET + cpm_get_irq(regs); 104#if defined(CONFIG_PCI) 105 else if (irq == ISA_BRIDGE_INT) { 106 int isa_irq; 107 108 if ((isa_irq = i8259_poll(regs)) >= 0) 109 irq = I8259_IRQ_OFFSET + isa_irq; 110 } 111#endif /* CONFIG_PCI */ 112 else if (irq == SIU_LEVEL7) 113 irq = -1; 114 115 return irq; 116} 117 118#if defined(CONFIG_MBX) && defined(CONFIG_PCI) 119/* Only the MBX uses the external 8259. This allows us to catch standard 120 * drivers that may mess up the internal interrupt controllers, and also 121 * allow them to run without modification on the MBX. 122 */ 123void mbx_i8259_action(int irq, void *dev_id, struct pt_regs *regs) 124{ 125 /* This interrupt handler never actually gets called. It is 126 * installed only to unmask the 8259 cascade interrupt in the SIU 127 * and to make the 8259 cascade interrupt visible in /proc/interrupts. 128 */ 129} 130#endif /* CONFIG_PCI */