summaryrefslogtreecommitdiff
path: root/arch/ppc/syslib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/syslib')
-rw-r--r--arch/ppc/syslib/Makefile2
-rw-r--r--arch/ppc/syslib/ipic.c646
-rw-r--r--arch/ppc/syslib/ipic.h47
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c89
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c8
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c6
-rw-r--r--arch/ppc/syslib/pq2_devices.c5
-rw-r--r--arch/ppc/syslib/pq2_sys.c3
8 files changed, 799 insertions, 7 deletions
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 2497bbc07e7..dca23f2ef85 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -93,7 +93,7 @@ obj-$(CONFIG_PCI) += pci_auto.o
endif
obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
obj-$(CONFIG_83xx) += ppc83xx_setup.o ppc_sys.o \
- mpc83xx_sys.o mpc83xx_devices.o
+ mpc83xx_sys.o mpc83xx_devices.o ipic.o
ifeq ($(CONFIG_83xx),y)
obj-$(CONFIG_PCI) += pci_auto.o
endif
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
new file mode 100644
index 00000000000..46801f5ec03
--- /dev/null
+++ b/arch/ppc/syslib/ipic.c
@@ -0,0 +1,646 @@
+/*
+ * 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);
diff --git a/arch/ppc/syslib/ipic.h b/arch/ppc/syslib/ipic.h
new file mode 100644
index 00000000000..a60c9d18bb7
--- /dev/null
+++ b/arch/ppc/syslib/ipic.h
@@ -0,0 +1,47 @@
+/*
+ * IPIC private definitions and structure.
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * 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.
+ */
+#ifndef __IPIC_H__
+#define __IPIC_H__
+
+#include <asm/ipic.h>
+
+#define MPC83xx_IPIC_SIZE (0x00100)
+
+/* System Global Interrupt Configuration Register */
+#define SICFR_IPSA 0x00010000
+#define SICFR_IPSD 0x00080000
+#define SICFR_MPSA 0x00200000
+#define SICFR_MPSB 0x00400000
+
+/* System External Interrupt Mask Register */
+#define SEMSR_SIRQ0 0x00008000
+
+/* System Error Control Register */
+#define SERCR_MCPR 0x00000001
+
+struct ipic {
+ volatile u32 __iomem *regs;
+ unsigned int irq_offset;
+};
+
+struct ipic_info {
+ u8 pend; /* pending register offset from base */
+ u8 mask; /* mask register offset from base */
+ u8 prio; /* priority register offset from base */
+ u8 force; /* force register offset from base */
+ u8 bit; /* register bit position (as per doc)
+ bit mask = 1 << (31 - bit) */
+ u8 prio_mask; /* priority mask value */
+};
+
+#endif /* __IPIC_H__ */
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 7735336f5b8..325136e5aee 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -16,9 +16,11 @@
#include <linux/device.h>
#include <linux/serial_8250.h>
#include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
#include <asm/mpc85xx.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/cpm2.h>
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
@@ -82,6 +84,60 @@ static struct fsl_i2c_platform_data mpc85xx_fsl_i2c2_pdata = {
.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
};
+static struct fs_platform_info mpc85xx_fcc1_pdata = {
+ .fs_no = fsid_fcc1,
+ .cp_page = CPM_CR_FCC1_PAGE,
+ .cp_block = CPM_CR_FCC1_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX1_CLK_MASK,
+ .clk_route = CMX1_CLK_ROUTE,
+ .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
+
+ .mem_offset = FCC1_MEM_OFFSET,
+};
+
+static struct fs_platform_info mpc85xx_fcc2_pdata = {
+ .fs_no = fsid_fcc2,
+ .cp_page = CPM_CR_FCC2_PAGE,
+ .cp_block = CPM_CR_FCC2_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX2_CLK_MASK,
+ .clk_route = CMX2_CLK_ROUTE,
+ .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
+
+ .mem_offset = FCC2_MEM_OFFSET,
+};
+
+static struct fs_platform_info mpc85xx_fcc3_pdata = {
+ .fs_no = fsid_fcc3,
+ .cp_page = CPM_CR_FCC3_PAGE,
+ .cp_block = CPM_CR_FCC3_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX3_CLK_MASK,
+ .clk_route = CMX3_CLK_ROUTE,
+ .clk_trx = (PC_F3RXCLK | PC_F3TXCLK),
+
+ .mem_offset = FCC3_MEM_OFFSET,
+};
+
static struct plat_serial8250_port serial_platform_data[] = {
[0] = {
.mapbase = 0x4500,
@@ -318,19 +374,28 @@ struct platform_device ppc_sys_platform_devices[] = {
[MPC85xx_CPM_FCC1] = {
.name = "fsl-cpm-fcc",
.id = 1,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc1_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91300,
.end = 0x9131F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x91380,
.end = 0x9139F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_pram",
+ .start = 0x88400,
+ .end = 0x884ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
.start = SIU_INT_FCC1,
.end = SIU_INT_FCC1,
.flags = IORESOURCE_IRQ,
@@ -340,19 +405,28 @@ struct platform_device ppc_sys_platform_devices[] = {
[MPC85xx_CPM_FCC2] = {
.name = "fsl-cpm-fcc",
.id = 2,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc2_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91320,
.end = 0x9133F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x913A0,
.end = 0x913CF,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_pram",
+ .start = 0x88500,
+ .end = 0x885ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
.start = SIU_INT_FCC2,
.end = SIU_INT_FCC2,
.flags = IORESOURCE_IRQ,
@@ -362,19 +436,28 @@ struct platform_device ppc_sys_platform_devices[] = {
[MPC85xx_CPM_FCC3] = {
.name = "fsl-cpm-fcc",
.id = 3,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc3_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91340,
.end = 0x9135F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x913D0,
.end = 0x913FF,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_pram",
+ .start = 0x88600,
+ .end = 0x886ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
.start = SIU_INT_FCC3,
.end = SIU_INT_FCC3,
.flags = IORESOURCE_IRQ,
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index 6f536383866..cf5ab47487a 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -218,6 +218,14 @@ struct platform_device ppc_sys_platform_devices[] = {
},
},
},
+
+ [MPC8xx_MDIO_FEC] = {
+ .name = "fsl-cpm-fec-mdio",
+ .id = 0,
+ .num_resources = 0,
+
+ },
+
};
static int __init mach_mpc8xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index eee21328485..18ba1d7ff9f 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -22,7 +22,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "MPC86X",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 7,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
@@ -32,13 +32,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC8xx_CPM_SCC4,
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
+ MPC8xx_MDIO_FEC,
},
},
{
.ppc_sys_name = "MPC885",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 8,
+ .num_devices = 9,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
@@ -49,6 +50,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC8xx_CPM_SCC4,
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
+ MPC8xx_MDIO_FEC,
},
},
{ /* default match */
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index 8692d00c08c..fefbc217a56 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -369,6 +369,11 @@ struct platform_device ppc_sys_platform_devices[] = {
},
},
},
+ [MPC82xx_MDIO_BB] = {
+ .name = "fsl-bb-mdio",
+ .id = 0,
+ .num_resources = 0,
+ },
};
static int __init mach_mpc82xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index fee8948162b..f52600c0db2 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -139,13 +139,14 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8272",
.mask = 0x0000ff00,
.value = 0x00000c00,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
+ MPC82xx_MDIO_BB,
},
},
/* below is a list of the 8280 family of processors */