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.12-rc2 127 lines 2.6 kB view raw
1/* 2 * 3 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> 4 * 5 * Module name: ppc403_pic.c 6 * 7 * Description: 8 * Interrupt controller driver for PowerPC 403-based processors. 9 */ 10 11/* 12 * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has 13 * 32 possible interrupts, a majority of which are not implemented on 14 * all cores. There are six configurable, external interrupt pins and 15 * there are eight internal interrupts for the on-chip serial port 16 * (SPU), DMA controller, and JTAG controller. 17 * 18 */ 19 20#include <linux/init.h> 21#include <linux/sched.h> 22#include <linux/signal.h> 23#include <linux/stddef.h> 24 25#include <asm/processor.h> 26#include <asm/system.h> 27#include <asm/irq.h> 28#include <asm/ppc4xx_pic.h> 29 30/* Function Prototypes */ 31 32static void ppc403_aic_enable(unsigned int irq); 33static void ppc403_aic_disable(unsigned int irq); 34static void ppc403_aic_disable_and_ack(unsigned int irq); 35 36static struct hw_interrupt_type ppc403_aic = { 37 "403GC AIC", 38 NULL, 39 NULL, 40 ppc403_aic_enable, 41 ppc403_aic_disable, 42 ppc403_aic_disable_and_ack, 43 0 44}; 45 46int 47ppc403_pic_get_irq(struct pt_regs *regs) 48{ 49 int irq; 50 unsigned long bits; 51 52 /* 53 * Only report the status of those interrupts that are actually 54 * enabled. 55 */ 56 57 bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER); 58 59 /* 60 * Walk through the interrupts from highest priority to lowest, and 61 * report the first pending interrupt found. 62 * We want PPC, not C bit numbering, so just subtract the ffs() 63 * result from 32. 64 */ 65 irq = 32 - ffs(bits); 66 67 if (irq == NR_AIC_IRQS) 68 irq = -1; 69 70 return (irq); 71} 72 73static void 74ppc403_aic_enable(unsigned int irq) 75{ 76 int bit, word; 77 78 bit = irq & 0x1f; 79 word = irq >> 5; 80 81 ppc_cached_irq_mask[word] |= (1 << (31 - bit)); 82 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); 83} 84 85static void 86ppc403_aic_disable(unsigned int irq) 87{ 88 int bit, word; 89 90 bit = irq & 0x1f; 91 word = irq >> 5; 92 93 ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); 94 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); 95} 96 97static void 98ppc403_aic_disable_and_ack(unsigned int irq) 99{ 100 int bit, word; 101 102 bit = irq & 0x1f; 103 word = irq >> 5; 104 105 ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); 106 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); 107 mtdcr(DCRN_EXISR, (1 << (31 - bit))); 108} 109 110void __init 111ppc4xx_pic_init(void) 112{ 113 int i; 114 115 /* 116 * Disable all external interrupts until they are 117 * explicity requested. 118 */ 119 ppc_cached_irq_mask[0] = 0; 120 121 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]); 122 123 ppc_md.get_irq = ppc403_pic_get_irq; 124 125 for (i = 0; i < NR_IRQS; i++) 126 irq_desc[i].handler = &ppc403_aic; 127}