|  | /* | 
|  | * include/asm-ppc/ipic.c | 
|  | * | 
|  | * IPIC routines implementations. | 
|  | * | 
|  | * Copyright 2005 Freescale Semiconductor, Inc. | 
|  | * | 
|  | * This program is free software; you can redistribute  it and/or modify it | 
|  | * under  the terms of  the GNU General  Public License as published by the | 
|  | * Free Software Foundation;  either version 2 of the  License, or (at your | 
|  | * option) any later version. | 
|  | */ | 
|  | #include <linux/kernel.h> | 
|  | #include <linux/init.h> | 
|  | #include <linux/errno.h> | 
|  | #include <linux/reboot.h> | 
|  | #include <linux/slab.h> | 
|  | #include <linux/stddef.h> | 
|  | #include <linux/sched.h> | 
|  | #include <linux/signal.h> | 
|  | #include <linux/sysdev.h> | 
|  | #include <asm/irq.h> | 
|  | #include <asm/io.h> | 
|  | #include <asm/ipic.h> | 
|  | #include <asm/mpc83xx.h> | 
|  |  | 
|  | #include "ipic.h" | 
|  |  | 
|  | static struct ipic p_ipic; | 
|  | static struct ipic * primary_ipic; | 
|  |  | 
|  | static struct ipic_info ipic_info[] = { | 
|  | [9] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 24, | 
|  | .prio_mask = 0, | 
|  | }, | 
|  | [10] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 25, | 
|  | .prio_mask = 1, | 
|  | }, | 
|  | [11] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 26, | 
|  | .prio_mask = 2, | 
|  | }, | 
|  | [14] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 29, | 
|  | .prio_mask = 5, | 
|  | }, | 
|  | [15] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 30, | 
|  | .prio_mask = 6, | 
|  | }, | 
|  | [16] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_D, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 31, | 
|  | .prio_mask = 7, | 
|  | }, | 
|  | [17] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 1, | 
|  | .prio_mask = 5, | 
|  | }, | 
|  | [18] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 2, | 
|  | .prio_mask = 6, | 
|  | }, | 
|  | [19] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 3, | 
|  | .prio_mask = 7, | 
|  | }, | 
|  | [20] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 4, | 
|  | .prio_mask = 4, | 
|  | }, | 
|  | [21] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 5, | 
|  | .prio_mask = 5, | 
|  | }, | 
|  | [22] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 6, | 
|  | .prio_mask = 6, | 
|  | }, | 
|  | [23] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 7, | 
|  | .prio_mask = 7, | 
|  | }, | 
|  | [32] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 0, | 
|  | .prio_mask = 0, | 
|  | }, | 
|  | [33] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 1, | 
|  | .prio_mask = 1, | 
|  | }, | 
|  | [34] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 2, | 
|  | .prio_mask = 2, | 
|  | }, | 
|  | [35] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 3, | 
|  | .prio_mask = 3, | 
|  | }, | 
|  | [36] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 4, | 
|  | .prio_mask = 4, | 
|  | }, | 
|  | [37] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 5, | 
|  | .prio_mask = 5, | 
|  | }, | 
|  | [38] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 6, | 
|  | .prio_mask = 6, | 
|  | }, | 
|  | [39] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_H, | 
|  | .prio	= IPIC_SIPRR_A, | 
|  | .force	= IPIC_SIFCR_H, | 
|  | .bit	= 7, | 
|  | .prio_mask = 7, | 
|  | }, | 
|  | [48] = { | 
|  | .pend	= IPIC_SEPNR, | 
|  | .mask	= IPIC_SEMSR, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SEFCR, | 
|  | .bit	= 0, | 
|  | .prio_mask = 4, | 
|  | }, | 
|  | [64] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 0, | 
|  | .prio_mask = 0, | 
|  | }, | 
|  | [65] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 1, | 
|  | .prio_mask = 1, | 
|  | }, | 
|  | [66] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 2, | 
|  | .prio_mask = 2, | 
|  | }, | 
|  | [67] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_A, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 3, | 
|  | .prio_mask = 3, | 
|  | }, | 
|  | [68] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 4, | 
|  | .prio_mask = 0, | 
|  | }, | 
|  | [69] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 5, | 
|  | .prio_mask = 1, | 
|  | }, | 
|  | [70] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 6, | 
|  | .prio_mask = 2, | 
|  | }, | 
|  | [71] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= IPIC_SMPRR_B, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 7, | 
|  | .prio_mask = 3, | 
|  | }, | 
|  | [72] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 8, | 
|  | }, | 
|  | [73] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 9, | 
|  | }, | 
|  | [74] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 10, | 
|  | }, | 
|  | [75] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 11, | 
|  | }, | 
|  | [76] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 12, | 
|  | }, | 
|  | [77] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 13, | 
|  | }, | 
|  | [78] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 14, | 
|  | }, | 
|  | [79] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 15, | 
|  | }, | 
|  | [80] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 16, | 
|  | }, | 
|  | [84] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 20, | 
|  | }, | 
|  | [85] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 21, | 
|  | }, | 
|  | [90] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 26, | 
|  | }, | 
|  | [91] = { | 
|  | .pend	= IPIC_SIPNR_H, | 
|  | .mask	= IPIC_SIMSR_L, | 
|  | .prio	= 0, | 
|  | .force	= IPIC_SIFCR_L, | 
|  | .bit	= 27, | 
|  | }, | 
|  | }; | 
|  |  | 
|  | static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) | 
|  | { | 
|  | return in_be32(base + (reg >> 2)); | 
|  | } | 
|  |  | 
|  | static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) | 
|  | { | 
|  | out_be32(base + (reg >> 2), value); | 
|  | } | 
|  |  | 
|  | static inline struct ipic * ipic_from_irq(unsigned int irq) | 
|  | { | 
|  | return primary_ipic; | 
|  | } | 
|  |  | 
|  | static void ipic_enable_irq(unsigned int irq) | 
|  | { | 
|  | struct ipic *ipic = ipic_from_irq(irq); | 
|  | unsigned int src = irq - ipic->irq_offset; | 
|  | u32 temp; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, ipic_info[src].mask); | 
|  | temp |= (1 << (31 - ipic_info[src].bit)); | 
|  | ipic_write(ipic->regs, ipic_info[src].mask, temp); | 
|  | } | 
|  |  | 
|  | static void ipic_disable_irq(unsigned int irq) | 
|  | { | 
|  | struct ipic *ipic = ipic_from_irq(irq); | 
|  | unsigned int src = irq - ipic->irq_offset; | 
|  | u32 temp; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, ipic_info[src].mask); | 
|  | temp &= ~(1 << (31 - ipic_info[src].bit)); | 
|  | ipic_write(ipic->regs, ipic_info[src].mask, temp); | 
|  | } | 
|  |  | 
|  | static void ipic_disable_irq_and_ack(unsigned int irq) | 
|  | { | 
|  | struct ipic *ipic = ipic_from_irq(irq); | 
|  | unsigned int src = irq - ipic->irq_offset; | 
|  | u32 temp; | 
|  |  | 
|  | ipic_disable_irq(irq); | 
|  |  | 
|  | temp = ipic_read(ipic->regs, ipic_info[src].pend); | 
|  | temp |= (1 << (31 - ipic_info[src].bit)); | 
|  | ipic_write(ipic->regs, ipic_info[src].pend, temp); | 
|  | } | 
|  |  | 
|  | static void ipic_end_irq(unsigned int irq) | 
|  | { | 
|  | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | 
|  | ipic_enable_irq(irq); | 
|  | } | 
|  |  | 
|  | struct hw_interrupt_type ipic = { | 
|  | .typename = " IPIC  ", | 
|  | .enable = ipic_enable_irq, | 
|  | .disable = ipic_disable_irq, | 
|  | .ack = ipic_disable_irq_and_ack, | 
|  | .end = ipic_end_irq, | 
|  | }; | 
|  |  | 
|  | void __init ipic_init(phys_addr_t phys_addr, | 
|  | unsigned int flags, | 
|  | unsigned int irq_offset, | 
|  | unsigned char *senses, | 
|  | unsigned int senses_count) | 
|  | { | 
|  | u32 i, temp = 0; | 
|  |  | 
|  | primary_ipic = &p_ipic; | 
|  | primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE); | 
|  |  | 
|  | primary_ipic->irq_offset = irq_offset; | 
|  |  | 
|  | ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0); | 
|  |  | 
|  | /* default priority scheme is grouped. If spread mode is required | 
|  | * configure SICFR accordingly */ | 
|  | if (flags & IPIC_SPREADMODE_GRP_A) | 
|  | temp |= SICFR_IPSA; | 
|  | if (flags & IPIC_SPREADMODE_GRP_D) | 
|  | temp |= SICFR_IPSD; | 
|  | if (flags & IPIC_SPREADMODE_MIX_A) | 
|  | temp |= SICFR_MPSA; | 
|  | if (flags & IPIC_SPREADMODE_MIX_B) | 
|  | temp |= SICFR_MPSB; | 
|  |  | 
|  | ipic_write(primary_ipic->regs, IPIC_SICNR, temp); | 
|  |  | 
|  | /* handle MCP route */ | 
|  | temp = 0; | 
|  | if (flags & IPIC_DISABLE_MCP_OUT) | 
|  | temp = SERCR_MCPR; | 
|  | ipic_write(primary_ipic->regs, IPIC_SERCR, temp); | 
|  |  | 
|  | /* handle routing of IRQ0 to MCP */ | 
|  | temp = ipic_read(primary_ipic->regs, IPIC_SEMSR); | 
|  |  | 
|  | if (flags & IPIC_IRQ0_MCP) | 
|  | temp |= SEMSR_SIRQ0; | 
|  | else | 
|  | temp &= ~SEMSR_SIRQ0; | 
|  |  | 
|  | ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); | 
|  |  | 
|  | for (i = 0 ; i < NR_IPIC_INTS ; i++) { | 
|  | irq_desc[i+irq_offset].chip = &ipic; | 
|  | irq_desc[i+irq_offset].status = IRQ_LEVEL; | 
|  | } | 
|  |  | 
|  | temp = 0; | 
|  | for (i = 0 ; i < senses_count ; i++) { | 
|  | if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { | 
|  | temp |= 1 << (15 - i); | 
|  | if (i != 0) | 
|  | irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; | 
|  | else | 
|  | irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0; | 
|  | } | 
|  | } | 
|  | ipic_write(primary_ipic->regs, IPIC_SECNR, temp); | 
|  |  | 
|  | printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS, | 
|  | senses_count, primary_ipic->regs); | 
|  | } | 
|  |  | 
|  | int ipic_set_priority(unsigned int irq, unsigned int priority) | 
|  | { | 
|  | struct ipic *ipic = ipic_from_irq(irq); | 
|  | unsigned int src = irq - ipic->irq_offset; | 
|  | u32 temp; | 
|  |  | 
|  | if (priority > 7) | 
|  | return -EINVAL; | 
|  | if (src > 127) | 
|  | return -EINVAL; | 
|  | if (ipic_info[src].prio == 0) | 
|  | return -EINVAL; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, ipic_info[src].prio); | 
|  |  | 
|  | if (priority < 4) { | 
|  | temp &= ~(0x7 << (20 + (3 - priority) * 3)); | 
|  | temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); | 
|  | } else { | 
|  | temp &= ~(0x7 << (4 + (7 - priority) * 3)); | 
|  | temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); | 
|  | } | 
|  |  | 
|  | ipic_write(ipic->regs, ipic_info[src].prio, temp); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void ipic_set_highest_priority(unsigned int irq) | 
|  | { | 
|  | struct ipic *ipic = ipic_from_irq(irq); | 
|  | unsigned int src = irq - ipic->irq_offset; | 
|  | u32 temp; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, IPIC_SICFR); | 
|  |  | 
|  | /* clear and set HPI */ | 
|  | temp &= 0x7f000000; | 
|  | temp |= (src & 0x7f) << 24; | 
|  |  | 
|  | ipic_write(ipic->regs, IPIC_SICFR, temp); | 
|  | } | 
|  |  | 
|  | void ipic_set_default_priority(void) | 
|  | { | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0); | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1); | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2); | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3); | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4); | 
|  | ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5); | 
|  | ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6); | 
|  | ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7); | 
|  |  | 
|  | ipic_set_priority(MPC83xx_IRQ_UART1, 0); | 
|  | ipic_set_priority(MPC83xx_IRQ_UART2, 1); | 
|  | ipic_set_priority(MPC83xx_IRQ_SEC2, 2); | 
|  | ipic_set_priority(MPC83xx_IRQ_IIC1, 5); | 
|  | ipic_set_priority(MPC83xx_IRQ_IIC2, 6); | 
|  | ipic_set_priority(MPC83xx_IRQ_SPI, 7); | 
|  | ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0); | 
|  | ipic_set_priority(MPC83xx_IRQ_PIT, 1); | 
|  | ipic_set_priority(MPC83xx_IRQ_PCI1, 2); | 
|  | ipic_set_priority(MPC83xx_IRQ_PCI2, 3); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT0, 4); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT1, 5); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT2, 6); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT3, 7); | 
|  | ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0); | 
|  | ipic_set_priority(MPC83xx_IRQ_MU, 1); | 
|  | ipic_set_priority(MPC83xx_IRQ_SBA, 2); | 
|  | ipic_set_priority(MPC83xx_IRQ_DMA, 3); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT4, 4); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT5, 5); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT6, 6); | 
|  | ipic_set_priority(MPC83xx_IRQ_EXT7, 7); | 
|  | } | 
|  |  | 
|  | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) | 
|  | { | 
|  | struct ipic *ipic = primary_ipic; | 
|  | u32 temp; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, IPIC_SERMR); | 
|  | temp |= (1 << (31 - mcp_irq)); | 
|  | ipic_write(ipic->regs, IPIC_SERMR, temp); | 
|  | } | 
|  |  | 
|  | void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) | 
|  | { | 
|  | struct ipic *ipic = primary_ipic; | 
|  | u32 temp; | 
|  |  | 
|  | temp = ipic_read(ipic->regs, IPIC_SERMR); | 
|  | temp &= (1 << (31 - mcp_irq)); | 
|  | ipic_write(ipic->regs, IPIC_SERMR, temp); | 
|  | } | 
|  |  | 
|  | u32 ipic_get_mcp_status(void) | 
|  | { | 
|  | return ipic_read(primary_ipic->regs, IPIC_SERMR); | 
|  | } | 
|  |  | 
|  | void ipic_clear_mcp_status(u32 mask) | 
|  | { | 
|  | ipic_write(primary_ipic->regs, IPIC_SERMR, mask); | 
|  | } | 
|  |  | 
|  | /* Return an interrupt vector or -1 if no interrupt is pending. */ | 
|  | int ipic_get_irq(struct pt_regs *regs) | 
|  | { | 
|  | int irq; | 
|  |  | 
|  | irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f; | 
|  |  | 
|  | if (irq == 0)    /* 0 --> no irq is pending */ | 
|  | irq = -1; | 
|  |  | 
|  | return irq; | 
|  | } | 
|  |  | 
|  | static struct sysdev_class ipic_sysclass = { | 
|  | set_kset_name("ipic"), | 
|  | }; | 
|  |  | 
|  | static struct sys_device device_ipic = { | 
|  | .id		= 0, | 
|  | .cls		= &ipic_sysclass, | 
|  | }; | 
|  |  | 
|  | static int __init init_ipic_sysfs(void) | 
|  | { | 
|  | int rc; | 
|  |  | 
|  | if (!primary_ipic->regs) | 
|  | return -ENODEV; | 
|  | printk(KERN_DEBUG "Registering ipic with sysfs...\n"); | 
|  |  | 
|  | rc = sysdev_class_register(&ipic_sysclass); | 
|  | if (rc) { | 
|  | printk(KERN_ERR "Failed registering ipic sys class\n"); | 
|  | return -ENODEV; | 
|  | } | 
|  | rc = sysdev_register(&device_ipic); | 
|  | if (rc) { | 
|  | printk(KERN_ERR "Failed registering ipic sys device\n"); | 
|  | return -ENODEV; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | subsys_initcall(init_ipic_sysfs); |