PageRenderTime 40ms CodeModel.GetById 18ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/ppc/syslib/ppc403_pic.c

https://bitbucket.org/evzijst/gittest
C | 127 lines | 69 code | 26 blank | 32 comment | 3 complexity | 9e747313d9009e257cf82df2e2372686 MD5 | raw file
  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}