Fixed powerpc-mkvmlinuz-support-powerpc.patch for 2.6.20-rc4
Re-enabled powerpc-mkvmlinuz-support-ppc.patch which was disabled without reason Updated efika patches to 2.6.20-rc4. svn path=/dists/trunk/linux-2.6/; revision=8162
This commit is contained in:
parent
81efc1bb84
commit
c63758bace
|
@ -29,12 +29,12 @@
|
|||
|
||||
PHONY += $(BOOT_TARGETS)
|
||||
|
||||
--- linux-2.6.19/arch/powerpc/boot/Makefile.orig 2006-12-05 16:14:42.000000000 +0000
|
||||
+++ linux-2.6.19/arch/powerpc/boot/Makefile 2006-12-05 16:13:37.000000000 +0000
|
||||
@@ -176,3 +176,18 @@
|
||||
|
||||
--- linux-2.6.20-rc3/arch/powerpc/boot/Makefile.orig 2007-01-04 16:22:53.000000000 +0100
|
||||
+++ linux-2.6.20-rc3/arch/powerpc/boot/Makefile 2007-01-04 16:23:40.000000000 +0100
|
||||
@@ -186,3 +186,19 @@
|
||||
clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
|
||||
clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
|
||||
clean-files += $(image-)
|
||||
+
|
||||
+#-----------------------------------------------------------
|
||||
+# install mkvmlinuz support files
|
||||
|
@ -48,5 +48,6 @@
|
|||
+ mkdir -p $(INSTALL_MKVMLINUZ)
|
||||
+ $(call cmd,mkvmlinuz)
|
||||
+
|
||||
+targets += mkvmlinuz_support_install
|
||||
+targets += mkvmlinuz_support_install
|
||||
+
|
||||
+
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
From 9f3ff0ffed7c1fc1dbf3c0628f1a22a20d0846ce Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 12:40:48 +0100
|
||||
Subject: [PATCH] Fix compilation issue when PPC_MPC52xx and PPC_MERGE are selected
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
include/asm-ppc/io.h | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
|
||||
index a4c411b..8ed380c 100644
|
||||
--- a/include/asm-ppc/io.h
|
||||
+++ b/include/asm-ppc/io.h
|
||||
@@ -26,7 +26,7 @@ #define PREP_PCI_DRAM_OFFSET 0x80000000
|
||||
|
||||
#if defined(CONFIG_4xx)
|
||||
#include <asm/ibm4xx.h>
|
||||
-#elif defined(CONFIG_PPC_MPC52xx)
|
||||
+#elif defined(CONFIG_PPC_MPC52xx) && !defined(CONFIG_PPC_MERGE)
|
||||
#include <asm/mpc52xx.h>
|
||||
#elif defined(CONFIG_8xx)
|
||||
#include <asm/mpc8xx.h>
|
||||
--
|
||||
1.4.3.2
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
From 6f004b2fa4f9b6e5692084f7301271503788c05c Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 9 Dec 2006 02:06:55 +0100
|
||||
Subject: [PATCH] powerpc: Add support for uevent to of_platform
|
||||
|
||||
This adds a proper uevent handler to the of_platform bus. This
|
||||
allows autoloading of modules (or at least should ;).
|
||||
It's _heavily_ based on the macio counterpart.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/kernel/of_platform.c | 70 +++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 70 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
|
||||
index b3189d0..f000023 100644
|
||||
--- a/arch/powerpc/kernel/of_platform.c
|
||||
+++ b/arch/powerpc/kernel/of_platform.c
|
||||
@@ -73,6 +73,75 @@ static int of_platform_bus_match(struct
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
+static int of_platform_uevent(struct device *dev, char **envp, int num_envp,
|
||||
+ char *buffer, int buffer_size)
|
||||
+{
|
||||
+ struct of_device *of;
|
||||
+ const char *compat;
|
||||
+ char *compat2;
|
||||
+ char compat_buf[128]; /* need to be size of 'compatible' */
|
||||
+
|
||||
+ int i = 0;
|
||||
+ int length = 0, cplen, sl, seen = 0;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ of = to_of_device(dev);
|
||||
+ if (!of)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ /* stuff we want to pass to /sbin/hotplug */
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_NAME=%s", of->node->name))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_TYPE=%s", of->node->type))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Since the compatible field can contain pretty much anything
|
||||
+ * it's not really legal to split it out with commas. We split it
|
||||
+ * up using a number of environment variables instead. */
|
||||
+
|
||||
+ compat = get_property(of->node, "compatible", &cplen);
|
||||
+ compat2 = compat_buf;
|
||||
+ if (compat)
|
||||
+ memcpy(compat2, compat, cplen);
|
||||
+ while (compat && *compat && cplen > 0) {
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sl = strlen (compat) + 1;
|
||||
+ compat += sl;
|
||||
+ compat2 += sl;
|
||||
+ cplen -= sl;
|
||||
+ seen++;
|
||||
+ compat2[-1] = 'C';
|
||||
+ }
|
||||
+ compat2[seen?-1:0] = 0;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_COMPATIBLE_N=%d", seen))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "MODALIAS=of:N%sT%sC%s",
|
||||
+ of->node->name, of->node->type,
|
||||
+ compat_buf))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ envp[i] = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int of_platform_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
@@ -132,6 +201,7 @@ static int of_platform_device_resume(str
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.name = "of_platform",
|
||||
.match = of_platform_bus_match,
|
||||
+ .uevent = of_platform_uevent,
|
||||
.probe = of_platform_device_probe,
|
||||
.remove = of_platform_device_remove,
|
||||
.suspend = of_platform_device_suspend,
|
||||
--
|
||||
1.4.2
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From 733239db928c98f4d110fc33f0cf1278cf5385ef Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Mon, 18 Dec 2006 22:48:02 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc/serial: Dispose irq mapping when done in mpc52xx_serial.c
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
drivers/serial/mpc52xx_uart.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
|
||||
index 9d11a75..eef3b02 100644
|
||||
--- a/drivers/serial/mpc52xx_uart.c
|
||||
+++ b/drivers/serial/mpc52xx_uart.c
|
||||
@@ -997,6 +997,9 @@ mpc52xx_uart_of_remove(struct of_device *op)
|
||||
if (port)
|
||||
uart_remove_one_port(&mpc52xx_uart_driver, port);
|
||||
|
||||
+ if (port->irq != NO_IRQ)
|
||||
+ irq_dispose_mapping(port->irq);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
From 1dbea513815ce823ccded38d5668bbae7416223f Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Thu, 21 Dec 2006 22:21:20 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: 52xx, Don't use device_initcall to probe of_platform_bus
|
||||
|
||||
Using device_initcall makes it happen for every platform that
|
||||
compiles this file in. This is really bad, for obvious reasons.
|
||||
|
||||
Instead, we use the .init field of the machine description. If
|
||||
the platform needs the hook to do something specific it can provides
|
||||
its own function and call mpc52xx_declare_of_platform_devices from
|
||||
there. If not, the mpc52xx_declare_of_platform_devices function can
|
||||
directly be used as the init hook.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/lite5200.c | 1 +
|
||||
arch/powerpc/platforms/52xx/mpc52xx_common.c | 7 ++++---
|
||||
include/asm-powerpc/mpc52xx.h | 1 +
|
||||
3 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
index eaff71e..0f21bab 100644
|
||||
--- a/arch/powerpc/platforms/52xx/lite5200.c
|
||||
+++ b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
@@ -153,6 +153,7 @@ define_machine(lite52xx) {
|
||||
.name = "lite52xx",
|
||||
.probe = lite52xx_probe,
|
||||
.setup_arch = lite52xx_setup_arch,
|
||||
+ .init = mpc52xx_declare_of_platform_devices,
|
||||
.init_IRQ = mpc52xx_init_irq,
|
||||
.get_irq = mpc52xx_get_irq,
|
||||
.show_cpuinfo = lite52xx_show_cpuinfo,
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
|
||||
index 8331ff4..cc40889 100644
|
||||
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
|
||||
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
|
||||
@@ -116,11 +116,12 @@ unmap_regs:
|
||||
if (xlb) iounmap(xlb);
|
||||
}
|
||||
|
||||
-static int __init
|
||||
+void __init
|
||||
mpc52xx_declare_of_platform_devices(void)
|
||||
{
|
||||
/* Find every child of the SOC node and add it to of_platform */
|
||||
- return of_platform_bus_probe(NULL, NULL, NULL);
|
||||
+ if (of_platform_bus_probe(NULL, NULL, NULL))
|
||||
+ printk(KERN_ERR __FILE__ ": "
|
||||
+ "Error while probing of_platform bus\n");
|
||||
}
|
||||
|
||||
-device_initcall(mpc52xx_declare_of_platform_devices);
|
||||
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
|
||||
index 4a28a85..4560d72 100644
|
||||
--- a/include/asm-powerpc/mpc52xx.h
|
||||
+++ b/include/asm-powerpc/mpc52xx.h
|
||||
@@ -244,6 +244,7 @@ struct mpc52xx_cdm {
|
||||
extern void __iomem * mpc52xx_find_and_map(const char *);
|
||||
extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
|
||||
extern void mpc52xx_setup_cpu(void);
|
||||
+extern void mpc52xx_declare_of_platform_devices(void);
|
||||
|
||||
extern void mpc52xx_init_irq(void);
|
||||
extern unsigned int mpc52xx_get_irq(void);
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,719 +0,0 @@
|
|||
From 0ac70faf67a7e5e3f24a841ace4658336f8f98df Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:00:06 +0100
|
||||
Subject: [PATCH] Add MPC5200 serial driver
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
drivers/serial/mpc52xx_uart.c | 287 +++++++++++++++++++++++++----------------
|
||||
1 files changed, 178 insertions(+), 109 deletions(-)
|
||||
|
||||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
|
||||
index 4f80c5b..debcd7b 100644
|
||||
--- a/drivers/serial/mpc52xx_uart.c
|
||||
+++ b/drivers/serial/mpc52xx_uart.c
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
- * drivers/serial/mpc52xx_uart.c
|
||||
- *
|
||||
* Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs.
|
||||
*
|
||||
* FIXME According to the usermanual the status bits in the status register
|
||||
@@ -14,18 +12,18 @@
|
||||
*
|
||||
*
|
||||
* Maintainer : Sylvain Munaut <tnt@246tNt.com>
|
||||
- *
|
||||
+ *
|
||||
* Some of the code has been inspired/copied from the 2.4 code written
|
||||
* by Dale Farnsworth <dfarnsworth@mvista.com>.
|
||||
- *
|
||||
+ *
|
||||
* Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
|
||||
* Copyright (C) 2003 MontaVista, Software, Inc.
|
||||
- *
|
||||
+ *
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
-
|
||||
+
|
||||
/* Platform device Usage :
|
||||
*
|
||||
* Since PSCs can have multiple function, the correct driver for each one
|
||||
@@ -44,7 +42,8 @@
|
||||
* will be mapped to.
|
||||
*/
|
||||
|
||||
-#include <linux/platform_device.h>
|
||||
+#define DEBUG
|
||||
+
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/serial.h>
|
||||
@@ -53,6 +52,8 @@ #include <linux/console.h>
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/io.h>
|
||||
+#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#include <asm/mpc52xx.h>
|
||||
#include <asm/mpc52xx_psc.h>
|
||||
@@ -96,32 +97,43 @@ #else
|
||||
#define uart_console(port) (0)
|
||||
#endif
|
||||
|
||||
+static struct of_device_id mpc52xx_uart_match[] = {
|
||||
+ {
|
||||
+ .type = "serial",
|
||||
+ .compatible = "mpc52xx-psc-uart",
|
||||
+ },
|
||||
+ {
|
||||
+ .type = "serial",
|
||||
+ .compatible = "mpc5200-psc",
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
|
||||
/* ======================================================================== */
|
||||
/* UART operations */
|
||||
/* ======================================================================== */
|
||||
|
||||
-static unsigned int
|
||||
+static unsigned int
|
||||
mpc52xx_uart_tx_empty(struct uart_port *port)
|
||||
{
|
||||
int status = in_be16(&PSC(port)->mpc52xx_psc_status);
|
||||
return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
|
||||
{
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
-static unsigned int
|
||||
+static unsigned int
|
||||
mpc52xx_uart_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
/* Not implemented */
|
||||
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_uart_stop_tx(struct uart_port *port)
|
||||
{
|
||||
/* port->lock taken by caller */
|
||||
@@ -129,7 +141,7 @@ mpc52xx_uart_stop_tx(struct uart_port *p
|
||||
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_uart_start_tx(struct uart_port *port)
|
||||
{
|
||||
/* port->lock taken by caller */
|
||||
@@ -137,12 +149,12 @@ mpc52xx_uart_start_tx(struct uart_port *
|
||||
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
-
|
||||
+
|
||||
port->x_char = ch;
|
||||
if (ch) {
|
||||
/* Make sure tx interrupts are on */
|
||||
@@ -150,7 +162,7 @@ mpc52xx_uart_send_xchar(struct uart_port
|
||||
port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
|
||||
out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
|
||||
}
|
||||
-
|
||||
+
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
@@ -178,7 +190,7 @@ mpc52xx_uart_break_ctl(struct uart_port
|
||||
out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK);
|
||||
else
|
||||
out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK);
|
||||
-
|
||||
+
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
@@ -197,11 +209,11 @@ mpc52xx_uart_startup(struct uart_port *p
|
||||
/* Reset/activate the port, clear and enable interrupts */
|
||||
out_8(&psc->command,MPC52xx_PSC_RST_RX);
|
||||
out_8(&psc->command,MPC52xx_PSC_RST_TX);
|
||||
-
|
||||
+
|
||||
out_be32(&psc->sicr,0); /* UART mode DCD ignored */
|
||||
|
||||
out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */
|
||||
-
|
||||
+
|
||||
out_8(&psc->rfcntl, 0x00);
|
||||
out_be16(&psc->rfalarm, 0x1ff);
|
||||
out_8(&psc->tfcntl, 0x07);
|
||||
@@ -209,10 +221,10 @@ mpc52xx_uart_startup(struct uart_port *p
|
||||
|
||||
port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
|
||||
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
|
||||
-
|
||||
+
|
||||
out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
|
||||
out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
|
||||
-
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -220,19 +232,19 @@ static void
|
||||
mpc52xx_uart_shutdown(struct uart_port *port)
|
||||
{
|
||||
struct mpc52xx_psc __iomem *psc = PSC(port);
|
||||
-
|
||||
+
|
||||
/* Shut down the port, interrupt and all */
|
||||
out_8(&psc->command,MPC52xx_PSC_RST_RX);
|
||||
out_8(&psc->command,MPC52xx_PSC_RST_TX);
|
||||
-
|
||||
- port->read_status_mask = 0;
|
||||
+
|
||||
+ port->read_status_mask = 0;
|
||||
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
|
||||
|
||||
/* Release interrupt */
|
||||
free_irq(port->irq, port);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
|
||||
struct termios *old)
|
||||
{
|
||||
@@ -241,10 +253,10 @@ mpc52xx_uart_set_termios(struct uart_por
|
||||
unsigned char mr1, mr2;
|
||||
unsigned short ctr;
|
||||
unsigned int j, baud, quot;
|
||||
-
|
||||
+
|
||||
/* Prepare what we're gonna write */
|
||||
mr1 = 0;
|
||||
-
|
||||
+
|
||||
switch (new->c_cflag & CSIZE) {
|
||||
case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS;
|
||||
break;
|
||||
@@ -261,8 +273,8 @@ mpc52xx_uart_set_termios(struct uart_por
|
||||
MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN;
|
||||
} else
|
||||
mr1 |= MPC52xx_PSC_MODE_PARNONE;
|
||||
-
|
||||
-
|
||||
+
|
||||
+
|
||||
mr2 = 0;
|
||||
|
||||
if (new->c_cflag & CSTOPB)
|
||||
@@ -276,7 +288,7 @@ mpc52xx_uart_set_termios(struct uart_por
|
||||
baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
|
||||
quot = uart_get_divisor(port, baud);
|
||||
ctr = quot & 0xffff;
|
||||
-
|
||||
+
|
||||
/* Get the lock */
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
@@ -290,14 +302,14 @@ mpc52xx_uart_set_termios(struct uart_por
|
||||
* boot for the console, all stuff is not yet ready to receive at that
|
||||
* time and that just makes the kernel oops */
|
||||
/* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
|
||||
- while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
|
||||
+ while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
|
||||
--j)
|
||||
udelay(1);
|
||||
|
||||
if (!j)
|
||||
printk( KERN_ERR "mpc52xx_uart.c: "
|
||||
"Unable to flush RX & TX fifos in-time in set_termios."
|
||||
- "Some chars may have been lost.\n" );
|
||||
+ "Some chars may have been lost.\n" );
|
||||
|
||||
/* Reset the TX & RX */
|
||||
out_8(&psc->command,MPC52xx_PSC_RST_RX);
|
||||
@@ -309,7 +321,7 @@ mpc52xx_uart_set_termios(struct uart_por
|
||||
out_8(&psc->mode,mr2);
|
||||
out_8(&psc->ctur,ctr >> 8);
|
||||
out_8(&psc->ctlr,ctr & 0xff);
|
||||
-
|
||||
+
|
||||
/* Reenable TX & RX */
|
||||
out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
|
||||
out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
|
||||
@@ -332,7 +344,7 @@ mpc52xx_uart_release_port(struct uart_po
|
||||
port->membase = NULL;
|
||||
}
|
||||
|
||||
- release_mem_region(port->mapbase, MPC52xx_PSC_SIZE);
|
||||
+ release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -341,12 +353,13 @@ mpc52xx_uart_request_port(struct uart_po
|
||||
int err;
|
||||
|
||||
if (port->flags & UPF_IOREMAP) /* Need to remap ? */
|
||||
- port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
|
||||
+ port->membase = ioremap(port->mapbase,
|
||||
+ sizeof(struct mpc52xx_psc));
|
||||
|
||||
if (!port->membase)
|
||||
return -EINVAL;
|
||||
|
||||
- err = request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
|
||||
+ err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc),
|
||||
"mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
|
||||
|
||||
if (err && (port->flags & UPF_IOREMAP)) {
|
||||
@@ -373,7 +386,7 @@ mpc52xx_uart_verify_port(struct uart_por
|
||||
|
||||
if ( (ser->irq != port->irq) ||
|
||||
(ser->io_type != SERIAL_IO_MEM) ||
|
||||
- (ser->baud_base != port->uartclk) ||
|
||||
+ (ser->baud_base != port->uartclk) ||
|
||||
(ser->iomem_base != (void*)port->mapbase) ||
|
||||
(ser->hub6 != 0 ) )
|
||||
return -EINVAL;
|
||||
@@ -404,11 +417,11 @@ static struct uart_ops mpc52xx_uart_ops
|
||||
.verify_port = mpc52xx_uart_verify_port
|
||||
};
|
||||
|
||||
-
|
||||
+
|
||||
/* ======================================================================== */
|
||||
/* Interrupt handling */
|
||||
/* ======================================================================== */
|
||||
-
|
||||
+
|
||||
static inline int
|
||||
mpc52xx_uart_int_rx_chars(struct uart_port *port)
|
||||
{
|
||||
@@ -435,11 +448,11 @@ #endif
|
||||
|
||||
flag = TTY_NORMAL;
|
||||
port->icount.rx++;
|
||||
-
|
||||
+
|
||||
if ( status & (MPC52xx_PSC_SR_PE |
|
||||
MPC52xx_PSC_SR_FE |
|
||||
MPC52xx_PSC_SR_RB) ) {
|
||||
-
|
||||
+
|
||||
if (status & MPC52xx_PSC_SR_RB) {
|
||||
flag = TTY_BREAK;
|
||||
uart_handle_break(port);
|
||||
@@ -464,7 +477,7 @@ #endif
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(tty);
|
||||
-
|
||||
+
|
||||
return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY;
|
||||
}
|
||||
|
||||
@@ -509,25 +522,25 @@ mpc52xx_uart_int_tx_chars(struct uart_po
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static irqreturn_t
|
||||
+static irqreturn_t
|
||||
mpc52xx_uart_int(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
unsigned long pass = ISR_PASS_LIMIT;
|
||||
unsigned int keepgoing;
|
||||
unsigned short status;
|
||||
-
|
||||
+
|
||||
spin_lock(&port->lock);
|
||||
-
|
||||
+
|
||||
/* While we have stuff to do, we continue */
|
||||
do {
|
||||
/* If we don't find anything to do, we stop */
|
||||
- keepgoing = 0;
|
||||
-
|
||||
+ keepgoing = 0;
|
||||
+
|
||||
/* Read status */
|
||||
status = in_be16(&PSC(port)->mpc52xx_psc_isr);
|
||||
status &= port->read_status_mask;
|
||||
-
|
||||
+
|
||||
/* Do we need to receive chars ? */
|
||||
/* For this RX interrupts must be on and some chars waiting */
|
||||
if ( status & MPC52xx_PSC_IMR_RXRDY )
|
||||
@@ -537,15 +550,15 @@ mpc52xx_uart_int(int irq, void *dev_id)
|
||||
/* For this, TX must be ready and TX interrupt enabled */
|
||||
if ( status & MPC52xx_PSC_IMR_TXRDY )
|
||||
keepgoing |= mpc52xx_uart_int_tx_chars(port);
|
||||
-
|
||||
+
|
||||
/* Limit number of iteration */
|
||||
if ( !(--pass) )
|
||||
keepgoing = 0;
|
||||
|
||||
} while (keepgoing);
|
||||
-
|
||||
+
|
||||
spin_unlock(&port->lock);
|
||||
-
|
||||
+
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -563,13 +576,13 @@ mpc52xx_console_get_options(struct uart_
|
||||
struct mpc52xx_psc __iomem *psc = PSC(port);
|
||||
unsigned char mr1;
|
||||
|
||||
+ pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
|
||||
/* Read the mode registers */
|
||||
out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
|
||||
mr1 = in_8(&psc->mode);
|
||||
-
|
||||
+
|
||||
/* CT{U,L}R are write-only ! */
|
||||
- *baud = __res.bi_baudrate ?
|
||||
- __res.bi_baudrate : CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
|
||||
+ *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
|
||||
|
||||
/* Parse them */
|
||||
switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
|
||||
@@ -579,26 +592,26 @@ mpc52xx_console_get_options(struct uart_
|
||||
case MPC52xx_PSC_MODE_8_BITS:
|
||||
default: *bits = 8;
|
||||
}
|
||||
-
|
||||
+
|
||||
if (mr1 & MPC52xx_PSC_MODE_PARNONE)
|
||||
*parity = 'n';
|
||||
else
|
||||
*parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e';
|
||||
}
|
||||
|
||||
-static void
|
||||
+static void
|
||||
mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
|
||||
{
|
||||
struct uart_port *port = &mpc52xx_uart_ports[co->index];
|
||||
struct mpc52xx_psc __iomem *psc = PSC(port);
|
||||
unsigned int i, j;
|
||||
-
|
||||
+
|
||||
/* Disable interrupts */
|
||||
out_be16(&psc->mpc52xx_psc_imr, 0);
|
||||
|
||||
/* Wait the TX buffer to be empty */
|
||||
- j = 5000000; /* Maximum wait */
|
||||
- while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
|
||||
+ j = 5000000; /* Maximum wait */
|
||||
+ while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
|
||||
--j)
|
||||
udelay(1);
|
||||
|
||||
@@ -606,14 +619,14 @@ mpc52xx_console_write(struct console *co
|
||||
for (i = 0; i < count; i++, s++) {
|
||||
/* Line return handling */
|
||||
if (*s == '\n')
|
||||
- out_8(&psc->mpc52xx_psc_buffer_8, '\r');
|
||||
-
|
||||
+ out_8(&psc->buffer.buffer_8, '\r');
|
||||
+
|
||||
/* Send the char */
|
||||
- out_8(&psc->mpc52xx_psc_buffer_8, *s);
|
||||
+ out_8(&psc->buffer.buffer_8, *s);
|
||||
|
||||
/* Wait the TX buffer to be empty */
|
||||
- j = 20000; /* Maximum wait */
|
||||
- while (!(in_be16(&psc->mpc52xx_psc_status) &
|
||||
+ j = 20000; /* Maximum wait */
|
||||
+ while (!(in_be16(&psc->mpc52xx_psc_status) &
|
||||
MPC52xx_PSC_SR_TXEMP) && --j)
|
||||
udelay(1);
|
||||
}
|
||||
@@ -626,33 +639,77 @@ static int __init
|
||||
mpc52xx_console_setup(struct console *co, char *options)
|
||||
{
|
||||
struct uart_port *port = &mpc52xx_uart_ports[co->index];
|
||||
+ struct device_node *np = NULL;
|
||||
+ const struct of_device_id *dev_id = NULL;
|
||||
+ struct device_node *np_idx;
|
||||
+ const void *pp = NULL;
|
||||
+ struct resource res;
|
||||
+ int index = 0;
|
||||
+ int ret;
|
||||
|
||||
int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
|
||||
int bits = 8;
|
||||
int parity = 'n';
|
||||
int flow = 'n';
|
||||
|
||||
- if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM)
|
||||
+ pr_debug("mpc52xx_console_setup co=%p, options=%s, index=%i\n",
|
||||
+ co, options, co->index);
|
||||
+
|
||||
+ for_each_node_by_type(np, "serial")
|
||||
+ {
|
||||
+ dev_id = of_match_node(mpc52xx_uart_match, np);
|
||||
+ if (dev_id)
|
||||
+ if (index++ == co->index)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!np) {
|
||||
+ pr_debug("PSC%x not found in device tree\n", co->index);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Fetch register locations */
|
||||
+ if ((ret = of_address_to_resource(np, 0, &res)) != 0) {
|
||||
+ pr_debug("Could not get resources for PSC%x\n", index);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Search for bus-frequency property in this node or a parent */
|
||||
+ np_idx = np;
|
||||
+ while (np_idx) {
|
||||
+ if ((pp = get_property(np_idx, "bus-frequency", NULL)) != NULL)
|
||||
+ break;
|
||||
+ np_idx = of_get_parent(np_idx);
|
||||
+ }
|
||||
+ if (!pp) {
|
||||
+ pr_debug("Could not find bus-frequency property!\n");
|
||||
return -EINVAL;
|
||||
-
|
||||
+ }
|
||||
+
|
||||
/* Basic port init. Needed since we use some uart_??? func before
|
||||
* real init for early access */
|
||||
spin_lock_init(&port->lock);
|
||||
- port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
|
||||
+ port->uartclk = *(const u32*)pp / 2;
|
||||
port->ops = &mpc52xx_uart_ops;
|
||||
- port->mapbase = MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1));
|
||||
+ port->mapbase = res.start;
|
||||
+ port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
|
||||
+ port->irq = irq_of_parse_and_map(np, 0);
|
||||
|
||||
- /* We ioremap ourself */
|
||||
- port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
|
||||
if (port->membase == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
+ pr_debug("mpc52xx_psc at %lx mapped to %p; irq=%x freq=%i\n",
|
||||
+ port->mapbase, port->membase, port->irq, port->uartclk);
|
||||
+
|
||||
/* Setup the port parameters accoding to options */
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
else
|
||||
mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
|
||||
|
||||
+ pr_debug("Setting console parameters: %i %i%c1 flow=%c\n",
|
||||
+ baud, bits, parity, flow);
|
||||
+
|
||||
return uart_set_options(port, co, baud, parity, bits, flow);
|
||||
}
|
||||
|
||||
@@ -669,8 +726,8 @@ static struct console mpc52xx_console =
|
||||
.data = &mpc52xx_uart_driver,
|
||||
};
|
||||
|
||||
-
|
||||
-static int __init
|
||||
+
|
||||
+static int __init
|
||||
mpc52xx_console_init(void)
|
||||
{
|
||||
register_console(&mpc52xx_console);
|
||||
@@ -705,28 +762,23 @@ static struct uart_driver mpc52xx_uart_d
|
||||
/* ======================================================================== */
|
||||
|
||||
static int __devinit
|
||||
-mpc52xx_uart_probe(struct platform_device *dev)
|
||||
+mpc52xx_uart_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
- struct resource *res = dev->resource;
|
||||
-
|
||||
+ static int idx = 0;
|
||||
struct uart_port *port = NULL;
|
||||
- int i, idx, ret;
|
||||
+ struct resource res;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match);
|
||||
|
||||
/* Check validity & presence */
|
||||
- idx = dev->id;
|
||||
- if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
|
||||
+ if (idx >= MPC52xx_PSC_MAXNUM)
|
||||
return -EINVAL;
|
||||
|
||||
- if (!mpc52xx_match_psc_function(idx,"uart"))
|
||||
- return -ENODEV;
|
||||
-
|
||||
/* Init the port structure */
|
||||
port = &mpc52xx_uart_ports[idx];
|
||||
|
||||
- memset(port, 0x00, sizeof(struct uart_port));
|
||||
-
|
||||
spin_lock_init(&port->lock);
|
||||
- port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
|
||||
port->fifosize = 512;
|
||||
port->iotype = UPIO_MEM;
|
||||
port->flags = UPF_BOOT_AUTOCONF |
|
||||
@@ -735,29 +787,36 @@ mpc52xx_uart_probe(struct platform_devic
|
||||
port->ops = &mpc52xx_uart_ops;
|
||||
|
||||
/* Search for IRQ and mapbase */
|
||||
- for (i=0 ; i<dev->num_resources ; i++, res++) {
|
||||
- if (res->flags & IORESOURCE_MEM)
|
||||
- port->mapbase = res->start;
|
||||
- else if (res->flags & IORESOURCE_IRQ)
|
||||
- port->irq = res->start;
|
||||
- }
|
||||
- if (!port->irq || !port->mapbase)
|
||||
+ if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ port->mapbase = res.start;
|
||||
+ port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
|
||||
+ port->irq = irq_of_parse_and_map(op->node, 0);
|
||||
+
|
||||
+ dev_dbg(&op->dev, "mpc52xx-psc UART at %lx. mapped to %p, irq %x\n",
|
||||
+ port->mapbase, port->membase, port->irq);
|
||||
+
|
||||
+ //if (!port->irq || !port->mapbase) {
|
||||
+ if (!port->mapbase) {
|
||||
+ printk(KERN_ERR "Could not allocate resources for PSC\n");
|
||||
return -EINVAL;
|
||||
+ }
|
||||
|
||||
/* Add the port to the uart sub-system */
|
||||
ret = uart_add_one_port(&mpc52xx_uart_driver, port);
|
||||
if (!ret)
|
||||
- platform_set_drvdata(dev, (void*)port);
|
||||
+ dev_set_drvdata(&op->dev, (void*)port);
|
||||
|
||||
+ idx++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
-mpc52xx_uart_remove(struct platform_device *dev)
|
||||
+mpc52xx_uart_remove(struct of_device *op)
|
||||
{
|
||||
- struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
|
||||
-
|
||||
- platform_set_drvdata(dev, NULL);
|
||||
+ struct uart_port *port = dev_get_drvdata(&op->dev);
|
||||
+ dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
if (port)
|
||||
uart_remove_one_port(&mpc52xx_uart_driver, port);
|
||||
@@ -767,20 +826,20 @@ mpc52xx_uart_remove(struct platform_devi
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int
|
||||
-mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
|
||||
+mpc52xx_uart_suspend(struct of_device *op, pm_message_t state)
|
||||
{
|
||||
- struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
|
||||
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
|
||||
|
||||
- if (sport)
|
||||
+ if (port)
|
||||
uart_suspend_port(&mpc52xx_uart_driver, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
-mpc52xx_uart_resume(struct platform_device *dev)
|
||||
+mpc52xx_uart_resume(struct of_device *op)
|
||||
{
|
||||
- struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
|
||||
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
|
||||
|
||||
if (port)
|
||||
uart_resume_port(&mpc52xx_uart_driver, port);
|
||||
@@ -789,7 +848,13 @@ mpc52xx_uart_resume(struct platform_devi
|
||||
}
|
||||
#endif
|
||||
|
||||
-static struct platform_driver mpc52xx_uart_platform_driver = {
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, mpc52xx_uart_match);
|
||||
+
|
||||
+static struct of_platform_driver mpc52xx_uart_of_driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "mpc52xx-uart",
|
||||
+ .match_table = mpc52xx_uart_match,
|
||||
.probe = mpc52xx_uart_probe,
|
||||
.remove = mpc52xx_uart_remove,
|
||||
#ifdef CONFIG_PM
|
||||
@@ -804,7 +869,7 @@ #endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Module */
|
||||
-/* ======================================================================== */
|
||||
+ /* ======================================================================== */
|
||||
|
||||
static int __init
|
||||
mpc52xx_uart_init(void)
|
||||
@@ -813,20 +878,24 @@ mpc52xx_uart_init(void)
|
||||
|
||||
printk(KERN_INFO "Serial: MPC52xx PSC driver\n");
|
||||
|
||||
- ret = uart_register_driver(&mpc52xx_uart_driver);
|
||||
- if (ret == 0) {
|
||||
- ret = platform_driver_register(&mpc52xx_uart_platform_driver);
|
||||
- if (ret)
|
||||
- uart_unregister_driver(&mpc52xx_uart_driver);
|
||||
+ if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {
|
||||
+ printk(KERN_ERR "Could not register mpc52xx uart driver\n");
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ if ((ret = of_register_platform_driver(&mpc52xx_uart_of_driver)) != 0) {
|
||||
+ printk(KERN_ERR "Could not register mpc52xx of driver\n");
|
||||
+ uart_unregister_driver(&mpc52xx_uart_driver);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
mpc52xx_uart_exit(void)
|
||||
{
|
||||
- platform_driver_unregister(&mpc52xx_uart_platform_driver);
|
||||
+ of_unregister_platform_driver(&mpc52xx_uart_of_driver);
|
||||
uart_unregister_driver(&mpc52xx_uart_driver);
|
||||
}
|
||||
|
||||
--
|
||||
1.4.3.2
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
From ae911446f91481cf26e6dc5edef034a50a6c410c Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 20:33:30 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Use common 52xx of_platform probe code for EFIKA
|
||||
|
||||
Now that the device tree has the good properties, we can
|
||||
remove all the efika_init code by a single call to common code.
|
||||
|
||||
While we're modifying that file, a few whitespaces/alignement/typo
|
||||
fixes are made (nothing significant).
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/efika-setup.c | 64 ++++++++---------------------
|
||||
1 files changed, 18 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/efika-setup.c b/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
index 110c980..d61ce84 100644
|
||||
--- a/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
+++ b/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* Efika 5K2 platform setup
|
||||
* Some code really inspired from the lite5200b platform.
|
||||
- *
|
||||
+ *
|
||||
* Copyright (C) 2006 bplan GmbH
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
@@ -81,35 +81,7 @@ static void __init efika_setup_arch(void)
|
||||
efika_pcisetup();
|
||||
|
||||
if (ppc_md.progress)
|
||||
- ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0);
|
||||
-}
|
||||
-
|
||||
-static void __init efika_init(void)
|
||||
-{
|
||||
- struct device_node *np;
|
||||
- struct device_node *cnp = NULL;
|
||||
- const u32 *base;
|
||||
-
|
||||
- /* Find every child of the SOC node and add it to of_platform */
|
||||
- np = of_find_node_by_name(NULL, "builtin");
|
||||
- if (np) {
|
||||
- char name[BUS_ID_SIZE];
|
||||
- while ((cnp = of_get_next_child(np, cnp))) {
|
||||
- strcpy(name, cnp->name);
|
||||
-
|
||||
- base = get_property(cnp, "reg", NULL);
|
||||
- if (base == NULL)
|
||||
- continue;
|
||||
-
|
||||
- snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base);
|
||||
- of_platform_device_create(cnp, name, NULL);
|
||||
-
|
||||
- printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (ppc_md.progress)
|
||||
- ppc_md.progress(" Have fun with your Efika! ", 0x7777);
|
||||
+ ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0);
|
||||
}
|
||||
|
||||
static int __init efika_probe(void)
|
||||
@@ -131,20 +103,20 @@ static int __init efika_probe(void)
|
||||
|
||||
define_machine(efika)
|
||||
{
|
||||
- .name = EFIKA_PLATFORM_NAME,
|
||||
- .probe = efika_probe,
|
||||
- .setup_arch = efika_setup_arch,
|
||||
- .init = efika_init,
|
||||
- .show_cpuinfo = efika_show_cpuinfo,
|
||||
- .init_IRQ = mpc52xx_init_irq,
|
||||
- .get_irq = mpc52xx_get_irq,
|
||||
- .restart = rtas_restart,
|
||||
- .power_off = rtas_power_off,
|
||||
- .halt = rtas_halt,
|
||||
- .set_rtc_time = rtas_set_rtc_time,
|
||||
- .get_rtc_time = rtas_get_rtc_time,
|
||||
- .progress = rtas_progress,
|
||||
- .get_boot_time = rtas_get_boot_time,
|
||||
- .calibrate_decr = generic_calibrate_decr,
|
||||
- .phys_mem_access_prot = pci_phys_mem_access_prot,
|
||||
+ .name = EFIKA_PLATFORM_NAME,
|
||||
+ .probe = efika_probe,
|
||||
+ .setup_arch = efika_setup_arch,
|
||||
+ .init = mpc52xx_declare_of_platform_devices,
|
||||
+ .show_cpuinfo = efika_show_cpuinfo,
|
||||
+ .init_IRQ = mpc52xx_init_irq,
|
||||
+ .get_irq = mpc52xx_get_irq,
|
||||
+ .restart = rtas_restart,
|
||||
+ .power_off = rtas_power_off,
|
||||
+ .halt = rtas_halt,
|
||||
+ .set_rtc_time = rtas_set_rtc_time,
|
||||
+ .get_rtc_time = rtas_get_rtc_time,
|
||||
+ .progress = rtas_progress,
|
||||
+ .get_boot_time = rtas_get_boot_time,
|
||||
+ .calibrate_decr = generic_calibrate_decr,
|
||||
+ .phys_mem_access_prot = pci_phys_mem_access_prot,
|
||||
};
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,306 +0,0 @@
|
|||
From e63b95820892f44ac7eec431900378763a83ae9d Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:05:34 +0100
|
||||
Subject: [PATCH] Add MPC5200 specific header
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
include/asm-powerpc/mpc52xx.h | 287 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 287 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
|
||||
new file mode 100644
|
||||
index 0000000..e9aa622
|
||||
--- /dev/null
|
||||
+++ b/include/asm-powerpc/mpc52xx.h
|
||||
@@ -0,0 +1,287 @@
|
||||
+/*
|
||||
+ * Prototypes, etc. for the Freescale MPC52xx embedded cpu chips
|
||||
+ * May need to be cleaned as the port goes on ...
|
||||
+ *
|
||||
+ * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ * Copyright (C) 2003 MontaVista, Software, Inc.
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_POWERPC_MPC52xx_H__
|
||||
+#define __ASM_POWERPC_MPC52xx_H__
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+#include <asm/types.h>
|
||||
+#include <asm/prom.h>
|
||||
+#endif /* __ASSEMBLY__ */
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* HW IRQ mapping */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_IRQ_L1_CRIT (0)
|
||||
+#define MPC52xx_IRQ_L1_MAIN (1)
|
||||
+#define MPC52xx_IRQ_L1_PERP (2)
|
||||
+#define MPC52xx_IRQ_L1_SDMA (3)
|
||||
+
|
||||
+#define MPC52xx_IRQ_L1_OFFSET (6)
|
||||
+#define MPC52xx_IRQ_L1_MASK (0xc0)
|
||||
+
|
||||
+#define MPC52xx_IRQ_L2_OFFSET (0)
|
||||
+#define MPC52xx_IRQ_L2_MASK (0x3f)
|
||||
+
|
||||
+#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Structures mapping of some unit register set */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
+/* Interrupt controller Register set */
|
||||
+struct mpc52xx_intr {
|
||||
+ u32 per_mask; /* INTR + 0x00 */
|
||||
+ u32 per_pri1; /* INTR + 0x04 */
|
||||
+ u32 per_pri2; /* INTR + 0x08 */
|
||||
+ u32 per_pri3; /* INTR + 0x0c */
|
||||
+ u32 ctrl; /* INTR + 0x10 */
|
||||
+ u32 main_mask; /* INTR + 0x14 */
|
||||
+ u32 main_pri1; /* INTR + 0x18 */
|
||||
+ u32 main_pri2; /* INTR + 0x1c */
|
||||
+ u32 reserved1; /* INTR + 0x20 */
|
||||
+ u32 enc_status; /* INTR + 0x24 */
|
||||
+ u32 crit_status; /* INTR + 0x28 */
|
||||
+ u32 main_status; /* INTR + 0x2c */
|
||||
+ u32 per_status; /* INTR + 0x30 */
|
||||
+ u32 reserved2; /* INTR + 0x34 */
|
||||
+ u32 per_error; /* INTR + 0x38 */
|
||||
+};
|
||||
+
|
||||
+/* Memory Mapping Control */
|
||||
+struct mpc52xx_mmap_ctl {
|
||||
+ u32 mbar; /* MMAP_CTRL + 0x00 */
|
||||
+
|
||||
+ u32 cs0_start; /* MMAP_CTRL + 0x04 */
|
||||
+ u32 cs0_stop; /* MMAP_CTRL + 0x08 */
|
||||
+ u32 cs1_start; /* MMAP_CTRL + 0x0c */
|
||||
+ u32 cs1_stop; /* MMAP_CTRL + 0x10 */
|
||||
+ u32 cs2_start; /* MMAP_CTRL + 0x14 */
|
||||
+ u32 cs2_stop; /* MMAP_CTRL + 0x18 */
|
||||
+ u32 cs3_start; /* MMAP_CTRL + 0x1c */
|
||||
+ u32 cs3_stop; /* MMAP_CTRL + 0x20 */
|
||||
+ u32 cs4_start; /* MMAP_CTRL + 0x24 */
|
||||
+ u32 cs4_stop; /* MMAP_CTRL + 0x28 */
|
||||
+ u32 cs5_start; /* MMAP_CTRL + 0x2c */
|
||||
+ u32 cs5_stop; /* MMAP_CTRL + 0x30 */
|
||||
+
|
||||
+ u32 sdram0; /* MMAP_CTRL + 0x34 */
|
||||
+ u32 sdram1; /* MMAP_CTRL + 0X38 */
|
||||
+
|
||||
+ u32 reserved[4]; /* MMAP_CTRL + 0x3c .. 0x48 */
|
||||
+
|
||||
+ u32 boot_start; /* MMAP_CTRL + 0x4c */
|
||||
+ u32 boot_stop; /* MMAP_CTRL + 0x50 */
|
||||
+
|
||||
+ u32 ipbi_ws_ctrl; /* MMAP_CTRL + 0x54 */
|
||||
+
|
||||
+ u32 cs6_start; /* MMAP_CTRL + 0x58 */
|
||||
+ u32 cs6_stop; /* MMAP_CTRL + 0x5c */
|
||||
+ u32 cs7_start; /* MMAP_CTRL + 0x60 */
|
||||
+ u32 cs7_stop; /* MMAP_CTRL + 0x64 */
|
||||
+};
|
||||
+
|
||||
+/* SDRAM control */
|
||||
+struct mpc52xx_sdram {
|
||||
+ u32 mode; /* SDRAM + 0x00 */
|
||||
+ u32 ctrl; /* SDRAM + 0x04 */
|
||||
+ u32 config1; /* SDRAM + 0x08 */
|
||||
+ u32 config2; /* SDRAM + 0x0c */
|
||||
+};
|
||||
+
|
||||
+/* SDMA */
|
||||
+struct mpc52xx_sdma {
|
||||
+ u32 taskBar; /* SDMA + 0x00 */
|
||||
+ u32 currentPointer; /* SDMA + 0x04 */
|
||||
+ u32 endPointer; /* SDMA + 0x08 */
|
||||
+ u32 variablePointer; /* SDMA + 0x0c */
|
||||
+
|
||||
+ u8 IntVect1; /* SDMA + 0x10 */
|
||||
+ u8 IntVect2; /* SDMA + 0x11 */
|
||||
+ u16 PtdCntrl; /* SDMA + 0x12 */
|
||||
+
|
||||
+ u32 IntPend; /* SDMA + 0x14 */
|
||||
+ u32 IntMask; /* SDMA + 0x18 */
|
||||
+
|
||||
+ u16 tcr[16]; /* SDMA + 0x1c .. 0x3a */
|
||||
+
|
||||
+ u8 ipr[32]; /* SDMA + 0x3c .. 0x5b */
|
||||
+
|
||||
+ u32 cReqSelect; /* SDMA + 0x5c */
|
||||
+ u32 task_size0; /* SDMA + 0x60 */
|
||||
+ u32 task_size1; /* SDMA + 0x64 */
|
||||
+ u32 MDEDebug; /* SDMA + 0x68 */
|
||||
+ u32 ADSDebug; /* SDMA + 0x6c */
|
||||
+ u32 Value1; /* SDMA + 0x70 */
|
||||
+ u32 Value2; /* SDMA + 0x74 */
|
||||
+ u32 Control; /* SDMA + 0x78 */
|
||||
+ u32 Status; /* SDMA + 0x7c */
|
||||
+ u32 PTDDebug; /* SDMA + 0x80 */
|
||||
+};
|
||||
+
|
||||
+/* GPT */
|
||||
+struct mpc52xx_gpt {
|
||||
+ u32 mode; /* GPTx + 0x00 */
|
||||
+ u32 count; /* GPTx + 0x04 */
|
||||
+ u32 pwm; /* GPTx + 0x08 */
|
||||
+ u32 status; /* GPTx + 0X0c */
|
||||
+};
|
||||
+
|
||||
+/* GPIO */
|
||||
+struct mpc52xx_gpio {
|
||||
+ u32 port_config; /* GPIO + 0x00 */
|
||||
+ u32 simple_gpioe; /* GPIO + 0x04 */
|
||||
+ u32 simple_ode; /* GPIO + 0x08 */
|
||||
+ u32 simple_ddr; /* GPIO + 0x0c */
|
||||
+ u32 simple_dvo; /* GPIO + 0x10 */
|
||||
+ u32 simple_ival; /* GPIO + 0x14 */
|
||||
+ u8 outo_gpioe; /* GPIO + 0x18 */
|
||||
+ u8 reserved1[3]; /* GPIO + 0x19 */
|
||||
+ u8 outo_dvo; /* GPIO + 0x1c */
|
||||
+ u8 reserved2[3]; /* GPIO + 0x1d */
|
||||
+ u8 sint_gpioe; /* GPIO + 0x20 */
|
||||
+ u8 reserved3[3]; /* GPIO + 0x21 */
|
||||
+ u8 sint_ode; /* GPIO + 0x24 */
|
||||
+ u8 reserved4[3]; /* GPIO + 0x25 */
|
||||
+ u8 sint_ddr; /* GPIO + 0x28 */
|
||||
+ u8 reserved5[3]; /* GPIO + 0x29 */
|
||||
+ u8 sint_dvo; /* GPIO + 0x2c */
|
||||
+ u8 reserved6[3]; /* GPIO + 0x2d */
|
||||
+ u8 sint_inten; /* GPIO + 0x30 */
|
||||
+ u8 reserved7[3]; /* GPIO + 0x31 */
|
||||
+ u16 sint_itype; /* GPIO + 0x34 */
|
||||
+ u16 reserved8; /* GPIO + 0x36 */
|
||||
+ u8 gpio_control; /* GPIO + 0x38 */
|
||||
+ u8 reserved9[3]; /* GPIO + 0x39 */
|
||||
+ u8 sint_istat; /* GPIO + 0x3c */
|
||||
+ u8 sint_ival; /* GPIO + 0x3d */
|
||||
+ u8 bus_errs; /* GPIO + 0x3e */
|
||||
+ u8 reserved10; /* GPIO + 0x3f */
|
||||
+};
|
||||
+
|
||||
+#define MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD 4
|
||||
+#define MPC52xx_GPIO_PSC_CONFIG_UART_WITH_CD 5
|
||||
+#define MPC52xx_GPIO_PCI_DIS (1<<15)
|
||||
+
|
||||
+/* GPIO with WakeUp*/
|
||||
+struct mpc52xx_gpio_wkup {
|
||||
+ u8 wkup_gpioe; /* GPIO_WKUP + 0x00 */
|
||||
+ u8 reserved1[3]; /* GPIO_WKUP + 0x03 */
|
||||
+ u8 wkup_ode; /* GPIO_WKUP + 0x04 */
|
||||
+ u8 reserved2[3]; /* GPIO_WKUP + 0x05 */
|
||||
+ u8 wkup_ddr; /* GPIO_WKUP + 0x08 */
|
||||
+ u8 reserved3[3]; /* GPIO_WKUP + 0x09 */
|
||||
+ u8 wkup_dvo; /* GPIO_WKUP + 0x0C */
|
||||
+ u8 reserved4[3]; /* GPIO_WKUP + 0x0D */
|
||||
+ u8 wkup_inten; /* GPIO_WKUP + 0x10 */
|
||||
+ u8 reserved5[3]; /* GPIO_WKUP + 0x11 */
|
||||
+ u8 wkup_iinten; /* GPIO_WKUP + 0x14 */
|
||||
+ u8 reserved6[3]; /* GPIO_WKUP + 0x15 */
|
||||
+ u16 wkup_itype; /* GPIO_WKUP + 0x18 */
|
||||
+ u8 reserved7[2]; /* GPIO_WKUP + 0x1A */
|
||||
+ u8 wkup_maste; /* GPIO_WKUP + 0x1C */
|
||||
+ u8 reserved8[3]; /* GPIO_WKUP + 0x1D */
|
||||
+ u8 wkup_ival; /* GPIO_WKUP + 0x20 */
|
||||
+ u8 reserved9[3]; /* GPIO_WKUP + 0x21 */
|
||||
+ u8 wkup_istat; /* GPIO_WKUP + 0x24 */
|
||||
+ u8 reserved10[3]; /* GPIO_WKUP + 0x25 */
|
||||
+};
|
||||
+
|
||||
+/* XLB Bus control */
|
||||
+struct mpc52xx_xlb {
|
||||
+ u8 reserved[0x40];
|
||||
+ u32 config; /* XLB + 0x40 */
|
||||
+ u32 version; /* XLB + 0x44 */
|
||||
+ u32 status; /* XLB + 0x48 */
|
||||
+ u32 int_enable; /* XLB + 0x4c */
|
||||
+ u32 addr_capture; /* XLB + 0x50 */
|
||||
+ u32 bus_sig_capture; /* XLB + 0x54 */
|
||||
+ u32 addr_timeout; /* XLB + 0x58 */
|
||||
+ u32 data_timeout; /* XLB + 0x5c */
|
||||
+ u32 bus_act_timeout; /* XLB + 0x60 */
|
||||
+ u32 master_pri_enable; /* XLB + 0x64 */
|
||||
+ u32 master_priority; /* XLB + 0x68 */
|
||||
+ u32 base_address; /* XLB + 0x6c */
|
||||
+ u32 snoop_window; /* XLB + 0x70 */
|
||||
+};
|
||||
+
|
||||
+#define MPC52xx_XLB_CFG_PLDIS (1 << 31)
|
||||
+#define MPC52xx_XLB_CFG_SNOOP (1 << 15)
|
||||
+
|
||||
+/* Clock Distribution control */
|
||||
+struct mpc52xx_cdm {
|
||||
+ u32 jtag_id; /* CDM + 0x00 reg0 read only */
|
||||
+ u32 rstcfg; /* CDM + 0x04 reg1 read only */
|
||||
+ u32 breadcrumb; /* CDM + 0x08 reg2 */
|
||||
+
|
||||
+ u8 mem_clk_sel; /* CDM + 0x0c reg3 byte0 */
|
||||
+ u8 xlb_clk_sel; /* CDM + 0x0d reg3 byte1 read only */
|
||||
+ u8 ipb_clk_sel; /* CDM + 0x0e reg3 byte2 */
|
||||
+ u8 pci_clk_sel; /* CDM + 0x0f reg3 byte3 */
|
||||
+
|
||||
+ u8 ext_48mhz_en; /* CDM + 0x10 reg4 byte0 */
|
||||
+ u8 fd_enable; /* CDM + 0x11 reg4 byte1 */
|
||||
+ u16 fd_counters; /* CDM + 0x12 reg4 byte2,3 */
|
||||
+
|
||||
+ u32 clk_enables; /* CDM + 0x14 reg5 */
|
||||
+
|
||||
+ u8 osc_disable; /* CDM + 0x18 reg6 byte0 */
|
||||
+ u8 reserved0[3]; /* CDM + 0x19 reg6 byte1,2,3 */
|
||||
+
|
||||
+ u8 ccs_sleep_enable; /* CDM + 0x1c reg7 byte0 */
|
||||
+ u8 osc_sleep_enable; /* CDM + 0x1d reg7 byte1 */
|
||||
+ u8 reserved1; /* CDM + 0x1e reg7 byte2 */
|
||||
+ u8 ccs_qreq_test; /* CDM + 0x1f reg7 byte3 */
|
||||
+
|
||||
+ u8 soft_reset; /* CDM + 0x20 u8 byte0 */
|
||||
+ u8 no_ckstp; /* CDM + 0x21 u8 byte0 */
|
||||
+ u8 reserved2[2]; /* CDM + 0x22 u8 byte1,2,3 */
|
||||
+
|
||||
+ u8 pll_lock; /* CDM + 0x24 reg9 byte0 */
|
||||
+ u8 pll_looselock; /* CDM + 0x25 reg9 byte1 */
|
||||
+ u8 pll_sm_lockwin; /* CDM + 0x26 reg9 byte2 */
|
||||
+ u8 reserved3; /* CDM + 0x27 reg9 byte3 */
|
||||
+
|
||||
+ u16 reserved4; /* CDM + 0x28 reg10 byte0,1 */
|
||||
+ u16 mclken_div_psc1; /* CDM + 0x2a reg10 byte2,3 */
|
||||
+
|
||||
+ u16 reserved5; /* CDM + 0x2c reg11 byte0,1 */
|
||||
+ u16 mclken_div_psc2; /* CDM + 0x2e reg11 byte2,3 */
|
||||
+
|
||||
+ u16 reserved6; /* CDM + 0x30 reg12 byte0,1 */
|
||||
+ u16 mclken_div_psc3; /* CDM + 0x32 reg12 byte2,3 */
|
||||
+
|
||||
+ u16 reserved7; /* CDM + 0x34 reg13 byte0,1 */
|
||||
+ u16 mclken_div_psc6; /* CDM + 0x36 reg13 byte2,3 */
|
||||
+};
|
||||
+
|
||||
+#endif /* __ASSEMBLY__ */
|
||||
+
|
||||
+
|
||||
+/* ========================================================================= */
|
||||
+/* Prototypes for MPC52xx sysdev */
|
||||
+/* ========================================================================= */
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
+extern void mpc52xx_init_irq(void);
|
||||
+extern unsigned int mpc52xx_get_irq(void);
|
||||
+
|
||||
+#endif /* __ASSEMBLY__ */
|
||||
+
|
||||
+#endif /* __ASM_POWERPC_MPC52xx_H__ */
|
||||
+
|
||||
--
|
||||
1.4.3.2
|
||||
|
33
debian/patches/features/powerpc/efika/0005-powerpc-Restore-proper-link-order-in-platform.txt
vendored
Normal file
33
debian/patches/features/powerpc/efika/0005-powerpc-Restore-proper-link-order-in-platform.txt
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
From 720e2caeeff0d9585d5627d29ffd660a5a9d9f88 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 20:43:39 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Restore 'proper' link order in platform
|
||||
|
||||
The 52xx was put before CHRP to allow EFIKA to be recognized
|
||||
properly. Now the efika tree is fixed up in prom_init so
|
||||
no need for this ugly hack. So we restore the 'normal'
|
||||
order.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/platforms/Makefile | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
|
||||
index 507d1b9..44d95ea 100644
|
||||
--- a/arch/powerpc/platforms/Makefile
|
||||
+++ b/arch/powerpc/platforms/Makefile
|
||||
@@ -5,9 +5,9 @@ ifeq ($(CONFIG_PPC64),y)
|
||||
obj-$(CONFIG_PPC_PMAC) += powermac/
|
||||
endif
|
||||
endif
|
||||
-obj-$(CONFIG_PPC_MPC52xx) += 52xx/
|
||||
obj-$(CONFIG_PPC_CHRP) += chrp/
|
||||
obj-$(CONFIG_4xx) += 4xx/
|
||||
+obj-$(CONFIG_PPC_MPC52xx) += 52xx/
|
||||
obj-$(CONFIG_PPC_83xx) += 83xx/
|
||||
obj-$(CONFIG_PPC_85xx) += 85xx/
|
||||
obj-$(CONFIG_PPC_86xx) += 86xx/
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,570 +0,0 @@
|
|||
From b20c97e6f809bff52b864db1352a866c66a2bbd1 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:06:28 +0100
|
||||
Subject: [PATCH] Add MPC5200 interrupt controller driver
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
arch/powerpc/sysdev/Makefile | 1 +
|
||||
arch/powerpc/sysdev/mpc52xx_pic.c | 538 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 539 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
|
||||
index 91f052d..5b5b61e 100644
|
||||
--- a/arch/powerpc/sysdev/Makefile
|
||||
+++ b/arch/powerpc/sysdev/Makefile
|
||||
@@ -13,6 +13,7 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
|
||||
obj-$(CONFIG_PPC_TODC) += todc.o
|
||||
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
|
||||
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
|
||||
+obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_pic.o
|
||||
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
obj-$(CONFIG_PPC_I8259) += i8259.o
|
||||
diff --git a/arch/powerpc/sysdev/mpc52xx_pic.c b/arch/powerpc/sysdev/mpc52xx_pic.c
|
||||
new file mode 100644
|
||||
index 0000000..6df51f0
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/sysdev/mpc52xx_pic.c
|
||||
@@ -0,0 +1,538 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * Programmable Interrupt Controller functions for the Freescale MPC52xx.
|
||||
+ *
|
||||
+ * Copyright (C) 2006 bplan GmbH
|
||||
+ *
|
||||
+ * Based on the code from the 2.4 kernel by
|
||||
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ * Copyright (C) 2003 Montavista Software, Inc
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#undef DEBUG
|
||||
+
|
||||
+#include <linux/stddef.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/signal.h>
|
||||
+#include <linux/stddef.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/hardirq.h>
|
||||
+
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/processor.h>
|
||||
+#include <asm/system.h>
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/prom.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+
|
||||
+/*
|
||||
+ *
|
||||
+*/
|
||||
+
|
||||
+static struct mpc52xx_intr __iomem *intr;
|
||||
+static struct mpc52xx_sdma __iomem *sdma;
|
||||
+static struct irq_host *mpc52xx_irqhost = NULL;
|
||||
+
|
||||
+static unsigned char mpc52xx_map_senses[4] = {
|
||||
+ IRQ_TYPE_LEVEL_HIGH,
|
||||
+ IRQ_TYPE_EDGE_RISING,
|
||||
+ IRQ_TYPE_EDGE_FALLING,
|
||||
+ IRQ_TYPE_LEVEL_LOW,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ *
|
||||
+*/
|
||||
+
|
||||
+static inline void io_be_setbit(u32 __iomem * addr, int bitno)
|
||||
+{
|
||||
+ out_be32(addr, in_be32(addr) | (1 << bitno));
|
||||
+}
|
||||
+
|
||||
+static inline void io_be_clrbit(u32 __iomem * addr, int bitno)
|
||||
+{
|
||||
+ out_be32(addr, in_be32(addr) & ~(1 << bitno));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * IRQ[0-3] interrupt irq_chip
|
||||
+*/
|
||||
+
|
||||
+static void mpc52xx_extirq_mask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_clrbit(&intr->ctrl, 11 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_extirq_unmask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_setbit(&intr->ctrl, 11 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_extirq_ack(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_setbit(&intr->ctrl, 27 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mpc52xx_extirq_irqchip = {
|
||||
+ .typename = " MPC52xx IRQ[0-3] ",
|
||||
+ .mask = mpc52xx_extirq_mask,
|
||||
+ .unmask = mpc52xx_extirq_unmask,
|
||||
+ .ack = mpc52xx_extirq_ack,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Main interrupt irq_chip
|
||||
+*/
|
||||
+
|
||||
+static void mpc52xx_main_mask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_setbit(&intr->main_mask, 15 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_main_unmask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_clrbit(&intr->main_mask, 15 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mpc52xx_main_irqchip = {
|
||||
+ .typename = "MPC52xx Main",
|
||||
+ .mask = mpc52xx_main_mask,
|
||||
+ .mask_ack = mpc52xx_main_mask,
|
||||
+ .unmask = mpc52xx_main_unmask,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Peripherals interrupt irq_chip
|
||||
+*/
|
||||
+
|
||||
+static void mpc52xx_periph_mask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_setbit(&intr->per_mask, 31 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_periph_unmask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_clrbit(&intr->per_mask, 31 - l2irq);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mpc52xx_periph_irqchip = {
|
||||
+ .typename = "MPC52xx Peripherals",
|
||||
+ .mask = mpc52xx_periph_mask,
|
||||
+ .mask_ack = mpc52xx_periph_mask,
|
||||
+ .unmask = mpc52xx_periph_unmask,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * SDMA interrupt irq_chip
|
||||
+*/
|
||||
+
|
||||
+static void mpc52xx_sdma_mask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_setbit(&sdma->IntMask, l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_sdma_unmask(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ io_be_clrbit(&sdma->IntMask, l2irq);
|
||||
+}
|
||||
+
|
||||
+static void mpc52xx_sdma_ack(unsigned int virq)
|
||||
+{
|
||||
+ int irq;
|
||||
+ int l2irq;
|
||||
+
|
||||
+ irq = irq_map[virq].hwirq;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
+
|
||||
+ out_be32(&sdma->IntPend, 1 << l2irq);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mpc52xx_sdma_irqchip = {
|
||||
+ .typename = "MPC52xx SDMA",
|
||||
+ .mask = mpc52xx_sdma_mask,
|
||||
+ .unmask = mpc52xx_sdma_unmask,
|
||||
+ .ack = mpc52xx_sdma_ack,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * irq_host
|
||||
+*/
|
||||
+
|
||||
+static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
|
||||
+{
|
||||
+ pr_debug("%s: node=%p\n", __func__, node);
|
||||
+ return mpc52xx_irqhost->host_data == node;
|
||||
+}
|
||||
+
|
||||
+static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
|
||||
+ u32 * intspec, unsigned int intsize,
|
||||
+ irq_hw_number_t * out_hwirq,
|
||||
+ unsigned int *out_flags)
|
||||
+{
|
||||
+ int intrvect_l1;
|
||||
+ int intrvect_l2;
|
||||
+ int intrvect_type;
|
||||
+ int intrvect_linux;
|
||||
+
|
||||
+ if (intsize != 3)
|
||||
+ return -1;
|
||||
+
|
||||
+ intrvect_l1 = (int)intspec[0];
|
||||
+ intrvect_l2 = (int)intspec[1];
|
||||
+ intrvect_type = (int)intspec[2];
|
||||
+
|
||||
+ intrvect_linux =
|
||||
+ (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK;
|
||||
+ intrvect_linux |=
|
||||
+ (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK;
|
||||
+
|
||||
+ pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
|
||||
+ intrvect_l2);
|
||||
+
|
||||
+ *out_hwirq = intrvect_linux;
|
||||
+ *out_flags = mpc52xx_map_senses[intrvect_type];
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * this function retrieves the correct IRQ type out
|
||||
+ * of the MPC regs
|
||||
+ * Only externals IRQs needs this
|
||||
+*/
|
||||
+static int mpc52xx_irqx_gettype(int irq)
|
||||
+{
|
||||
+ int type;
|
||||
+ u32 ctrl_reg;
|
||||
+
|
||||
+ ctrl_reg = in_be32(&intr->ctrl);
|
||||
+ type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
|
||||
+
|
||||
+ return mpc52xx_map_senses[type];
|
||||
+}
|
||||
+
|
||||
+static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
|
||||
+ irq_hw_number_t irq)
|
||||
+{
|
||||
+ int l1irq;
|
||||
+ int l2irq;
|
||||
+ struct irq_chip *good_irqchip;
|
||||
+ void *good_handle;
|
||||
+ int type;
|
||||
+
|
||||
+ l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
|
||||
+ l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
+
|
||||
+ /*
|
||||
+ * Most of ours IRQs will be level low
|
||||
+ * Only external IRQs on some platform may be others
|
||||
+ */
|
||||
+ type = IRQ_TYPE_LEVEL_LOW;
|
||||
+
|
||||
+ switch (l1irq) {
|
||||
+ case MPC52xx_IRQ_L1_CRIT:
|
||||
+ pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
|
||||
+
|
||||
+ BUG_ON(l2irq != 0);
|
||||
+
|
||||
+ type = mpc52xx_irqx_gettype(l2irq);
|
||||
+ good_irqchip = &mpc52xx_extirq_irqchip;
|
||||
+ break;
|
||||
+
|
||||
+ case MPC52xx_IRQ_L1_MAIN:
|
||||
+ pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
|
||||
+
|
||||
+ if ((l2irq >= 1) && (l2irq <= 3)) {
|
||||
+ type = mpc52xx_irqx_gettype(l2irq);
|
||||
+ good_irqchip = &mpc52xx_extirq_irqchip;
|
||||
+ } else {
|
||||
+ good_irqchip = &mpc52xx_main_irqchip;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case MPC52xx_IRQ_L1_PERP:
|
||||
+ pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
|
||||
+ good_irqchip = &mpc52xx_periph_irqchip;
|
||||
+ break;
|
||||
+
|
||||
+ case MPC52xx_IRQ_L1_SDMA:
|
||||
+ pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
|
||||
+ good_irqchip = &mpc52xx_sdma_irqchip;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq);
|
||||
+ printk(KERN_ERR "Unknow IRQ!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case IRQ_TYPE_EDGE_FALLING:
|
||||
+ case IRQ_TYPE_EDGE_RISING:
|
||||
+ good_handle = handle_edge_irq;
|
||||
+ break;
|
||||
+ default:
|
||||
+ good_handle = handle_level_irq;
|
||||
+ }
|
||||
+
|
||||
+ set_irq_chip_and_handler(virq, good_irqchip, good_handle);
|
||||
+
|
||||
+ pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
|
||||
+ (int)irq, type);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_host_ops mpc52xx_irqhost_ops = {
|
||||
+ .match = mpc52xx_irqhost_match,
|
||||
+ .xlate = mpc52xx_irqhost_xlate,
|
||||
+ .map = mpc52xx_irqhost_map,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * init (public)
|
||||
+*/
|
||||
+
|
||||
+void __init mpc52xx_init_irq(void)
|
||||
+{
|
||||
+ struct device_node *picnode = NULL;
|
||||
+ int picnode_regsize;
|
||||
+ u32 picnode_regoffset;
|
||||
+
|
||||
+ struct device_node *sdmanode = NULL;
|
||||
+ int sdmanode_regsize;
|
||||
+ u32 sdmanode_regoffset;
|
||||
+
|
||||
+ u64 size64;
|
||||
+ int flags;
|
||||
+
|
||||
+ u32 intr_ctrl;
|
||||
+
|
||||
+ picnode = of_find_compatible_node(NULL, "interrupt-controller",
|
||||
+ "mpc5200-pic");
|
||||
+ if (picnode == NULL) {
|
||||
+ printk(KERN_ERR "MPC52xx PIC: "
|
||||
+ "Unable to find the interrupt controller "
|
||||
+ "in the OpenFirmware device tree\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ sdmanode = of_find_compatible_node(NULL, "dma-controller",
|
||||
+ "mpc5200-bestcomm");
|
||||
+ if (sdmanode == NULL) {
|
||||
+ printk(KERN_ERR "MPC52xx PIC"
|
||||
+ "Unable to find the Bestcomm DMA controller device "
|
||||
+ "in the OpenFirmware device tree\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ /* Retrieve PIC ressources */
|
||||
+ picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags);
|
||||
+ if (picnode_regoffset == 0) {
|
||||
+ printk(KERN_ERR "MPC52xx PIC"
|
||||
+ "Unable to get the interrupt controller address\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ picnode_regoffset =
|
||||
+ of_translate_address(picnode, (u32 *) picnode_regoffset);
|
||||
+ picnode_regsize = (int)size64;
|
||||
+
|
||||
+ /* Retrieve SDMA ressources */
|
||||
+ sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags);
|
||||
+ if (sdmanode_regoffset == 0) {
|
||||
+ printk(KERN_ERR "MPC52xx PIC: "
|
||||
+ "Unable to get the Bestcomm DMA controller address\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ sdmanode_regoffset =
|
||||
+ of_translate_address(sdmanode, (u32 *) sdmanode_regoffset);
|
||||
+ sdmanode_regsize = (int)size64;
|
||||
+
|
||||
+ /* Remap the necessary zones */
|
||||
+ intr = ioremap(picnode_regoffset, picnode_regsize);
|
||||
+ if (intr == NULL) {
|
||||
+ printk(KERN_ERR "MPC52xx PIC: "
|
||||
+ "Unable to ioremap interrupt controller registers!\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ sdma = ioremap(sdmanode_regoffset, sdmanode_regsize);
|
||||
+ if (sdma == NULL) {
|
||||
+ iounmap(intr);
|
||||
+ printk(KERN_ERR "MPC52xx PIC: "
|
||||
+ "Unable to ioremap Bestcomm DMA registers!\n");
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO "MPC52xx PIC: MPC52xx PIC Remapped at 0x%8.8x\n",
|
||||
+ picnode_regoffset);
|
||||
+ printk(KERN_INFO "MPC52xx PIC: MPC52xx SDMA Remapped at 0x%8.8x\n",
|
||||
+ sdmanode_regoffset);
|
||||
+
|
||||
+ /* Disable all interrupt sources. */
|
||||
+ out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
|
||||
+ out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
|
||||
+ out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
|
||||
+ out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
|
||||
+ intr_ctrl = in_be32(&intr->ctrl);
|
||||
+ intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
|
||||
+ intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
|
||||
+ 0x00001000 | /* MEE master external enable */
|
||||
+ 0x00000000 | /* 0 means disable IRQ 0-3 */
|
||||
+ 0x00000001; /* CEb route critical normally */
|
||||
+ out_be32(&intr->ctrl, intr_ctrl);
|
||||
+
|
||||
+ /* Zero a bunch of the priority settings. */
|
||||
+ out_be32(&intr->per_pri1, 0);
|
||||
+ out_be32(&intr->per_pri2, 0);
|
||||
+ out_be32(&intr->per_pri3, 0);
|
||||
+ out_be32(&intr->main_pri1, 0);
|
||||
+ out_be32(&intr->main_pri2, 0);
|
||||
+
|
||||
+ /*
|
||||
+ * As last step, add an irq host to translate the real
|
||||
+ * hw irq information provided by the ofw to linux virq
|
||||
+ */
|
||||
+
|
||||
+ mpc52xx_irqhost =
|
||||
+ irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTHWIRQ,
|
||||
+ &mpc52xx_irqhost_ops, -1);
|
||||
+
|
||||
+ if (mpc52xx_irqhost) {
|
||||
+ mpc52xx_irqhost->host_data = picnode;
|
||||
+ printk(KERN_INFO "MPC52xx PIC is up and running!\n");
|
||||
+ } else {
|
||||
+ printk(KERN_ERR
|
||||
+ "MPC52xx PIC: Unable to allocate the IRQ host\n");
|
||||
+ }
|
||||
+
|
||||
+end:
|
||||
+ of_node_put(picnode);
|
||||
+ of_node_put(sdmanode);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * get_irq (public)
|
||||
+*/
|
||||
+unsigned int mpc52xx_get_irq(void)
|
||||
+{
|
||||
+ u32 status;
|
||||
+ int irq = NO_IRQ_IGNORE;
|
||||
+
|
||||
+ status = in_be32(&intr->enc_status);
|
||||
+ if (status & 0x00000400) { /* critical */
|
||||
+ irq = (status >> 8) & 0x3;
|
||||
+ if (irq == 2) /* high priority peripheral */
|
||||
+ goto peripheral;
|
||||
+ irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) &
|
||||
+ MPC52xx_IRQ_L1_MASK;
|
||||
+ } else if (status & 0x00200000) { /* main */
|
||||
+ irq = (status >> 16) & 0x1f;
|
||||
+ if (irq == 4) /* low priority peripheral */
|
||||
+ goto peripheral;
|
||||
+ irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) &
|
||||
+ MPC52xx_IRQ_L1_MASK;
|
||||
+ } else if (status & 0x20000000) { /* peripheral */
|
||||
+ peripheral:
|
||||
+ irq = (status >> 24) & 0x1f;
|
||||
+ if (irq == 0) { /* bestcomm */
|
||||
+ status = in_be32(&sdma->IntPend);
|
||||
+ irq = ffs(status) - 1;
|
||||
+ irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) &
|
||||
+ MPC52xx_IRQ_L1_MASK;
|
||||
+ } else
|
||||
+ irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) &
|
||||
+ MPC52xx_IRQ_L1_MASK;
|
||||
+ }
|
||||
+
|
||||
+ pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
|
||||
+ irq_linear_revmap(mpc52xx_irqhost, irq));
|
||||
+
|
||||
+ return irq_linear_revmap(mpc52xx_irqhost, irq);
|
||||
+}
|
||||
+
|
||||
--
|
||||
1.4.3.2
|
||||
|
236
debian/patches/features/powerpc/efika/0006-Rework-the-OHCI-quirk-mecanism-as-suggested-by-David.txt
vendored
Normal file
236
debian/patches/features/powerpc/efika/0006-Rework-the-OHCI-quirk-mecanism-as-suggested-by-David.txt
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
From 9282a04f14cef512736ac4a895fb48456e6a8989 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Thu, 14 Dec 2006 14:13:26 +1100
|
||||
Subject: [PATCH] [PATCH] Rework the OHCI quirk mecanism as suggested by David
|
||||
|
||||
This patch applies David Brownell's suggestion for reworking the
|
||||
OHCI quirk mechanism via a table of PCI IDs. It adapts the existing
|
||||
quirks to use that mechanism.
|
||||
|
||||
This also moves the quirks to reset() as suggested by the comment
|
||||
in there. This is necessary as we need to have the endian properly
|
||||
set before we try to init the controller.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||
|
||||
drivers/usb/host/ohci-pci.c | 173 +++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 110 insertions(+), 63 deletions(-)
|
||||
---
|
||||
drivers/usb/host/ohci-pci.c | 173 +++++++++++++++++++++++++++----------------
|
||||
1 files changed, 110 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
|
||||
index 596e0b4..82fbec3 100644
|
||||
--- a/drivers/usb/host/ohci-pci.c
|
||||
+++ b/drivers/usb/host/ohci-pci.c
|
||||
@@ -20,79 +20,128 @@
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
-static int
|
||||
-ohci_pci_reset (struct usb_hcd *hcd)
|
||||
+/* AMD 756, for most chips (early revs), corrupts register
|
||||
+ * values on read ... so enable the vendor workaround.
|
||||
+ */
|
||||
+static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
|
||||
- ohci_hcd_init (ohci);
|
||||
- return ohci_init (ohci);
|
||||
+ ohci->flags = OHCI_QUIRK_AMD756;
|
||||
+ ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
|
||||
+
|
||||
+ /* also erratum 10 (suspend/resume issues) */
|
||||
+ device_init_wakeup(&hcd->self.root_hub->dev, 0);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-static int __devinit
|
||||
-ohci_pci_start (struct usb_hcd *hcd)
|
||||
+/* Apple's OHCI driver has a lot of bizarre workarounds
|
||||
+ * for this chip. Evidently control and bulk lists
|
||||
+ * can get confused. (B&W G3 models, and ...)
|
||||
+ */
|
||||
+static int __devinit ohci_quirk_opti(struct usb_hcd *hcd)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
- int ret;
|
||||
|
||||
- /* REVISIT this whole block should move to reset(), which handles
|
||||
- * all the other one-time init.
|
||||
+ ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Check for NSC87560. We have to look at the bridge (fn1) to
|
||||
+ * identify the USB (fn2). This quirk might apply to more or
|
||||
+ * even all NSC stuff.
|
||||
+ */
|
||||
+static int __devinit ohci_quirk_ns(struct usb_hcd *hcd)
|
||||
+{
|
||||
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
+ struct pci_dev *b;
|
||||
+
|
||||
+ b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
|
||||
+ if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
|
||||
+ && b->vendor == PCI_VENDOR_ID_NS) {
|
||||
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
+
|
||||
+ ohci->flags |= OHCI_QUIRK_SUPERIO;
|
||||
+ ohci_dbg (ohci, "Using NSC SuperIO setup\n");
|
||||
+ }
|
||||
+ pci_dev_put(b);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Check for Compaq's ZFMicro chipset, which needs short
|
||||
+ * delays before control or bulk queues get re-activated
|
||||
+ * in finish_unlinks()
|
||||
+ */
|
||||
+static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd)
|
||||
+{
|
||||
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
+
|
||||
+ ohci->flags |= OHCI_QUIRK_ZFMICRO;
|
||||
+ ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* List of quirks for OHCI */
|
||||
+static const struct pci_device_id ohci_pci_quirks[] = {
|
||||
+ {
|
||||
+ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c),
|
||||
+ .driver_data = (unsigned long)ohci_quirk_amd756,
|
||||
+ },
|
||||
+ {
|
||||
+ PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861),
|
||||
+ .driver_data = (unsigned long)ohci_quirk_opti,
|
||||
+ },
|
||||
+ {
|
||||
+ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID),
|
||||
+ .driver_data = (unsigned long)ohci_quirk_ns,
|
||||
+ },
|
||||
+ {
|
||||
+ PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8),
|
||||
+ .driver_data = (unsigned long)ohci_quirk_zfmicro,
|
||||
+ },
|
||||
+ /* FIXME for some of the early AMD 760 southbridges, OHCI
|
||||
+ * won't work at all. blacklist them.
|
||||
*/
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static int ohci_pci_reset (struct usb_hcd *hcd)
|
||||
+{
|
||||
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
+ int ret = 0;
|
||||
+
|
||||
if (hcd->self.controller) {
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
+ const struct pci_device_id *quirk_id;
|
||||
|
||||
- /* AMD 756, for most chips (early revs), corrupts register
|
||||
- * values on read ... so enable the vendor workaround.
|
||||
- */
|
||||
- if (pdev->vendor == PCI_VENDOR_ID_AMD
|
||||
- && pdev->device == 0x740c) {
|
||||
- ohci->flags = OHCI_QUIRK_AMD756;
|
||||
- ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
|
||||
- /* also erratum 10 (suspend/resume issues) */
|
||||
- device_init_wakeup(&hcd->self.root_hub->dev, 0);
|
||||
+ quirk_id = pci_match_id(ohci_pci_quirks, pdev);
|
||||
+ if (quirk_id != NULL) {
|
||||
+ int (*quirk)(struct usb_hcd *ohci);
|
||||
+ quirk = (void *)quirk_id->driver_data;
|
||||
+ ret = quirk(hcd);
|
||||
}
|
||||
+ }
|
||||
+ if (ret == 0) {
|
||||
+ ohci_hcd_init (ohci);
|
||||
+ return ohci_init (ohci);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
- /* FIXME for some of the early AMD 760 southbridges, OHCI
|
||||
- * won't work at all. blacklist them.
|
||||
- */
|
||||
-
|
||||
- /* Apple's OHCI driver has a lot of bizarre workarounds
|
||||
- * for this chip. Evidently control and bulk lists
|
||||
- * can get confused. (B&W G3 models, and ...)
|
||||
- */
|
||||
- else if (pdev->vendor == PCI_VENDOR_ID_OPTI
|
||||
- && pdev->device == 0xc861) {
|
||||
- ohci_dbg (ohci,
|
||||
- "WARNING: OPTi workarounds unavailable\n");
|
||||
- }
|
||||
|
||||
- /* Check for NSC87560. We have to look at the bridge (fn1) to
|
||||
- * identify the USB (fn2). This quirk might apply to more or
|
||||
- * even all NSC stuff.
|
||||
- */
|
||||
- else if (pdev->vendor == PCI_VENDOR_ID_NS) {
|
||||
- struct pci_dev *b;
|
||||
-
|
||||
- b = pci_get_slot (pdev->bus,
|
||||
- PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
|
||||
- if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
|
||||
- && b->vendor == PCI_VENDOR_ID_NS) {
|
||||
- ohci->flags |= OHCI_QUIRK_SUPERIO;
|
||||
- ohci_dbg (ohci, "Using NSC SuperIO setup\n");
|
||||
- }
|
||||
- pci_dev_put(b);
|
||||
- }
|
||||
+static int __devinit ohci_pci_start (struct usb_hcd *hcd)
|
||||
+{
|
||||
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
+ int ret;
|
||||
|
||||
- /* Check for Compaq's ZFMicro chipset, which needs short
|
||||
- * delays before control or bulk queues get re-activated
|
||||
- * in finish_unlinks()
|
||||
- */
|
||||
- else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ
|
||||
- && pdev->device == 0xa0f8) {
|
||||
- ohci->flags |= OHCI_QUIRK_ZFMICRO;
|
||||
- ohci_dbg (ohci,
|
||||
- "enabled Compaq ZFMicro chipset quirk\n");
|
||||
- }
|
||||
+#ifdef CONFIG_PM /* avoid warnings about unused pdev */
|
||||
+ if (hcd->self.controller) {
|
||||
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
|
||||
/* RWC may not be set for add-in PCI cards, since boot
|
||||
* firmware probably ignored them. This transfers PCI
|
||||
@@ -101,16 +150,14 @@ ohci_pci_start (struct usb_hcd *hcd)
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
ohci->hc_control |= OHCI_CTRL_RWC;
|
||||
}
|
||||
+#endif /* CONFIG_PM */
|
||||
|
||||
- /* NOTE: there may have already been a first reset, to
|
||||
- * keep bios/smm irqs from making trouble
|
||||
- */
|
||||
- if ((ret = ohci_run (ohci)) < 0) {
|
||||
+ ret = ohci_run (ohci);
|
||||
+ if (ret < 0) {
|
||||
ohci_err (ohci, "can't start\n");
|
||||
ohci_stop (hcd);
|
||||
- return ret;
|
||||
}
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
--
|
||||
1.4.4.2
|
||||
|
367
debian/patches/features/powerpc/efika/0007-Implement-support-for-split-endian-OHCI.txt
vendored
Normal file
367
debian/patches/features/powerpc/efika/0007-Implement-support-for-split-endian-OHCI.txt
vendored
Normal file
|
@ -0,0 +1,367 @@
|
|||
From a87f8738eb3651b7eea1feae793def3a48dc36c6 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Thu, 14 Dec 2006 14:13:28 +1100
|
||||
Subject: [PATCH] [PATCH] Implement support for "split" endian OHCI
|
||||
|
||||
This patch separates support for big endian MMIO register access
|
||||
and big endian descriptors in order to support the Toshiba SCC
|
||||
implementation which has big endian registers but little endian
|
||||
in-memory descriptors.
|
||||
|
||||
It simplifies the access functions a bit in ohci.h while at it.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||
|
||||
drivers/usb/host/Kconfig | 10 ++
|
||||
drivers/usb/host/ohci-pci.c | 26 +++++++
|
||||
drivers/usb/host/ohci-ppc-soc.c | 2
|
||||
drivers/usb/host/ohci.h | 147 +++++++++++++++++++++++++---------------
|
||||
4 files changed, 130 insertions(+), 55 deletions(-)
|
||||
---
|
||||
drivers/usb/host/Kconfig | 10 ++-
|
||||
drivers/usb/host/ohci-pci.c | 26 +++++++
|
||||
drivers/usb/host/ohci-ppc-soc.c | 2 +-
|
||||
drivers/usb/host/ohci.h | 147 +++++++++++++++++++++++++--------------
|
||||
4 files changed, 130 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
|
||||
index cc60759..faabce8 100644
|
||||
--- a/drivers/usb/host/Kconfig
|
||||
+++ b/drivers/usb/host/Kconfig
|
||||
@@ -101,7 +101,8 @@ config USB_OHCI_HCD_PPC_SOC
|
||||
bool "OHCI support for on-chip PPC USB controller"
|
||||
depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
|
||||
default y
|
||||
- select USB_OHCI_BIG_ENDIAN
|
||||
+ select USB_OHCI_BIG_ENDIAN_DESC
|
||||
+ select USB_OHCI_BIG_ENDIAN_MMIO
|
||||
---help---
|
||||
Enables support for the USB controller on the MPC52xx or
|
||||
STB03xxx processor chip. If unsure, say Y.
|
||||
@@ -115,7 +116,12 @@ config USB_OHCI_HCD_PCI
|
||||
Enables support for PCI-bus plug-in USB controller cards.
|
||||
If unsure, say Y.
|
||||
|
||||
-config USB_OHCI_BIG_ENDIAN
|
||||
+config USB_OHCI_BIG_ENDIAN_DESC
|
||||
+ bool
|
||||
+ depends on USB_OHCI_HCD
|
||||
+ default n
|
||||
+
|
||||
+config USB_OHCI_BIG_ENDIAN_MMIO
|
||||
bool
|
||||
depends on USB_OHCI_HCD
|
||||
default n
|
||||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
|
||||
index 82fbec3..292daf0 100644
|
||||
--- a/drivers/usb/host/ohci-pci.c
|
||||
+++ b/drivers/usb/host/ohci-pci.c
|
||||
@@ -85,6 +85,27 @@ static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Check for Toshiba SCC OHCI which has big endian registers
|
||||
+ * and little endian in memory data structures
|
||||
+ */
|
||||
+static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
|
||||
+{
|
||||
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
+
|
||||
+ /* That chip is only present in the southbridge of some
|
||||
+ * cell based platforms which are supposed to select
|
||||
+ * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if
|
||||
+ * that was the case though.
|
||||
+ */
|
||||
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
|
||||
+ ohci->flags |= OHCI_QUIRK_BE_MMIO;
|
||||
+ ohci_dbg (ohci, "enabled big endian Toshiba quirk\n");
|
||||
+ return 0;
|
||||
+#else
|
||||
+ ohci_err (ohci, "unsupported big endian Toshiba quirk\n");
|
||||
+ return -ENXIO;
|
||||
+#endif
|
||||
+}
|
||||
|
||||
/* List of quirks for OHCI */
|
||||
static const struct pci_device_id ohci_pci_quirks[] = {
|
||||
@@ -104,9 +125,14 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
||||
PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8),
|
||||
.driver_data = (unsigned long)ohci_quirk_zfmicro,
|
||||
},
|
||||
+ {
|
||||
+ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6),
|
||||
+ .driver_data = (unsigned long)ohci_quirk_toshiba_scc,
|
||||
+ },
|
||||
/* FIXME for some of the early AMD 760 southbridges, OHCI
|
||||
* won't work at all. blacklist them.
|
||||
*/
|
||||
+
|
||||
{},
|
||||
};
|
||||
|
||||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
|
||||
index e1a7eb8..c7ce8e6 100644
|
||||
--- a/drivers/usb/host/ohci-ppc-soc.c
|
||||
+++ b/drivers/usb/host/ohci-ppc-soc.c
|
||||
@@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
|
||||
}
|
||||
|
||||
ohci = hcd_to_ohci(hcd);
|
||||
- ohci->flags |= OHCI_BIG_ENDIAN;
|
||||
+ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
|
||||
ohci_hcd_init(ohci);
|
||||
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
|
||||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
|
||||
index 405257f..fc7c161 100644
|
||||
--- a/drivers/usb/host/ohci.h
|
||||
+++ b/drivers/usb/host/ohci.h
|
||||
@@ -394,8 +394,9 @@ struct ohci_hcd {
|
||||
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
|
||||
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
|
||||
#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */
|
||||
-#define OHCI_BIG_ENDIAN 0x08 /* big endian HC */
|
||||
-#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/
|
||||
+#define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */
|
||||
+#define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */
|
||||
+#define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/
|
||||
// there are also chip quirks/bugs in init logic
|
||||
|
||||
};
|
||||
@@ -439,117 +440,156 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
|
||||
* a minority (notably the IBM STB04XXX and the Motorola MPC5200
|
||||
* processors) implement them in big endian format.
|
||||
*
|
||||
+ * In addition some more exotic implementations like the Toshiba
|
||||
+ * Spider (aka SCC) cell southbridge are "mixed" endian, that is,
|
||||
+ * they have a different endianness for registers vs. in-memory
|
||||
+ * descriptors.
|
||||
+ *
|
||||
* This attempts to support either format at compile time without a
|
||||
* runtime penalty, or both formats with the additional overhead
|
||||
* of checking a flag bit.
|
||||
+ *
|
||||
+ * That leads to some tricky Kconfig rules howevber. There are
|
||||
+ * different defaults based on some arch/ppc platforms, though
|
||||
+ * the basic rules are:
|
||||
+ *
|
||||
+ * Controller type Kconfig options needed
|
||||
+ * --------------- ----------------------
|
||||
+ * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN
|
||||
+ *
|
||||
+ * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_
|
||||
+ * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
|
||||
+ *
|
||||
+ * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_
|
||||
+ * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC}
|
||||
+ *
|
||||
+ * (If you have a mixed endian controller, you -must- also define
|
||||
+ * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building
|
||||
+ * both your mixed endian and a fully big endian controller support in
|
||||
+ * the same kernel image).
|
||||
*/
|
||||
|
||||
-#ifdef CONFIG_USB_OHCI_BIG_ENDIAN
|
||||
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
|
||||
+#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN
|
||||
+#define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC)
|
||||
+#else
|
||||
+#define big_endian_desc(ohci) 1 /* only big endian */
|
||||
+#endif
|
||||
+#else
|
||||
+#define big_endian_desc(ohci) 0 /* only little endian */
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
|
||||
#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN
|
||||
-#define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */
|
||||
+#define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO)
|
||||
+#else
|
||||
+#define big_endian_mmio(ohci) 1 /* only big endian */
|
||||
+#endif
|
||||
#else
|
||||
-#define big_endian(ohci) 1 /* only big endian */
|
||||
+#define big_endian_mmio(ohci) 0 /* only little endian */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Big-endian read/write functions are arch-specific.
|
||||
* Other arches can be added if/when they're needed.
|
||||
+ *
|
||||
+ * REVISIT: arch/powerpc now has readl/writel_be, so the
|
||||
+ * definition below can die once the STB04xxx support is
|
||||
+ * finally ported over.
|
||||
*/
|
||||
-#if defined(CONFIG_PPC)
|
||||
+#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
|
||||
#define readl_be(addr) in_be32((__force unsigned *)addr)
|
||||
#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
|
||||
#endif
|
||||
|
||||
-static inline unsigned int ohci_readl (const struct ohci_hcd *ohci,
|
||||
- __hc32 __iomem * regs)
|
||||
+static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
|
||||
+ __hc32 __iomem * regs)
|
||||
{
|
||||
- return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs);
|
||||
+ return big_endian_mmio(ohci) ?
|
||||
+ readl_be ((__force u32 *)regs) :
|
||||
+ readl ((__force u32 *)regs);
|
||||
}
|
||||
|
||||
-static inline void ohci_writel (const struct ohci_hcd *ohci,
|
||||
- const unsigned int val, __hc32 __iomem *regs)
|
||||
+static inline void _ohci_writel (const struct ohci_hcd *ohci,
|
||||
+ const unsigned int val, __hc32 __iomem *regs)
|
||||
{
|
||||
- big_endian(ohci) ? writel_be (val, regs) :
|
||||
- writel (val, (__force u32 *)regs);
|
||||
+ big_endian_mmio(ohci) ?
|
||||
+ writel_be (val, (__force u32 *)regs) :
|
||||
+ writel (val, (__force u32 *)regs);
|
||||
}
|
||||
|
||||
-#else /* !CONFIG_USB_OHCI_BIG_ENDIAN */
|
||||
-
|
||||
-#define big_endian(ohci) 0 /* only little endian */
|
||||
-
|
||||
#ifdef CONFIG_ARCH_LH7A404
|
||||
- /* Marc Singer: at the time this code was written, the LH7A404
|
||||
- * had a problem reading the USB host registers. This
|
||||
- * implementation of the ohci_readl function performs the read
|
||||
- * twice as a work-around.
|
||||
- */
|
||||
-static inline unsigned int
|
||||
-ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs)
|
||||
-{
|
||||
- *(volatile __force unsigned int*) regs;
|
||||
- return *(volatile __force unsigned int*) regs;
|
||||
-}
|
||||
+/* Marc Singer: at the time this code was written, the LH7A404
|
||||
+ * had a problem reading the USB host registers. This
|
||||
+ * implementation of the ohci_readl function performs the read
|
||||
+ * twice as a work-around.
|
||||
+ */
|
||||
+#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r))
|
||||
+#define ohci_writel(o,v,r) _ohci_writel(o,v,r)
|
||||
#else
|
||||
- /* Standard version of ohci_readl uses standard, platform
|
||||
- * specific implementation. */
|
||||
-static inline unsigned int
|
||||
-ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs)
|
||||
-{
|
||||
- return readl(regs);
|
||||
-}
|
||||
+#define ohci_readl(o,r) _ohci_readl(o,r)
|
||||
+#define ohci_writel(o,v,r) _ohci_writel(o,v,r)
|
||||
#endif
|
||||
|
||||
-static inline void ohci_writel (const struct ohci_hcd *ohci,
|
||||
- const unsigned int val, __hc32 __iomem *regs)
|
||||
-{
|
||||
- writel (val, regs);
|
||||
-}
|
||||
-
|
||||
-#endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* cpu to ohci */
|
||||
static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x)
|
||||
{
|
||||
- return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ (__force __hc16)cpu_to_be16(x) :
|
||||
+ (__force __hc16)cpu_to_le16(x);
|
||||
}
|
||||
|
||||
static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x)
|
||||
{
|
||||
- return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ cpu_to_be16p(x) :
|
||||
+ cpu_to_le16p(x);
|
||||
}
|
||||
|
||||
static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x)
|
||||
{
|
||||
- return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ (__force __hc32)cpu_to_be32(x) :
|
||||
+ (__force __hc32)cpu_to_le32(x);
|
||||
}
|
||||
|
||||
static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x)
|
||||
{
|
||||
- return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ cpu_to_be32p(x) :
|
||||
+ cpu_to_le32p(x);
|
||||
}
|
||||
|
||||
/* ohci to cpu */
|
||||
static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x)
|
||||
{
|
||||
- return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ be16_to_cpu((__force __be16)x) :
|
||||
+ le16_to_cpu((__force __le16)x);
|
||||
}
|
||||
|
||||
static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x)
|
||||
{
|
||||
- return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ be16_to_cpup((__force __be16 *)x) :
|
||||
+ le16_to_cpup((__force __le16 *)x);
|
||||
}
|
||||
|
||||
static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x)
|
||||
{
|
||||
- return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ be32_to_cpu((__force __be32)x) :
|
||||
+ le32_to_cpu((__force __le32)x);
|
||||
}
|
||||
|
||||
static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x)
|
||||
{
|
||||
- return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x);
|
||||
+ return big_endian_desc(ohci) ?
|
||||
+ be32_to_cpup((__force __be32 *)x) :
|
||||
+ le32_to_cpup((__force __le32 *)x);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -557,6 +597,9 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x)
|
||||
/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all
|
||||
* hardware handles 16 bit reads. That creates a different confusion on
|
||||
* some big-endian SOC implementations. Same thing happens with PSW access.
|
||||
+ *
|
||||
+ * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over
|
||||
+ * to arch/powerpc
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STB03xxx
|
||||
@@ -568,7 +611,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x)
|
||||
static inline u16 ohci_frame_no(const struct ohci_hcd *ohci)
|
||||
{
|
||||
u32 tmp;
|
||||
- if (big_endian(ohci)) {
|
||||
+ if (big_endian_desc(ohci)) {
|
||||
tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no);
|
||||
tmp >>= OHCI_BE_FRAME_NO_SHIFT;
|
||||
} else
|
||||
@@ -580,7 +623,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci)
|
||||
static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci,
|
||||
const struct td *td, int index)
|
||||
{
|
||||
- return (__hc16 *)(big_endian(ohci) ?
|
||||
+ return (__hc16 *)(big_endian_desc(ohci) ?
|
||||
&td->hwPSW[index ^ 1] : &td->hwPSW[index]);
|
||||
}
|
||||
|
||||
--
|
||||
1.4.4.2
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,470 @@
|
|||
From 51294aa1482ea961a3e51ddac587b70b7c1c8ba0 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Wed, 13 Dec 2006 20:35:37 +0100
|
||||
Subject: [PATCH] [PATCH] ohci: Rework bus glue integration to allow several at once
|
||||
|
||||
The previous model had the module_init & module_exit function in the
|
||||
bus glue .c files themselves. That's a problem if several glues need
|
||||
to be selected at once and the driver is built has module. This case
|
||||
is quite common in embedded system where you want to handle both the
|
||||
integrated ohci controller and some extra controller on PCI.
|
||||
|
||||
The ohci-hcd.c file now provide the module_init & module_exit and
|
||||
appropriate driver registering/unregistering is done conditionally,
|
||||
using #ifdefs.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/host/ohci-at91.c | 15 ------
|
||||
drivers/usb/host/ohci-au1xxx.c | 16 ------
|
||||
drivers/usb/host/ohci-ep93xx.c | 12 -----
|
||||
drivers/usb/host/ohci-hcd.c | 98 +++++++++++++++++++++++++++++++++------
|
||||
drivers/usb/host/ohci-lh7a404.c | 16 ------
|
||||
drivers/usb/host/ohci-omap.c | 19 --------
|
||||
drivers/usb/host/ohci-pci.c | 20 --------
|
||||
drivers/usb/host/ohci-pnx4008.c | 12 -----
|
||||
drivers/usb/host/ohci-pnx8550.c | 16 ------
|
||||
drivers/usb/host/ohci-ppc-soc.c | 16 ------
|
||||
drivers/usb/host/ohci-pxa27x.c | 16 ------
|
||||
drivers/usb/host/ohci-s3c2410.c | 12 -----
|
||||
drivers/usb/host/ohci-sa1111.c | 16 ------
|
||||
13 files changed, 83 insertions(+), 201 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
|
||||
index cc40551..53f62cf 100644
|
||||
--- a/drivers/usb/host/ohci-at91.c
|
||||
+++ b/drivers/usb/host/ohci-at91.c
|
||||
@@ -320,18 +320,3 @@ static struct platform_driver ohci_hcd_at91_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_at91_init (void)
|
||||
-{
|
||||
- if (usb_disabled())
|
||||
- return -ENODEV;
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_at91_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_at91_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_at91_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_at91_init);
|
||||
-module_exit (ohci_hcd_at91_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
|
||||
index e70b243..663a060 100644
|
||||
--- a/drivers/usb/host/ohci-au1xxx.c
|
||||
+++ b/drivers/usb/host/ohci-au1xxx.c
|
||||
@@ -345,19 +345,3 @@ static struct platform_driver ohci_hcd_au1xxx_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_au1xxx_init (void)
|
||||
-{
|
||||
- pr_debug (DRIVER_INFO " (Au1xxx)");
|
||||
- pr_debug ("block sizes: ed %d td %d\n",
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_au1xxx_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_au1xxx_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_au1xxx_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_au1xxx_init);
|
||||
-module_exit (ohci_hcd_au1xxx_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
|
||||
index 43ae696..e9974c3 100644
|
||||
--- a/drivers/usb/host/ohci-ep93xx.c
|
||||
+++ b/drivers/usb/host/ohci-ep93xx.c
|
||||
@@ -214,15 +214,3 @@ static struct platform_driver ohci_hcd_ep93xx_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_ep93xx_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&ohci_hcd_ep93xx_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_ep93xx_cleanup(void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_ep93xx_driver);
|
||||
-}
|
||||
-
|
||||
-module_init(ohci_hcd_ep93xx_init);
|
||||
-module_exit(ohci_hcd_ep93xx_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
|
||||
index c1c1d87..9926b8f 100644
|
||||
--- a/drivers/usb/host/ohci-hcd.c
|
||||
+++ b/drivers/usb/host/ohci-hcd.c
|
||||
@@ -855,63 +855,131 @@ MODULE_LICENSE ("GPL");
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include "ohci-pci.c"
|
||||
+#define PCI_DRIVER ohci_pci_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SA1111
|
||||
#include "ohci-sa1111.c"
|
||||
+#define SA1111_DRIVER ohci_hcd_sa1111_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_S3C2410
|
||||
#include "ohci-s3c2410.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_s3c2410_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP
|
||||
#include "ohci-omap.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_omap_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_LH7A404
|
||||
#include "ohci-lh7a404.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_lh7a404_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
#include "ohci-pxa27x.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_EP93XX
|
||||
#include "ohci-ep93xx.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_ep93xx_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_AU1X00
|
||||
#include "ohci-au1xxx.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver
|
||||
#endif
|
||||
|
||||
-#ifdef CONFIG_PNX8550
|
||||
-#include "ohci-pnx8550.c"
|
||||
-#endif
|
||||
+#ifdef CONFIG_PNX8550
|
||||
+#include "ohci-pnx8550.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
|
||||
#include "ohci-ppc-soc.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AT91
|
||||
#include "ohci-at91.c"
|
||||
+#define PLATFORM_DRIVER ohci_hcd_at91_driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_PNX4008
|
||||
#include "ohci-pnx4008.c"
|
||||
+#define PLATFORM_DRIVER usb_hcd_pnx4008_driver
|
||||
#endif
|
||||
|
||||
-#if !(defined(CONFIG_PCI) \
|
||||
- || defined(CONFIG_SA1111) \
|
||||
- || defined(CONFIG_ARCH_S3C2410) \
|
||||
- || defined(CONFIG_ARCH_OMAP) \
|
||||
- || defined (CONFIG_ARCH_LH7A404) \
|
||||
- || defined (CONFIG_PXA27x) \
|
||||
- || defined (CONFIG_ARCH_EP93XX) \
|
||||
- || defined (CONFIG_SOC_AU1X00) \
|
||||
- || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|
||||
- || defined (CONFIG_ARCH_AT91) \
|
||||
- || defined (CONFIG_ARCH_PNX4008) \
|
||||
- )
|
||||
+
|
||||
+#if !defined(PCI_DRIVER) && \
|
||||
+ !defined(PLATFORM_DRIVER) && \
|
||||
+ !defined(SA1111_DRIVER)
|
||||
#error "missing bus glue for ohci-hcd"
|
||||
#endif
|
||||
+
|
||||
+static int __init ohci_hcd_mod_init(void)
|
||||
+{
|
||||
+ int retval = 0;
|
||||
+ int ls = 0;
|
||||
+
|
||||
+ if (usb_disabled())
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name);
|
||||
+ pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
|
||||
+ sizeof (struct ed), sizeof (struct td));
|
||||
+
|
||||
+#ifdef PLATFORM_DRIVER
|
||||
+ retval = platform_driver_register(&PLATFORM_DRIVER);
|
||||
+ if (retval < 0)
|
||||
+ return retval;
|
||||
+ ls++;
|
||||
+#endif
|
||||
+
|
||||
+#ifdef SA1111_DRIVER
|
||||
+ retval = sa1111_driver_register(&SA1111_DRIVER);
|
||||
+ if (retval < 0)
|
||||
+ goto error;
|
||||
+ ls++;
|
||||
+#endif
|
||||
+
|
||||
+#ifdef PCI_DRIVER
|
||||
+ retval = pci_register_driver(&PCI_DRIVER);
|
||||
+ if (retval < 0)
|
||||
+ goto error;
|
||||
+ ls++;
|
||||
+#endif
|
||||
+
|
||||
+ return retval;
|
||||
+
|
||||
+ /* Error path */
|
||||
+error:
|
||||
+#ifdef PLATFORM_DRIVER
|
||||
+ if (ls--)
|
||||
+ platform_driver_unregister(&PLATFORM_DRIVER);
|
||||
+#endif
|
||||
+#ifdef SA1111_DRIVER
|
||||
+ if (ls--)
|
||||
+ sa1111_driver_unregister(&SA1111_DRIVER);
|
||||
+#endif
|
||||
+ return retval;
|
||||
+}
|
||||
+module_init(ohci_hcd_mod_init);
|
||||
+
|
||||
+static void __exit ohci_hcd_mod_exit(void)
|
||||
+{
|
||||
+#ifdef PCI_DRIVER
|
||||
+ pci_unregister_driver(&PCI_DRIVER);
|
||||
+#endif
|
||||
+#ifdef SA1111_DRIVER
|
||||
+ sa1111_driver_unregister(&SA1111_DRIVER);
|
||||
+#endif
|
||||
+#ifdef PLATFORM_DRIVER
|
||||
+ platform_driver_unregister(&PLATFORM_DRIVER);
|
||||
+#endif
|
||||
+}
|
||||
+module_exit(ohci_hcd_mod_exit);
|
||||
+
|
||||
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
|
||||
index e9807cf..4a043ab 100644
|
||||
--- a/drivers/usb/host/ohci-lh7a404.c
|
||||
+++ b/drivers/usb/host/ohci-lh7a404.c
|
||||
@@ -251,19 +251,3 @@ static struct platform_driver ohci_hcd_lh7a404_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_lh7a404_init (void)
|
||||
-{
|
||||
- pr_debug (DRIVER_INFO " (LH7A404)");
|
||||
- pr_debug ("block sizes: ed %d td %d\n",
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_lh7a404_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_lh7a404_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_lh7a404_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_lh7a404_init);
|
||||
-module_exit (ohci_hcd_lh7a404_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
|
||||
index 27be1f9..5cfa3d1 100644
|
||||
--- a/drivers/usb/host/ohci-omap.c
|
||||
+++ b/drivers/usb/host/ohci-omap.c
|
||||
@@ -544,22 +544,3 @@ static struct platform_driver ohci_hcd_omap_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_omap_init (void)
|
||||
-{
|
||||
- printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name);
|
||||
- if (usb_disabled())
|
||||
- return -ENODEV;
|
||||
-
|
||||
- pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_omap_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_omap_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_omap_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_omap_init);
|
||||
-module_exit (ohci_hcd_omap_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
|
||||
index 292daf0..b331ac4 100644
|
||||
--- a/drivers/usb/host/ohci-pci.c
|
||||
+++ b/drivers/usb/host/ohci-pci.c
|
||||
@@ -311,23 +311,3 @@ static struct pci_driver ohci_pci_driver = {
|
||||
.shutdown = usb_hcd_pci_shutdown,
|
||||
};
|
||||
|
||||
-
|
||||
-static int __init ohci_hcd_pci_init (void)
|
||||
-{
|
||||
- printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
|
||||
- if (usb_disabled())
|
||||
- return -ENODEV;
|
||||
-
|
||||
- pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
- return pci_register_driver (&ohci_pci_driver);
|
||||
-}
|
||||
-module_init (ohci_hcd_pci_init);
|
||||
-
|
||||
-/*-------------------------------------------------------------------------*/
|
||||
-
|
||||
-static void __exit ohci_hcd_pci_cleanup (void)
|
||||
-{
|
||||
- pci_unregister_driver (&ohci_pci_driver);
|
||||
-}
|
||||
-module_exit (ohci_hcd_pci_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
|
||||
index 3a8cbfb..893b172 100644
|
||||
--- a/drivers/usb/host/ohci-pnx4008.c
|
||||
+++ b/drivers/usb/host/ohci-pnx4008.c
|
||||
@@ -465,15 +465,3 @@ static struct platform_driver usb_hcd_pnx4008_driver = {
|
||||
.remove = usb_hcd_pnx4008_remove,
|
||||
};
|
||||
|
||||
-static int __init usb_hcd_pnx4008_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&usb_hcd_pnx4008_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit usb_hcd_pnx4008_cleanup(void)
|
||||
-{
|
||||
- return platform_driver_unregister(&usb_hcd_pnx4008_driver);
|
||||
-}
|
||||
-
|
||||
-module_init(usb_hcd_pnx4008_init);
|
||||
-module_exit(usb_hcd_pnx4008_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
|
||||
index 6922b91..de45eb0 100644
|
||||
--- a/drivers/usb/host/ohci-pnx8550.c
|
||||
+++ b/drivers/usb/host/ohci-pnx8550.c
|
||||
@@ -240,19 +240,3 @@ static struct platform_driver ohci_hcd_pnx8550_driver = {
|
||||
.remove = ohci_hcd_pnx8550_drv_remove,
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_pnx8550_init (void)
|
||||
-{
|
||||
- pr_debug (DRIVER_INFO " (pnx8550)");
|
||||
- pr_debug ("block sizes: ed %d td %d\n",
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_pnx8550_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_pnx8550_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_pnx8550_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_pnx8550_init);
|
||||
-module_exit (ohci_hcd_pnx8550_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
|
||||
index c7ce8e6..1a2e177 100644
|
||||
--- a/drivers/usb/host/ohci-ppc-soc.c
|
||||
+++ b/drivers/usb/host/ohci-ppc-soc.c
|
||||
@@ -208,19 +208,3 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_ppc_soc_init(void)
|
||||
-{
|
||||
- pr_debug(DRIVER_INFO " (PPC SOC)\n");
|
||||
- pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed),
|
||||
- sizeof(struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_ppc_soc_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_ppc_soc_cleanup(void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_ppc_soc_driver);
|
||||
-}
|
||||
-
|
||||
-module_init(ohci_hcd_ppc_soc_init);
|
||||
-module_exit(ohci_hcd_ppc_soc_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
|
||||
index 3bbea84..f1563dc 100644
|
||||
--- a/drivers/usb/host/ohci-pxa27x.c
|
||||
+++ b/drivers/usb/host/ohci-pxa27x.c
|
||||
@@ -369,19 +369,3 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_pxa27x_init (void)
|
||||
-{
|
||||
- pr_debug (DRIVER_INFO " (pxa27x)");
|
||||
- pr_debug ("block sizes: ed %d td %d\n",
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return platform_driver_register(&ohci_hcd_pxa27x_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_pxa27x_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_pxa27x_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_pxa27x_init);
|
||||
-module_exit (ohci_hcd_pxa27x_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
|
||||
index b350d45..6829814 100644
|
||||
--- a/drivers/usb/host/ohci-s3c2410.c
|
||||
+++ b/drivers/usb/host/ohci-s3c2410.c
|
||||
@@ -501,15 +501,3 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_s3c2410_init (void)
|
||||
-{
|
||||
- return platform_driver_register(&ohci_hcd_s3c2410_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_s3c2410_cleanup (void)
|
||||
-{
|
||||
- platform_driver_unregister(&ohci_hcd_s3c2410_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_s3c2410_init);
|
||||
-module_exit (ohci_hcd_s3c2410_cleanup);
|
||||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
|
||||
index fe0090e..0f48f2d 100644
|
||||
--- a/drivers/usb/host/ohci-sa1111.c
|
||||
+++ b/drivers/usb/host/ohci-sa1111.c
|
||||
@@ -269,19 +269,3 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = {
|
||||
.remove = ohci_hcd_sa1111_drv_remove,
|
||||
};
|
||||
|
||||
-static int __init ohci_hcd_sa1111_init (void)
|
||||
-{
|
||||
- dbg (DRIVER_INFO " (SA-1111)");
|
||||
- dbg ("block sizes: ed %d td %d",
|
||||
- sizeof (struct ed), sizeof (struct td));
|
||||
-
|
||||
- return sa1111_driver_register(&ohci_hcd_sa1111_driver);
|
||||
-}
|
||||
-
|
||||
-static void __exit ohci_hcd_sa1111_cleanup (void)
|
||||
-{
|
||||
- sa1111_driver_unregister(&ohci_hcd_sa1111_driver);
|
||||
-}
|
||||
-
|
||||
-module_init (ohci_hcd_sa1111_init);
|
||||
-module_exit (ohci_hcd_sa1111_cleanup);
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,35 +1,43 @@
|
|||
From bc515daf6d0845b0ddb739f3ba822b66f84344a7 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 12:55:37 +0100
|
||||
Subject: [PATCH] Add USB/OHCI glue for OpenFirmware devices
|
||||
From 944afcaa19737396ed514e3e845a3db2de9377f3 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Wed, 13 Dec 2006 21:03:30 +0100
|
||||
Subject: [PATCH] [PATCH] ohci: Add support for OHCI controller on the of_platform bus
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
PPC embedded systems can have a ohci controller builtin. In the
|
||||
new model, it will end up as a driver on the of_platform bus,
|
||||
this patches takes care of them.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/host/Kconfig | 19 +++
|
||||
drivers/usb/host/ohci-hcd.c | 6 +
|
||||
drivers/usb/host/ohci-ppc-of.c | 285 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 310 insertions(+), 0 deletions(-)
|
||||
drivers/usb/host/Kconfig | 23 ++++-
|
||||
drivers/usb/host/ohci-hcd.c | 20 ++++
|
||||
drivers/usb/host/ohci-ppc-of.c | 232 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 274 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
|
||||
index cf10cbc..f5ef6f5 100644
|
||||
index faabce8..c49715d 100644
|
||||
--- a/drivers/usb/host/Kconfig
|
||||
+++ b/drivers/usb/host/Kconfig
|
||||
@@ -106,6 +106,25 @@ config USB_OHCI_HCD_PPC_SOC
|
||||
@@ -107,9 +107,30 @@ config USB_OHCI_HCD_PPC_SOC
|
||||
Enables support for the USB controller on the MPC52xx or
|
||||
STB03xxx processor chip. If unsure, say Y.
|
||||
|
||||
+config USB_OHCI_HCD_PPC_OF
|
||||
+ bool "OHCI support for PPC USB controller for OpenFirmware platform"
|
||||
+ bool "OHCI support for PPC USB controller on OF platform bus"
|
||||
+ depends on USB_OHCI_HCD && PPC_OF
|
||||
+ default y
|
||||
+ ---help---
|
||||
+ Enables support for the USB controller PowerPC OpenFirmware platform
|
||||
+ Enables support for the USB controller PowerPC present on the
|
||||
+ OpenFirmware platform bus.
|
||||
+
|
||||
+config USB_OHCI_HCD_PPC_OF_BE
|
||||
+ bool "Support big endian HC"
|
||||
+ depends on USB_OHCI_HCD_PPC_OF
|
||||
+ default y
|
||||
+ select USB_OHCI_BIG_ENDIAN
|
||||
+ select USB_OHCI_BIG_ENDIAN_DESC
|
||||
+ select USB_OHCI_BIG_ENDIAN_MMIO
|
||||
+
|
||||
+config USB_OHCI_HCD_PPC_OF_LE
|
||||
+ bool "Support little endian HC"
|
||||
|
@ -39,156 +47,91 @@ index cf10cbc..f5ef6f5 100644
|
|||
+
|
||||
config USB_OHCI_HCD_PCI
|
||||
bool "OHCI support for PCI-bus USB controllers"
|
||||
depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx)
|
||||
- depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx)
|
||||
+ depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF)
|
||||
default y
|
||||
select USB_OHCI_LITTLE_ENDIAN
|
||||
---help---
|
||||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
|
||||
index 9be6b30..04413b6 100644
|
||||
index 9926b8f..c6ae1ff 100644
|
||||
--- a/drivers/usb/host/ohci-hcd.c
|
||||
+++ b/drivers/usb/host/ohci-hcd.c
|
||||
@@ -930,6 +930,10 @@ #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC
|
||||
#include "ohci-ppc-soc.c"
|
||||
@@ -914,8 +914,14 @@ MODULE_LICENSE ("GPL");
|
||||
#endif
|
||||
|
||||
|
||||
+#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
|
||||
+#include "ohci-ppc-of.c"
|
||||
+#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver
|
||||
+#endif
|
||||
+
|
||||
#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
|
||||
#include "ohci-at91.c"
|
||||
#endif
|
||||
@@ -950,6 +954,8 @@ #if !(defined(CONFIG_PCI) \
|
||||
|| defined (CONFIG_ARCH_AT91RM9200) \
|
||||
|| defined (CONFIG_ARCH_AT91SAM9261) \
|
||||
|| defined (CONFIG_ARCH_PNX4008) \
|
||||
+ || defined (CONFIG_USB_OHCI_HCD_PPC_OF_LE) \
|
||||
+ || defined (CONFIG_USB_OHCI_HCD_PPC_OF_BE) \
|
||||
)
|
||||
#if !defined(PCI_DRIVER) && \
|
||||
!defined(PLATFORM_DRIVER) && \
|
||||
+ !defined(OF_PLATFORM_DRIVER) && \
|
||||
!defined(SA1111_DRIVER)
|
||||
#error "missing bus glue for ohci-hcd"
|
||||
#endif
|
||||
@@ -939,6 +945,13 @@ static int __init ohci_hcd_mod_init(void)
|
||||
ls++;
|
||||
#endif
|
||||
|
||||
+#ifdef OF_PLATFORM_DRIVER
|
||||
+ retval = of_register_platform_driver(&OF_PLATFORM_DRIVER);
|
||||
+ if (retval < 0)
|
||||
+ goto error;
|
||||
+ ls++;
|
||||
+#endif
|
||||
+
|
||||
#ifdef SA1111_DRIVER
|
||||
retval = sa1111_driver_register(&SA1111_DRIVER);
|
||||
if (retval < 0)
|
||||
@@ -961,6 +974,10 @@ error:
|
||||
if (ls--)
|
||||
platform_driver_unregister(&PLATFORM_DRIVER);
|
||||
#endif
|
||||
+#ifdef OF_PLATFORM_DRIVER
|
||||
+ if (ls--)
|
||||
+ of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
|
||||
+#endif
|
||||
#ifdef SA1111_DRIVER
|
||||
if (ls--)
|
||||
sa1111_driver_unregister(&SA1111_DRIVER);
|
||||
@@ -977,6 +994,9 @@ static void __exit ohci_hcd_mod_exit(void)
|
||||
#ifdef SA1111_DRIVER
|
||||
sa1111_driver_unregister(&SA1111_DRIVER);
|
||||
#endif
|
||||
+#ifdef OF_PLATFORM_DRIVER
|
||||
+ of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
|
||||
+#endif
|
||||
#ifdef PLATFORM_DRIVER
|
||||
platform_driver_unregister(&PLATFORM_DRIVER);
|
||||
#endif
|
||||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
|
||||
new file mode 100644
|
||||
index 0000000..30ce520
|
||||
index 0000000..84b555b
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/host/ohci-ppc-of.c
|
||||
@@ -0,0 +1,285 @@
|
||||
@@ -0,0 +1,232 @@
|
||||
+/*
|
||||
+ * OHCI HCD (Host Controller Driver) for USB.
|
||||
+ *
|
||||
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
|
||||
+ * (C) Copyright 2002 Hewlett-Packard Company
|
||||
+ * (C) Copyright 2003-2005 MontaVista Software Inc.
|
||||
+ * (C) Copyright 2006 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ *
|
||||
+ * Probe and init OHCI Big endian HC from OpenFirmware device tree
|
||||
+ * Tested on Efika 5k2
|
||||
+ * Bus glue for OHCI HC on the of_platform bus
|
||||
+ *
|
||||
+ * Modified by Dale Farnsworth <dale@farnsworth.org> from ohci-sa1111.c
|
||||
+ * Modified for of_platform bus from ohci-sa1111.c
|
||||
+ *
|
||||
+ * This file is licenced under the GPL.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/signal.h>
|
||||
+
|
||||
+#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
+#include <asm/prom.h>
|
||||
+
|
||||
+/* configure so an HC device and id are always provided */
|
||||
+/* always called with process context; sleeping is OK */
|
||||
+
|
||||
+/*
|
||||
+ * usb_hcd_ppc_of_probe - initialize On-Chip HCDs
|
||||
+ * Context: !in_interrupt()
|
||||
+ *
|
||||
+ * Allocates basic resources for this USB host controller.
|
||||
+ *
|
||||
+ * Store this function in the HCD's struct pci_driver as probe().
|
||||
+ */
|
||||
+static int usb_hcd_ppc_of_probe(const struct hc_driver *driver,
|
||||
+ struct of_device *dev, int is_bigendian)
|
||||
+{
|
||||
+ int retval;
|
||||
+ struct usb_hcd *hcd;
|
||||
+ struct ohci_hcd *ohci;
|
||||
+ struct resource res;
|
||||
+ int irq;
|
||||
+ int ret;
|
||||
+
|
||||
+ pr_debug("initializing PPC-OF USB Controller\n");
|
||||
+
|
||||
+ if ((ret = of_address_to_resource(dev->node, 0, &res)) != 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ hcd = usb_create_hcd(driver, &dev->dev, "PPC-OF USB");
|
||||
+ if (!hcd)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hcd->rsrc_start = res.start;
|
||||
+ hcd->rsrc_len = res.end - res.start + 1;
|
||||
+
|
||||
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
|
||||
+ pr_debug(__FILE__ ": request_mem_region failed\n");
|
||||
+ retval = -EBUSY;
|
||||
+ goto err1;
|
||||
+ }
|
||||
+
|
||||
+ irq = irq_of_parse_and_map(dev->node, 0);
|
||||
+ if (irq == NO_IRQ) {
|
||||
+ retval = -EBUSY;
|
||||
+ goto err2;
|
||||
+ }
|
||||
+
|
||||
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+ if (!hcd->regs) {
|
||||
+ pr_debug(__FILE__ ": ioremap failed\n");
|
||||
+ retval = -ENOMEM;
|
||||
+ goto err2;
|
||||
+ }
|
||||
+
|
||||
+ ohci = hcd_to_ohci(hcd);
|
||||
+ if (is_bigendian)
|
||||
+ ohci->flags |= OHCI_BIG_ENDIAN;
|
||||
+
|
||||
+ ohci_hcd_init(ohci);
|
||||
+
|
||||
+ retval = usb_add_hcd(hcd, irq, 0);
|
||||
+ if (retval == 0)
|
||||
+ return retval;
|
||||
+
|
||||
+ pr_debug("Removing PPC-OF USB Controller\n");
|
||||
+
|
||||
+ iounmap(hcd->regs);
|
||||
+ err2:
|
||||
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+ err1:
|
||||
+ usb_put_hcd(hcd);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* may be called without controller electrically present */
|
||||
+/* may be called with controller, bus, and devices active */
|
||||
+
|
||||
+/*
|
||||
+ * usb_hcd_ppc_of_remove - shutdown processing for On-Chip HCDs
|
||||
+ * @pdev: USB Host Controller being removed
|
||||
+ * Context: !in_interrupt()
|
||||
+ *
|
||||
+ * Reverses the effect of usb_hcd_ppc_of_probe().
|
||||
+ * It is always called from a thread
|
||||
+ * context, normally "rmmod", "apmd", or something similar.
|
||||
+ *
|
||||
+ */
|
||||
+static void usb_hcd_ppc_of_remove(struct usb_hcd *hcd,
|
||||
+ struct of_device *op)
|
||||
+{
|
||||
+ usb_remove_hcd(hcd);
|
||||
+
|
||||
+ pr_debug("stopping PPC-OF USB Controller\n");
|
||||
+
|
||||
+ iounmap(hcd->regs);
|
||||
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+ usb_put_hcd(hcd);
|
||||
+}
|
||||
+
|
||||
+static int __devinit
|
||||
+ohci_ppc_of_start(struct usb_hcd *hcd)
|
||||
|
@ -210,6 +153,7 @@ index 0000000..30ce520
|
|||
+
|
||||
+static const struct hc_driver ohci_ppc_of_hc_driver = {
|
||||
+ .description = hcd_name,
|
||||
+ .product_desc = "OF OHCI",
|
||||
+ .hcd_priv_size = sizeof(struct ohci_hcd),
|
||||
+
|
||||
+ /*
|
||||
|
@ -251,17 +195,98 @@ index 0000000..30ce520
|
|||
+};
|
||||
+
|
||||
+
|
||||
+static int __devinit
|
||||
+ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
|
||||
+{
|
||||
+ struct device_node *dn = op->node;
|
||||
+ struct usb_hcd *hcd;
|
||||
+ struct ohci_hcd *ohci;
|
||||
+ struct resource res;
|
||||
+ int irq;
|
||||
+
|
||||
+static int ohci_hcd_ppc_of_drv_remove(struct of_device *op)
|
||||
+ int rv;
|
||||
+ int is_bigendian;
|
||||
+
|
||||
+ if (usb_disabled())
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ is_bigendian =
|
||||
+ device_is_compatible(dn, "ohci-bigendian") ||
|
||||
+ device_is_compatible(dn, "ohci-be");;
|
||||
+
|
||||
+ dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
|
||||
+
|
||||
+ rv = of_address_to_resource(dn, 0, &res);
|
||||
+ if (rv)
|
||||
+ return rv;
|
||||
+
|
||||
+ hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB");
|
||||
+ if (!hcd)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hcd->rsrc_start = res.start;
|
||||
+ hcd->rsrc_len = res.end - res.start + 1;
|
||||
+
|
||||
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
|
||||
+ printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
|
||||
+ rv = -EBUSY;
|
||||
+ goto err_rmr;
|
||||
+ }
|
||||
+
|
||||
+ irq = irq_of_parse_and_map(dn, 0);
|
||||
+ if (irq == NO_IRQ) {
|
||||
+ printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
|
||||
+ rv = -EBUSY;
|
||||
+ goto err_irq;
|
||||
+ }
|
||||
+
|
||||
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+ if (!hcd->regs) {
|
||||
+ printk(KERN_ERR __FILE__ ": ioremap failed\n");
|
||||
+ rv = -ENOMEM;
|
||||
+ goto err_ioremap;
|
||||
+ }
|
||||
+
|
||||
+ ohci = hcd_to_ohci(hcd);
|
||||
+ if (is_bigendian)
|
||||
+ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
|
||||
+
|
||||
+ ohci_hcd_init(ohci);
|
||||
+
|
||||
+ rv = usb_add_hcd(hcd, irq, 0);
|
||||
+ if (rv == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ iounmap(hcd->regs);
|
||||
+err_ioremap:
|
||||
+ irq_dispose_mapping(irq);
|
||||
+err_irq:
|
||||
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+err_rmr:
|
||||
+ usb_put_hcd(hcd);
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static int ohci_hcd_ppc_of_remove(struct of_device *op)
|
||||
+{
|
||||
+ struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
|
||||
+ dev_set_drvdata(&op->dev, NULL);
|
||||
+
|
||||
+ usb_hcd_ppc_of_remove(hcd, op);
|
||||
+ dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n");
|
||||
+
|
||||
+ usb_remove_hcd(hcd);
|
||||
+
|
||||
+ iounmap(hcd->regs);
|
||||
+ irq_dispose_mapping(hcd->irq);
|
||||
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
+
|
||||
+ usb_put_hcd(hcd);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ohci_hcd_ppc_of_drv_shutdown(struct of_device *op)
|
||||
+static int ohci_hcd_ppc_of_shutdown(struct of_device *op)
|
||||
+{
|
||||
+ struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
|
||||
+
|
||||
|
@ -271,9 +296,6 @@ index 0000000..30ce520
|
|||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ *
|
||||
+*/
|
||||
+
|
||||
+static struct of_device_id ohci_hcd_ppc_of_match[] = {
|
||||
+#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE
|
||||
|
@ -298,37 +320,21 @@ index 0000000..30ce520
|
|||
+#endif
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
|
||||
+
|
||||
+static int __devinit
|
||||
+ohci_hcd_ppc_of_drv_probe(struct of_device *op, const struct of_device_id *match)
|
||||
+{
|
||||
+ struct device_node *dev;
|
||||
+ int ret;
|
||||
+ int is_bigendian;
|
||||
+#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
|
||||
+ !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
|
||||
+#error "No endianess selected for ppc-of-ohci"
|
||||
+#endif
|
||||
+
|
||||
+ if (usb_disabled())
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ dev = op->node;
|
||||
+ is_bigendian = 0;
|
||||
+
|
||||
+ if ( device_is_compatible(dev, "ohci-bigendian") )
|
||||
+ is_bigendian = 1;
|
||||
+
|
||||
+ if ( device_is_compatible(dev, "ohci-be") )
|
||||
+ is_bigendian = 1;
|
||||
+
|
||||
+ ret = usb_hcd_ppc_of_probe(&ohci_ppc_of_hc_driver, op, is_bigendian);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct of_platform_driver ohci_hcd_ppc_of_driver = {
|
||||
+ .name = "ppc-of-ohci",
|
||||
+ .match_table = ohci_hcd_ppc_of_match,
|
||||
+ .probe = ohci_hcd_ppc_of_drv_probe,
|
||||
+ .remove = ohci_hcd_ppc_of_drv_remove,
|
||||
+ .shutdown = ohci_hcd_ppc_of_drv_shutdown,
|
||||
+#ifdef CONFIG_PM
|
||||
+ .probe = ohci_hcd_ppc_of_probe,
|
||||
+ .remove = ohci_hcd_ppc_of_remove,
|
||||
+ .shutdown = ohci_hcd_ppc_of_shutdown,
|
||||
+#ifdef CONFIG_PM
|
||||
+ /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
|
||||
+ /*.resume = ohci_hcd_ppc_soc_drv_resume,*/
|
||||
+#endif
|
||||
|
@ -338,23 +344,6 @@ index 0000000..30ce520
|
|||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ohci_hcd_ppc_of_init(void)
|
||||
+{
|
||||
+ pr_debug(DRIVER_INFO " (PPC OF)\n");
|
||||
+ pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed),
|
||||
+ sizeof(struct td));
|
||||
+
|
||||
+ return of_register_platform_driver(&ohci_hcd_ppc_of_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit ohci_hcd_ppc_of_cleanup(void)
|
||||
+{
|
||||
+ of_unregister_platform_driver(&ohci_hcd_ppc_of_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(ohci_hcd_ppc_of_init);
|
||||
+module_exit(ohci_hcd_ppc_of_cleanup);
|
||||
+
|
||||
--
|
||||
1.4.3.2
|
||||
1.4.4.2
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,21 +1,24 @@
|
|||
From bb6dea9b9a251e42efcec030af2d5272d5d5714a Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:01:30 +0100
|
||||
Subject: [PATCH] Add MPC5200 CPU/PIO driver using libata
|
||||
From 83ebd6314e55f9baf2c4e795397346b338274ef5 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Fri, 8 Dec 2006 00:08:14 +0100
|
||||
Subject: [PATCH] [PATCH] libata: Add support for the MPC52xx ATA controller
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
This patch adds initial libata support for the Freescale
|
||||
MPC5200 integrated IDE controller.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
Signed-off-by: Jeff Garzik <jeff@garzik.org>
|
||||
---
|
||||
drivers/ata/Kconfig | 9 +
|
||||
drivers/ata/Makefile | 1 +
|
||||
drivers/ata/pata_mpc52xx.c | 510 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/ata/pata_mpc52xx.h | 107 +++++++++
|
||||
4 files changed, 627 insertions(+), 0 deletions(-)
|
||||
drivers/ata/pata_mpc52xx.c | 563 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 573 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
|
||||
index 03f6338..be01ddf 100644
|
||||
index b34e0a9..fa1d327 100644
|
||||
--- a/drivers/ata/Kconfig
|
||||
+++ b/drivers/ata/Kconfig
|
||||
@@ -328,6 +328,15 @@ config PATA_TRIFLEX
|
||||
@@ -337,6 +337,15 @@ config PATA_MARVELL
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
|
@ -32,23 +35,23 @@ index 03f6338..be01ddf 100644
|
|||
tristate "Intel PATA MPIIX support"
|
||||
depends on PCI
|
||||
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
|
||||
index 72243a6..e3a741c 100644
|
||||
index bc3d81a..3081e1f 100644
|
||||
--- a/drivers/ata/Makefile
|
||||
+++ b/drivers/ata/Makefile
|
||||
@@ -38,6 +38,7 @@ obj-$(CONFIG_PATA_NETCELL) += pata_netce
|
||||
@@ -38,6 +38,7 @@ obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
|
||||
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
|
||||
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
|
||||
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
|
||||
+obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
|
||||
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
|
||||
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
|
||||
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
|
||||
obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
|
||||
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
|
||||
new file mode 100644
|
||||
index 0000000..c75d4c9
|
||||
index 0000000..8b7019a
|
||||
--- /dev/null
|
||||
+++ b/drivers/ata/pata_mpc52xx.c
|
||||
@@ -0,0 +1,510 @@
|
||||
@@ -0,0 +1,563 @@
|
||||
+/*
|
||||
+ * drivers/ata/pata_mpc52xx.c
|
||||
+ *
|
||||
|
@ -65,15 +68,15 @@ index 0000000..c75d4c9
|
|||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/libata.h>
|
||||
+
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/types.h>
|
||||
+#include <asm/prom.h>
|
||||
+#include <asm/of_platform.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+
|
||||
+#include "pata_mpc52xx.h"
|
||||
+
|
||||
+
|
||||
+#define DRV_NAME "mpc52xx_ata"
|
||||
+#define DRV_VERSION "0.1.0"
|
||||
|
@ -106,38 +109,91 @@ index 0000000..c75d4c9
|
|||
+#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
|
||||
+
|
||||
+
|
||||
+/* Bit definitions inside the registers */
|
||||
+#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
|
||||
+#define MPC52xx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */
|
||||
+#define MPC52xx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt in PIO */
|
||||
+#define MPC52xx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports IORDY protocol */
|
||||
+
|
||||
+#define MPC52xx_ATA_HOSTSTAT_TIP 0x80000000UL /* Transaction in progress */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_UREP 0x40000000UL /* UDMA Read Extended Pause */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_RERR 0x02000000UL /* Read Error */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
|
||||
+
|
||||
+#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
|
||||
+
|
||||
+#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
|
||||
+#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
|
||||
+#define MPC52xx_ATA_DMAMODE_UDMA 0x04 /* UDMA enabled */
|
||||
+#define MPC52xx_ATA_DMAMODE_IE 0x08 /* Enable drive interrupt to CPU in DMA mode */
|
||||
+#define MPC52xx_ATA_DMAMODE_FE 0x10 /* FIFO Flush enable in Rx mode */
|
||||
+#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
|
||||
+#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
|
||||
+
|
||||
+
|
||||
+/* Structure of the hardware registers */
|
||||
+struct mpc52xx_ata {
|
||||
+
|
||||
+ /* Host interface registers */
|
||||
+ u32 config; /* ATA + 0x00 Host configuration */
|
||||
+ u32 host_status; /* ATA + 0x04 Host controller status */
|
||||
+ u32 pio1; /* ATA + 0x08 PIO Timing 1 */
|
||||
+ u32 pio2; /* ATA + 0x0c PIO Timing 2 */
|
||||
+ u32 mdma1; /* ATA + 0x10 MDMA Timing 1 */
|
||||
+ u32 mdma2; /* ATA + 0x14 MDMA Timing 2 */
|
||||
+ u32 udma1; /* ATA + 0x18 UDMA Timing 1 */
|
||||
+ u32 udma2; /* ATA + 0x1c UDMA Timing 2 */
|
||||
+ u32 udma3; /* ATA + 0x20 UDMA Timing 3 */
|
||||
+ u32 udma4; /* ATA + 0x24 UDMA Timing 4 */
|
||||
+ u32 udma5; /* ATA + 0x28 UDMA Timing 5 */
|
||||
+ u32 share_cnt; /* ATA + 0x2c ATA share counter */
|
||||
+ u32 reserved0[3];
|
||||
+
|
||||
+ /* FIFO registers */
|
||||
+ u32 fifo_data; /* ATA + 0x3c */
|
||||
+ u8 fifo_status_frame; /* ATA + 0x40 */
|
||||
+ u8 fifo_status; /* ATA + 0x41 */
|
||||
+ u16 reserved7[1];
|
||||
+ u8 fifo_control; /* ATA + 0x44 */
|
||||
+ u8 reserved8[5];
|
||||
+ u16 fifo_alarm; /* ATA + 0x4a */
|
||||
+ u16 reserved9;
|
||||
+ u16 fifo_rdp; /* ATA + 0x4e */
|
||||
+ u16 reserved10;
|
||||
+ u16 fifo_wrp; /* ATA + 0x52 */
|
||||
+ u16 reserved11;
|
||||
+ u16 fifo_lfrdp; /* ATA + 0x56 */
|
||||
+ u16 reserved12;
|
||||
+ u16 fifo_lfwrp; /* ATA + 0x5a */
|
||||
+
|
||||
+ /* Drive TaskFile registers */
|
||||
+ u8 tf_control; /* ATA + 0x5c TASKFILE Control/Alt Status */
|
||||
+ u8 reserved13[3];
|
||||
+ u16 tf_data; /* ATA + 0x60 TASKFILE Data */
|
||||
+ u16 reserved14;
|
||||
+ u8 tf_features; /* ATA + 0x64 TASKFILE Features/Error */
|
||||
+ u8 reserved15[3];
|
||||
+ u8 tf_sec_count; /* ATA + 0x68 TASKFILE Sector Count */
|
||||
+ u8 reserved16[3];
|
||||
+ u8 tf_sec_num; /* ATA + 0x6c TASKFILE Sector Number */
|
||||
+ u8 reserved17[3];
|
||||
+ u8 tf_cyl_low; /* ATA + 0x70 TASKFILE Cylinder Low */
|
||||
+ u8 reserved18[3];
|
||||
+ u8 tf_cyl_high; /* ATA + 0x74 TASKFILE Cylinder High */
|
||||
+ u8 reserved19[3];
|
||||
+ u8 tf_dev_head; /* ATA + 0x78 TASKFILE Device/Head */
|
||||
+ u8 reserved20[3];
|
||||
+ u8 tf_command; /* ATA + 0x7c TASKFILE Command/Status */
|
||||
+ u8 dma_mode; /* ATA + 0x7d ATA Host DMA Mode configuration */
|
||||
+ u8 reserved21[2];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Aux fns */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+
|
||||
+/* OF device tree */
|
||||
+
|
||||
+static unsigned int
|
||||
+mpc52xx_find_ipb_freq(struct device_node *on)
|
||||
+{
|
||||
+ struct device_node *onp;
|
||||
+ const unsigned int *p_ipb_freq = NULL;
|
||||
+
|
||||
+ of_node_get(on);
|
||||
+ while (on) {
|
||||
+ p_ipb_freq = get_property(on, "bus-frequency", NULL);
|
||||
+
|
||||
+ if (p_ipb_freq)
|
||||
+ break;
|
||||
+
|
||||
+ onp = of_get_parent(on);
|
||||
+ of_node_put(on);
|
||||
+ on = onp;
|
||||
+ }
|
||||
+
|
||||
+ if (on)
|
||||
+ of_node_put(on);
|
||||
+
|
||||
+ return p_ipb_freq ? *p_ipb_freq : 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* MPC52xx low level hw control */
|
||||
+
|
||||
+static int
|
||||
|
@ -559,119 +615,6 @@ index 0000000..c75d4c9
|
|||
+MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
|
||||
+MODULE_VERSION(DRV_VERSION);
|
||||
+
|
||||
diff --git a/drivers/ata/pata_mpc52xx.h b/drivers/ata/pata_mpc52xx.h
|
||||
new file mode 100644
|
||||
index 0000000..2430ae2
|
||||
--- /dev/null
|
||||
+++ b/drivers/ata/pata_mpc52xx.h
|
||||
@@ -0,0 +1,107 @@
|
||||
+/*
|
||||
+ * drivers/ata/pata_mpc52xx.h
|
||||
+ *
|
||||
+ * Definitions for the Freescale MPC52xx on-chip IDE interface
|
||||
+ *
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PATA_MPC52xx_H__
|
||||
+#define __PATA_MPC52xx_H__
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/ide.h>
|
||||
+#include <asm/types.h>
|
||||
+#include <asm/io.h>
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* Bit definitions inside the registers */
|
||||
+
|
||||
+#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
|
||||
+#define MPC52xx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */
|
||||
+#define MPC52xx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt in PIO */
|
||||
+#define MPC52xx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports IORDY protocol */
|
||||
+
|
||||
+#define MPC52xx_ATA_HOSTSTAT_TIP 0x80000000UL /* Transaction in progress */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_UREP 0x40000000UL /* UDMA Read Extended Pause */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_RERR 0x02000000UL /* Read Error */
|
||||
+#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
|
||||
+
|
||||
+#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
|
||||
+
|
||||
+#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
|
||||
+#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
|
||||
+#define MPC52xx_ATA_DMAMODE_UDMA 0x04 /* UDMA enabled */
|
||||
+#define MPC52xx_ATA_DMAMODE_IE 0x08 /* Enable drive interrupt to CPU in DMA mode */
|
||||
+#define MPC52xx_ATA_DMAMODE_FE 0x10 /* FIFO Flush enable in Rx mode */
|
||||
+#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
|
||||
+#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
|
||||
+
|
||||
+
|
||||
+/* Structure of the hardware registers */
|
||||
+struct mpc52xx_ata {
|
||||
+
|
||||
+ /* Host interface registers */
|
||||
+ u32 config; /* ATA + 0x00 Host configuration */
|
||||
+ u32 host_status; /* ATA + 0x04 Host controller status */
|
||||
+ u32 pio1; /* ATA + 0x08 PIO Timing 1 */
|
||||
+ u32 pio2; /* ATA + 0x0c PIO Timing 2 */
|
||||
+ u32 mdma1; /* ATA + 0x10 MDMA Timing 1 */
|
||||
+ u32 mdma2; /* ATA + 0x14 MDMA Timing 2 */
|
||||
+ u32 udma1; /* ATA + 0x18 UDMA Timing 1 */
|
||||
+ u32 udma2; /* ATA + 0x1c UDMA Timing 2 */
|
||||
+ u32 udma3; /* ATA + 0x20 UDMA Timing 3 */
|
||||
+ u32 udma4; /* ATA + 0x24 UDMA Timing 4 */
|
||||
+ u32 udma5; /* ATA + 0x28 UDMA Timing 5 */
|
||||
+ u32 share_cnt; /* ATA + 0x2c ATA share counter */
|
||||
+ u32 reserved0[3];
|
||||
+
|
||||
+ /* FIFO registers */
|
||||
+ u32 fifo_data; /* ATA + 0x3c */
|
||||
+ u8 fifo_status_frame; /* ATA + 0x40 */
|
||||
+ u8 fifo_status; /* ATA + 0x41 */
|
||||
+ u16 reserved7[1];
|
||||
+ u8 fifo_control; /* ATA + 0x44 */
|
||||
+ u8 reserved8[5];
|
||||
+ u16 fifo_alarm; /* ATA + 0x4a */
|
||||
+ u16 reserved9;
|
||||
+ u16 fifo_rdp; /* ATA + 0x4e */
|
||||
+ u16 reserved10;
|
||||
+ u16 fifo_wrp; /* ATA + 0x52 */
|
||||
+ u16 reserved11;
|
||||
+ u16 fifo_lfrdp; /* ATA + 0x56 */
|
||||
+ u16 reserved12;
|
||||
+ u16 fifo_lfwrp; /* ATA + 0x5a */
|
||||
+
|
||||
+ /* Drive TaskFile registers */
|
||||
+ u8 tf_control; /* ATA + 0x5c TASKFILE Control/Alt Status */
|
||||
+ u8 reserved13[3];
|
||||
+ u16 tf_data; /* ATA + 0x60 TASKFILE Data */
|
||||
+ u16 reserved14;
|
||||
+ u8 tf_features; /* ATA + 0x64 TASKFILE Features/Error */
|
||||
+ u8 reserved15[3];
|
||||
+ u8 tf_sec_count; /* ATA + 0x68 TASKFILE Sector Count */
|
||||
+ u8 reserved16[3];
|
||||
+ u8 tf_sec_num; /* ATA + 0x6c TASKFILE Sector Number */
|
||||
+ u8 reserved17[3];
|
||||
+ u8 tf_cyl_low; /* ATA + 0x70 TASKFILE Cylinder Low */
|
||||
+ u8 reserved18[3];
|
||||
+ u8 tf_cyl_high; /* ATA + 0x74 TASKFILE Cylinder High */
|
||||
+ u8 reserved19[3];
|
||||
+ u8 tf_dev_head; /* ATA + 0x78 TASKFILE Device/Head */
|
||||
+ u8 reserved20[3];
|
||||
+ u8 tf_command; /* ATA + 0x7c TASKFILE Command/Status */
|
||||
+ u8 dma_mode; /* ATA + 0x7d ATA Host DMA Mode configuration */
|
||||
+ u8 reserved21[2];
|
||||
+};
|
||||
+
|
||||
+#endif /* __PATA_MPC52xx_H__ */
|
||||
+
|
||||
--
|
||||
1.4.3.2
|
||||
1.4.4.2
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 473274f1f615316cf5828caa47704f4d2f9ad1be Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:34:18 +0100
|
||||
Subject: [PATCH] Filter out efika
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
arch/powerpc/platforms/chrp/setup.c | 9 +++++++++
|
||||
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
|
||||
index 49b8dab..1337da8 100644
|
||||
--- a/arch/powerpc/platforms/chrp/setup.c
|
||||
+++ b/arch/powerpc/platforms/chrp/setup.c
|
||||
@@ -580,11 +580,20 @@ static int __init chrp_probe(void)
|
||||
{
|
||||
char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"device_type", NULL);
|
||||
+
|
||||
+ char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
+ "model", NULL);
|
||||
if (dtype == NULL)
|
||||
return 0;
|
||||
if (strcmp(dtype, "chrp"))
|
||||
return 0;
|
||||
|
||||
+ /*
|
||||
+ * Filter out efika because it has its own platform
|
||||
+ */
|
||||
+ if (model && (strcmp(model, "EFIKA5K2") == 0) )
|
||||
+ return 0;
|
||||
+
|
||||
ISA_DMA_THRESHOLD = ~0L;
|
||||
DMA_MODE_READ = 0x44;
|
||||
DMA_MODE_WRITE = 0x48;
|
||||
--
|
||||
1.4.3.2
|
||||
|
38
debian/patches/features/powerpc/efika/0011-ohci-Whitespace-and-typo-fix-in-ohci-ppc-of.c.txt
vendored
Normal file
38
debian/patches/features/powerpc/efika/0011-ohci-Whitespace-and-typo-fix-in-ohci-ppc-of.c.txt
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
From 947dc060772ceb8b33a35bd2ded245908fa9442f Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 22:16:05 +0100
|
||||
Subject: [PATCH] [PATCH] ohci: Whitespace and typo fix in ohci-ppc-of.c
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
drivers/usb/host/ohci-ppc-of.c | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
|
||||
index 84b555b..08e237c 100644
|
||||
--- a/drivers/usb/host/ohci-ppc-of.c
|
||||
+++ b/drivers/usb/host/ohci-ppc-of.c
|
||||
@@ -96,9 +96,9 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
- is_bigendian =
|
||||
+ is_bigendian =
|
||||
device_is_compatible(dn, "ohci-bigendian") ||
|
||||
- device_is_compatible(dn, "ohci-be");;
|
||||
+ device_is_compatible(dn, "ohci-be");
|
||||
|
||||
dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
|
||||
|
||||
@@ -206,7 +206,7 @@ static struct of_device_id ohci_hcd_ppc_of_match[] = {
|
||||
#endif
|
||||
{},
|
||||
};
|
||||
-MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
|
||||
+MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
|
||||
|
||||
#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
|
||||
!defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,900 +0,0 @@
|
|||
From 2842fd40de284f328016997ba40d7b83823510c5 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:49:57 +0100
|
||||
Subject: [PATCH] Backport of_platform
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
arch/powerpc/kernel/Makefile | 2 +-
|
||||
arch/powerpc/kernel/of_device.c | 172 +++------------
|
||||
arch/powerpc/kernel/of_platform.c | 374 +++++++++++++++++++++++++++++++
|
||||
arch/powerpc/platforms/powermac/setup.c | 1 +
|
||||
drivers/macintosh/smu.c | 3 +-
|
||||
drivers/macintosh/therm_adt746x.c | 2 +-
|
||||
drivers/macintosh/therm_pm72.c | 5 +-
|
||||
drivers/macintosh/therm_windtunnel.c | 7 +-
|
||||
drivers/video/platinumfb.c | 5 +-
|
||||
include/asm-powerpc/of_device.h | 34 +---
|
||||
include/asm-powerpc/of_platform.h | 60 +++++
|
||||
11 files changed, 478 insertions(+), 187 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
|
||||
index 7af23c4..6d9476f 100644
|
||||
--- a/arch/powerpc/kernel/Makefile
|
||||
+++ b/arch/powerpc/kernel/Makefile
|
||||
@@ -21,7 +21,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfm
|
||||
obj-$(CONFIG_PPC64) += vdso64/
|
||||
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
|
||||
obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
|
||||
-obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
|
||||
+obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o
|
||||
procfs-$(CONFIG_PPC64) := proc_ppc64.o
|
||||
obj-$(CONFIG_PROC_FS) += $(procfs-y)
|
||||
rtaspci-$(CONFIG_PPC64) := rtas_pci.o
|
||||
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
|
||||
index 397c83e..5c65398 100644
|
||||
--- a/arch/powerpc/kernel/of_device.c
|
||||
+++ b/arch/powerpc/kernel/of_device.c
|
||||
@@ -9,30 +9,26 @@ #include <asm/errno.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/**
|
||||
- * of_match_device - Tell if an of_device structure has a matching
|
||||
- * of_match structure
|
||||
+ * of_match_node - Tell if an device_node has a matching of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
- * @dev: the of device structure to match against
|
||||
+ * @node: the of device structure to match against
|
||||
*
|
||||
- * Used by a driver to check whether an of_device present in the
|
||||
- * system is in its list of supported devices.
|
||||
+ * Low level utility function used by device matching.
|
||||
*/
|
||||
-const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
- const struct of_device *dev)
|
||||
+const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
+ const struct device_node *node)
|
||||
{
|
||||
- if (!dev->node)
|
||||
- return NULL;
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
- match &= dev->node->name
|
||||
- && !strcmp(matches->name, dev->node->name);
|
||||
+ match &= node->name
|
||||
+ && !strcmp(matches->name, node->name);
|
||||
if (matches->type[0])
|
||||
- match &= dev->node->type
|
||||
- && !strcmp(matches->type, dev->node->type);
|
||||
+ match &= node->type
|
||||
+ && !strcmp(matches->type, node->type);
|
||||
if (matches->compatible[0])
|
||||
- match &= device_is_compatible(dev->node,
|
||||
- matches->compatible);
|
||||
+ match &= device_is_compatible(node,
|
||||
+ matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
@@ -40,16 +36,21 @@ const struct of_device_id *of_match_devi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
+/**
|
||||
+ * of_match_device - Tell if an of_device structure has a matching
|
||||
+ * of_match structure
|
||||
+ * @ids: array of of device match structures to search in
|
||||
+ * @dev: the of device structure to match against
|
||||
+ *
|
||||
+ * Used by a driver to check whether an of_device present in the
|
||||
+ * system is in its list of supported devices.
|
||||
+ */
|
||||
+const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
+ const struct of_device *dev)
|
||||
{
|
||||
- struct of_device * of_dev = to_of_device(dev);
|
||||
- struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
- const struct of_device_id * matches = of_drv->match_table;
|
||||
-
|
||||
- if (!matches)
|
||||
- return 0;
|
||||
-
|
||||
- return of_match_device(matches, of_dev) != NULL;
|
||||
+ if (!dev->node)
|
||||
+ return NULL;
|
||||
+ return of_match_node(matches, dev->node);
|
||||
}
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
@@ -71,96 +72,8 @@ void of_dev_put(struct of_device *dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
|
||||
-
|
||||
-static int of_device_probe(struct device *dev)
|
||||
-{
|
||||
- int error = -ENODEV;
|
||||
- struct of_platform_driver *drv;
|
||||
- struct of_device *of_dev;
|
||||
- const struct of_device_id *match;
|
||||
-
|
||||
- drv = to_of_platform_driver(dev->driver);
|
||||
- of_dev = to_of_device(dev);
|
||||
-
|
||||
- if (!drv->probe)
|
||||
- return error;
|
||||
-
|
||||
- of_dev_get(of_dev);
|
||||
-
|
||||
- match = of_match_device(drv->match_table, of_dev);
|
||||
- if (match)
|
||||
- error = drv->probe(of_dev, match);
|
||||
- if (error)
|
||||
- of_dev_put(of_dev);
|
||||
-
|
||||
- return error;
|
||||
-}
|
||||
-
|
||||
-static int of_device_remove(struct device *dev)
|
||||
-{
|
||||
- struct of_device * of_dev = to_of_device(dev);
|
||||
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
-
|
||||
- if (dev->driver && drv->remove)
|
||||
- drv->remove(of_dev);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int of_device_suspend(struct device *dev, pm_message_t state)
|
||||
-{
|
||||
- struct of_device * of_dev = to_of_device(dev);
|
||||
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
- int error = 0;
|
||||
-
|
||||
- if (dev->driver && drv->suspend)
|
||||
- error = drv->suspend(of_dev, state);
|
||||
- return error;
|
||||
-}
|
||||
-
|
||||
-static int of_device_resume(struct device * dev)
|
||||
-{
|
||||
- struct of_device * of_dev = to_of_device(dev);
|
||||
- struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
- int error = 0;
|
||||
-
|
||||
- if (dev->driver && drv->resume)
|
||||
- error = drv->resume(of_dev);
|
||||
- return error;
|
||||
-}
|
||||
-
|
||||
-struct bus_type of_platform_bus_type = {
|
||||
- .name = "of_platform",
|
||||
- .match = of_platform_bus_match,
|
||||
- .probe = of_device_probe,
|
||||
- .remove = of_device_remove,
|
||||
- .suspend = of_device_suspend,
|
||||
- .resume = of_device_resume,
|
||||
-};
|
||||
-
|
||||
-static int __init of_bus_driver_init(void)
|
||||
-{
|
||||
- return bus_register(&of_platform_bus_type);
|
||||
-}
|
||||
-
|
||||
-postcore_initcall(of_bus_driver_init);
|
||||
-
|
||||
-int of_register_driver(struct of_platform_driver *drv)
|
||||
-{
|
||||
- /* initialize common driver fields */
|
||||
- drv->driver.name = drv->name;
|
||||
- drv->driver.bus = &of_platform_bus_type;
|
||||
-
|
||||
- /* register with core */
|
||||
- return driver_register(&drv->driver);
|
||||
-}
|
||||
-
|
||||
-void of_unregister_driver(struct of_platform_driver *drv)
|
||||
-{
|
||||
- driver_unregister(&drv->driver);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
+static ssize_t dev_show_devspec(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
@@ -208,41 +121,10 @@ void of_device_unregister(struct of_devi
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
-struct of_device* of_platform_device_create(struct device_node *np,
|
||||
- const char *bus_id,
|
||||
- struct device *parent)
|
||||
-{
|
||||
- struct of_device *dev;
|
||||
-
|
||||
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
- if (!dev)
|
||||
- return NULL;
|
||||
- memset(dev, 0, sizeof(*dev));
|
||||
-
|
||||
- dev->node = of_node_get(np);
|
||||
- dev->dma_mask = 0xffffffffUL;
|
||||
- dev->dev.dma_mask = &dev->dma_mask;
|
||||
- dev->dev.parent = parent;
|
||||
- dev->dev.bus = &of_platform_bus_type;
|
||||
- dev->dev.release = of_release_dev;
|
||||
-
|
||||
- strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
|
||||
-
|
||||
- if (of_device_register(dev) != 0) {
|
||||
- kfree(dev);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- return dev;
|
||||
-}
|
||||
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
-EXPORT_SYMBOL(of_platform_bus_type);
|
||||
-EXPORT_SYMBOL(of_register_driver);
|
||||
-EXPORT_SYMBOL(of_unregister_driver);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
-EXPORT_SYMBOL(of_platform_device_create);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
|
||||
new file mode 100644
|
||||
index 0000000..41c71bc
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/kernel/of_platform.c
|
||||
@@ -0,0 +1,374 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
+ * <benh@kernel.crashing.org>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#undef DEBUG
|
||||
+
|
||||
+#include <linux/string.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <asm/errno.h>
|
||||
+#ifdef CONFIG_PPC_DCR
|
||||
+#include <asm/dcr.h>
|
||||
+#endif
|
||||
+#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * The list of OF IDs below is used for matching bus types in the
|
||||
+ * system whose devices are to be exposed as of_platform_devices.
|
||||
+ *
|
||||
+ * This is the default list valid for most platforms. This file provides
|
||||
+ * functions who can take an explicit list if necessary though
|
||||
+ *
|
||||
+ * The search is always performed recursively looking for children of
|
||||
+ * the provided device_node and recursively if such a children matches
|
||||
+ * a bus type in the list
|
||||
+ */
|
||||
+
|
||||
+static struct of_device_id of_default_bus_ids[] = {
|
||||
+ { .type = "soc", },
|
||||
+ { .compatible = "soc", },
|
||||
+ { .type = "spider", },
|
||||
+ { .type = "axon", },
|
||||
+ { .type = "plb5", },
|
||||
+ { .type = "plb4", },
|
||||
+ { .type = "opb", },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ *
|
||||
+ * OF platform device type definition & base infrastructure
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
+{
|
||||
+ struct of_device * of_dev = to_of_device(dev);
|
||||
+ struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
+ const struct of_device_id * matches = of_drv->match_table;
|
||||
+
|
||||
+ if (!matches)
|
||||
+ return 0;
|
||||
+
|
||||
+ return of_match_device(matches, of_dev) != NULL;
|
||||
+}
|
||||
+
|
||||
+static int of_platform_device_probe(struct device *dev)
|
||||
+{
|
||||
+ int error = -ENODEV;
|
||||
+ struct of_platform_driver *drv;
|
||||
+ struct of_device *of_dev;
|
||||
+ const struct of_device_id *match;
|
||||
+
|
||||
+ drv = to_of_platform_driver(dev->driver);
|
||||
+ of_dev = to_of_device(dev);
|
||||
+
|
||||
+ if (!drv->probe)
|
||||
+ return error;
|
||||
+
|
||||
+ of_dev_get(of_dev);
|
||||
+
|
||||
+ match = of_match_device(drv->match_table, of_dev);
|
||||
+ if (match)
|
||||
+ error = drv->probe(of_dev, match);
|
||||
+ if (error)
|
||||
+ of_dev_put(of_dev);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int of_platform_device_remove(struct device *dev)
|
||||
+{
|
||||
+ struct of_device * of_dev = to_of_device(dev);
|
||||
+ struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
+
|
||||
+ if (dev->driver && drv->remove)
|
||||
+ drv->remove(of_dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int of_platform_device_suspend(struct device *dev, pm_message_t state)
|
||||
+{
|
||||
+ struct of_device * of_dev = to_of_device(dev);
|
||||
+ struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (dev->driver && drv->suspend)
|
||||
+ error = drv->suspend(of_dev, state);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int of_platform_device_resume(struct device * dev)
|
||||
+{
|
||||
+ struct of_device * of_dev = to_of_device(dev);
|
||||
+ struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (dev->driver && drv->resume)
|
||||
+ error = drv->resume(of_dev);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+struct bus_type of_platform_bus_type = {
|
||||
+ .name = "of_platform",
|
||||
+ .match = of_platform_bus_match,
|
||||
+ .probe = of_platform_device_probe,
|
||||
+ .remove = of_platform_device_remove,
|
||||
+ .suspend = of_platform_device_suspend,
|
||||
+ .resume = of_platform_device_resume,
|
||||
+};
|
||||
+EXPORT_SYMBOL(of_platform_bus_type);
|
||||
+
|
||||
+static int __init of_bus_driver_init(void)
|
||||
+{
|
||||
+ return bus_register(&of_platform_bus_type);
|
||||
+}
|
||||
+
|
||||
+postcore_initcall(of_bus_driver_init);
|
||||
+
|
||||
+int of_register_platform_driver(struct of_platform_driver *drv)
|
||||
+{
|
||||
+ /* initialize common driver fields */
|
||||
+ drv->driver.name = drv->name;
|
||||
+ drv->driver.bus = &of_platform_bus_type;
|
||||
+
|
||||
+ /* register with core */
|
||||
+ return driver_register(&drv->driver);
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_register_platform_driver);
|
||||
+
|
||||
+void of_unregister_platform_driver(struct of_platform_driver *drv)
|
||||
+{
|
||||
+ driver_unregister(&drv->driver);
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_unregister_platform_driver);
|
||||
+
|
||||
+static void of_platform_make_bus_id(struct of_device *dev)
|
||||
+{
|
||||
+ struct device_node *node = dev->node;
|
||||
+ char *name = dev->dev.bus_id;
|
||||
+ const u32 *reg;
|
||||
+ u64 addr;
|
||||
+
|
||||
+ /*
|
||||
+ * If it's a DCR based device, use 'd' for native DCRs
|
||||
+ * and 'D' for MMIO DCRs.
|
||||
+ */
|
||||
+#ifdef CONFIG_PPC_DCR
|
||||
+ reg = get_property(node, "dcr-reg", NULL);
|
||||
+ if (reg) {
|
||||
+#ifdef CONFIG_PPC_DCR_NATIVE
|
||||
+ snprintf(name, BUS_ID_SIZE, "d%x.%s",
|
||||
+ *reg, node->name);
|
||||
+#else /* CONFIG_PPC_DCR_NATIVE */
|
||||
+ addr = of_translate_dcr_address(node, *reg, NULL);
|
||||
+ if (addr != OF_BAD_ADDR) {
|
||||
+ snprintf(name, BUS_ID_SIZE,
|
||||
+ "D%llx.%s", (unsigned long long)addr,
|
||||
+ node->name);
|
||||
+ return;
|
||||
+ }
|
||||
+#endif /* !CONFIG_PPC_DCR_NATIVE */
|
||||
+ }
|
||||
+#endif /* CONFIG_PPC_DCR */
|
||||
+
|
||||
+ /*
|
||||
+ * For MMIO, get the physical address
|
||||
+ */
|
||||
+ reg = get_property(node, "reg", NULL);
|
||||
+ if (reg) {
|
||||
+ addr = of_translate_address(node, reg);
|
||||
+ if (addr != OF_BAD_ADDR) {
|
||||
+ snprintf(name, BUS_ID_SIZE,
|
||||
+ "%llx.%s", (unsigned long long)addr,
|
||||
+ node->name);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * No BusID, use the node name and pray
|
||||
+ */
|
||||
+ snprintf(name, BUS_ID_SIZE, "%s", node->name);
|
||||
+}
|
||||
+
|
||||
+struct of_device* of_platform_device_create(struct device_node *np,
|
||||
+ const char *bus_id,
|
||||
+ struct device *parent)
|
||||
+{
|
||||
+ struct of_device *dev;
|
||||
+
|
||||
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
+ if (!dev)
|
||||
+ return NULL;
|
||||
+ memset(dev, 0, sizeof(*dev));
|
||||
+
|
||||
+ dev->node = of_node_get(np);
|
||||
+ dev->dma_mask = 0xffffffffUL;
|
||||
+ dev->dev.dma_mask = &dev->dma_mask;
|
||||
+ dev->dev.parent = parent;
|
||||
+ dev->dev.bus = &of_platform_bus_type;
|
||||
+ dev->dev.release = of_release_dev;
|
||||
+
|
||||
+ if (bus_id)
|
||||
+ strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
|
||||
+ else
|
||||
+ of_platform_make_bus_id(dev);
|
||||
+
|
||||
+ if (of_device_register(dev) != 0) {
|
||||
+ kfree(dev);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return dev;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_platform_device_create);
|
||||
+
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * of_platform_bus_create - Create an OF device for a bus node and all its
|
||||
+ * children. Optionally recursively instanciate matching busses.
|
||||
+ * @bus: device node of the bus to instanciate
|
||||
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
|
||||
+ * disallow recursive creation of child busses
|
||||
+ */
|
||||
+static int of_platform_bus_create(struct device_node *bus,
|
||||
+ struct of_device_id *matches,
|
||||
+ struct device *parent)
|
||||
+{
|
||||
+ struct device_node *child;
|
||||
+ struct of_device *dev;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ for (child = NULL; (child = of_get_next_child(bus, child)); ) {
|
||||
+ pr_debug(" create child: %s\n", child->full_name);
|
||||
+ dev = of_platform_device_create(child, NULL, parent);
|
||||
+ if (dev == NULL)
|
||||
+ rc = -ENOMEM;
|
||||
+ else if (!of_match_node(matches, child))
|
||||
+ continue;
|
||||
+ if (rc == 0) {
|
||||
+ pr_debug(" and sub busses\n");
|
||||
+ rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
+ } if (rc) {
|
||||
+ of_node_put(child);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * of_platform_bus_probe - Probe the device-tree for platform busses
|
||||
+ * @root: parent of the first level to probe or NULL for the root of the tree
|
||||
+ * @matches: match table, NULL to use the default
|
||||
+ * @parent: parent to hook devices from, NULL for toplevel
|
||||
+ *
|
||||
+ * Note that children of the provided root are not instanciated as devices
|
||||
+ * unless the specified root itself matches the bus list and is not NULL.
|
||||
+ */
|
||||
+
|
||||
+int of_platform_bus_probe(struct device_node *root,
|
||||
+ struct of_device_id *matches,
|
||||
+ struct device *parent)
|
||||
+{
|
||||
+ struct device_node *child;
|
||||
+ struct of_device *dev;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ if (matches == NULL)
|
||||
+ matches = of_default_bus_ids;
|
||||
+ if (matches == OF_NO_DEEP_PROBE)
|
||||
+ return -EINVAL;
|
||||
+ if (root == NULL)
|
||||
+ root = of_find_node_by_path("/");
|
||||
+ else
|
||||
+ of_node_get(root);
|
||||
+
|
||||
+ pr_debug("of_platform_bus_probe()\n");
|
||||
+ pr_debug(" starting at: %s\n", root->full_name);
|
||||
+
|
||||
+ /* Do a self check of bus type, if there's a match, create
|
||||
+ * children
|
||||
+ */
|
||||
+ if (of_match_node(matches, root)) {
|
||||
+ pr_debug(" root match, create all sub devices\n");
|
||||
+ dev = of_platform_device_create(root, NULL, parent);
|
||||
+ if (dev == NULL) {
|
||||
+ rc = -ENOMEM;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ pr_debug(" create all sub busses\n");
|
||||
+ rc = of_platform_bus_create(root, matches, &dev->dev);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ for (child = NULL; (child = of_get_next_child(root, child)); ) {
|
||||
+ if (!of_match_node(matches, child))
|
||||
+ continue;
|
||||
+
|
||||
+ pr_debug(" match: %s\n", child->full_name);
|
||||
+ dev = of_platform_device_create(child, NULL, parent);
|
||||
+ if (dev == NULL)
|
||||
+ rc = -ENOMEM;
|
||||
+ else
|
||||
+ rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
+ if (rc) {
|
||||
+ of_node_put(child);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ bail:
|
||||
+ of_node_put(root);
|
||||
+ return rc;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_platform_bus_probe);
|
||||
+
|
||||
+static int of_dev_node_match(struct device *dev, void *data)
|
||||
+{
|
||||
+ return to_of_device(dev)->node == data;
|
||||
+}
|
||||
+
|
||||
+struct of_device *of_find_device_by_node(struct device_node *np)
|
||||
+{
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ dev = bus_find_device(&of_platform_bus_type,
|
||||
+ NULL, np, of_dev_node_match);
|
||||
+ if (dev)
|
||||
+ return to_of_device(dev);
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_find_device_by_node);
|
||||
+
|
||||
+static int of_dev_phandle_match(struct device *dev, void *data)
|
||||
+{
|
||||
+ phandle *ph = data;
|
||||
+ return to_of_device(dev)->node->linux_phandle == *ph;
|
||||
+}
|
||||
+
|
||||
+struct of_device *of_find_device_by_phandle(phandle ph)
|
||||
+{
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ dev = bus_find_device(&of_platform_bus_type,
|
||||
+ NULL, &ph, of_dev_phandle_match);
|
||||
+ if (dev)
|
||||
+ return to_of_device(dev);
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(of_find_device_by_phandle);
|
||||
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
|
||||
index 824a618..e25a0bd 100644
|
||||
--- a/arch/powerpc/platforms/powermac/setup.c
|
||||
+++ b/arch/powerpc/platforms/powermac/setup.c
|
||||
@@ -70,6 +70,7 @@ #include <asm/btext.h>
|
||||
#include <asm/pmac_feature.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/smu.h>
|
||||
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
|
||||
index ade25b3..4f724cd 100644
|
||||
--- a/drivers/macintosh/smu.c
|
||||
+++ b/drivers/macintosh/smu.c
|
||||
@@ -46,6 +46,7 @@ #include <asm/sections.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#define VERSION "0.7"
|
||||
#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
|
||||
@@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void)
|
||||
* I'm a bit too far from figuring out how that works with those
|
||||
* new chipsets, but that will come back and bite us
|
||||
*/
|
||||
- of_register_driver(&smu_of_platform_driver);
|
||||
+ of_register_platform_driver(&smu_of_platform_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
|
||||
index a0f30d0..13b953a 100644
|
||||
--- a/drivers/macintosh/therm_adt746x.c
|
||||
+++ b/drivers/macintosh/therm_adt746x.c
|
||||
@@ -30,7 +30,7 @@ #include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/sections.h>
|
||||
-#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
|
||||
index d00c0c3..2e4ad44 100644
|
||||
--- a/drivers/macintosh/therm_pm72.c
|
||||
+++ b/drivers/macintosh/therm_pm72.c
|
||||
@@ -129,6 +129,7 @@ #include <asm/system.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/of_device.h>
|
||||
#include <asm/macio.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#include "therm_pm72.h"
|
||||
|
||||
@@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- of_register_driver(&fcu_of_platform_driver);
|
||||
+ of_register_platform_driver(&fcu_of_platform_driver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit therm_pm72_exit(void)
|
||||
{
|
||||
- of_unregister_driver(&fcu_of_platform_driver);
|
||||
+ of_unregister_platform_driver(&fcu_of_platform_driver);
|
||||
|
||||
if (of_dev)
|
||||
of_device_unregister(of_dev);
|
||||
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
|
||||
index 738faab..a1d3a98 100644
|
||||
--- a/drivers/macintosh/therm_windtunnel.c
|
||||
+++ b/drivers/macintosh/therm_windtunnel.c
|
||||
@@ -36,12 +36,13 @@ #include <linux/sched.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
+
|
||||
#include <asm/prom.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/sections.h>
|
||||
-#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
#include <asm/macio.h>
|
||||
|
||||
#define LOG_TEMP 0 /* continously log temperature */
|
||||
@@ -511,14 +512,14 @@ g4fan_init( void )
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
- of_register_driver( &therm_of_driver );
|
||||
+ of_register_platform_driver( &therm_of_driver );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
g4fan_exit( void )
|
||||
{
|
||||
- of_unregister_driver( &therm_of_driver );
|
||||
+ of_unregister_platform_driver( &therm_of_driver );
|
||||
|
||||
if( x.of_dev )
|
||||
of_device_unregister( x.of_dev );
|
||||
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
|
||||
index fdb33cd..cb26c6d 100644
|
||||
--- a/drivers/video/platinumfb.c
|
||||
+++ b/drivers/video/platinumfb.c
|
||||
@@ -34,6 +34,7 @@ #include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#include "macmodes.h"
|
||||
#include "platinumfb.h"
|
||||
@@ -682,14 +683,14 @@ #ifndef MODULE
|
||||
return -ENODEV;
|
||||
platinumfb_setup(option);
|
||||
#endif
|
||||
- of_register_driver(&platinum_driver);
|
||||
+ of_register_platform_driver(&platinum_driver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit platinumfb_exit(void)
|
||||
{
|
||||
- of_unregister_driver(&platinum_driver);
|
||||
+ of_unregister_platform_driver(&platinum_driver);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
|
||||
index c5c0b0b..1ef7e9e 100644
|
||||
--- a/include/asm-powerpc/of_device.h
|
||||
+++ b/include/asm-powerpc/of_device.h
|
||||
@@ -6,12 +6,6 @@ #include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
-/*
|
||||
- * The of_platform_bus_type is a bus type used by drivers that do not
|
||||
- * attach to a macio or similar bus but still use OF probing
|
||||
- * mechanism
|
||||
- */
|
||||
-extern struct bus_type of_platform_bus_type;
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
@@ -26,40 +20,16 @@ struct of_device
|
||||
};
|
||||
#define to_of_device(d) container_of(d, struct of_device, dev)
|
||||
|
||||
+extern const struct of_device_id *of_match_node(
|
||||
+ const struct of_device_id *matches, const struct device_node *node);
|
||||
extern const struct of_device_id *of_match_device(
|
||||
const struct of_device_id *matches, const struct of_device *dev);
|
||||
|
||||
extern struct of_device *of_dev_get(struct of_device *dev);
|
||||
extern void of_dev_put(struct of_device *dev);
|
||||
|
||||
-/*
|
||||
- * An of_platform_driver driver is attached to a basic of_device on
|
||||
- * the "platform bus" (of_platform_bus_type)
|
||||
- */
|
||||
-struct of_platform_driver
|
||||
-{
|
||||
- char *name;
|
||||
- struct of_device_id *match_table;
|
||||
- struct module *owner;
|
||||
-
|
||||
- int (*probe)(struct of_device* dev, const struct of_device_id *match);
|
||||
- int (*remove)(struct of_device* dev);
|
||||
-
|
||||
- int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
- int (*resume)(struct of_device* dev);
|
||||
- int (*shutdown)(struct of_device* dev);
|
||||
-
|
||||
- struct device_driver driver;
|
||||
-};
|
||||
-#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
|
||||
-
|
||||
-extern int of_register_driver(struct of_platform_driver *drv);
|
||||
-extern void of_unregister_driver(struct of_platform_driver *drv);
|
||||
extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
-extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
- const char *bus_id,
|
||||
- struct device *parent);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
diff --git a/include/asm-powerpc/of_platform.h b/include/asm-powerpc/of_platform.h
|
||||
new file mode 100644
|
||||
index 0000000..217eafb
|
||||
--- /dev/null
|
||||
+++ b/include/asm-powerpc/of_platform.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
+ * <benh@kernel.crashing.org>
|
||||
+ *
|
||||
+ * 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 <asm/of_device.h>
|
||||
+
|
||||
+/*
|
||||
+ * The of_platform_bus_type is a bus type used by drivers that do not
|
||||
+ * attach to a macio or similar bus but still use OF probing
|
||||
+ * mechanism
|
||||
+ */
|
||||
+extern struct bus_type of_platform_bus_type;
|
||||
+
|
||||
+/*
|
||||
+ * An of_platform_driver driver is attached to a basic of_device on
|
||||
+ * the "platform bus" (of_platform_bus_type)
|
||||
+ */
|
||||
+struct of_platform_driver
|
||||
+{
|
||||
+ char *name;
|
||||
+ struct of_device_id *match_table;
|
||||
+ struct module *owner;
|
||||
+
|
||||
+ int (*probe)(struct of_device* dev,
|
||||
+ const struct of_device_id *match);
|
||||
+ int (*remove)(struct of_device* dev);
|
||||
+
|
||||
+ int (*suspend)(struct of_device* dev, pm_message_t state);
|
||||
+ int (*resume)(struct of_device* dev);
|
||||
+ int (*shutdown)(struct of_device* dev);
|
||||
+
|
||||
+ struct device_driver driver;
|
||||
+};
|
||||
+#define to_of_platform_driver(drv) \
|
||||
+ container_of(drv,struct of_platform_driver, driver)
|
||||
+
|
||||
+/* Platform drivers register/unregister */
|
||||
+extern int of_register_platform_driver(struct of_platform_driver *drv);
|
||||
+extern void of_unregister_platform_driver(struct of_platform_driver *drv);
|
||||
+
|
||||
+/* Platform devices and busses creation */
|
||||
+extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
+ const char *bus_id,
|
||||
+ struct device *parent);
|
||||
+/* pseudo "matches" value to not do deep probe */
|
||||
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
|
||||
+
|
||||
+extern int of_platform_bus_probe(struct device_node *root,
|
||||
+ struct of_device_id *matches,
|
||||
+ struct device *parent);
|
||||
+
|
||||
+extern struct of_device *of_find_device_by_node(struct device_node *np);
|
||||
+extern struct of_device *of_find_device_by_phandle(phandle ph);
|
||||
--
|
||||
1.4.3.2
|
||||
|
31
debian/patches/features/powerpc/efika/0012-ata-Fix-pata_mpc52xx.c-compatible-list.txt
vendored
Normal file
31
debian/patches/features/powerpc/efika/0012-ata-Fix-pata_mpc52xx.c-compatible-list.txt
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 20e872b5fed46ba15ed6f2c29cc2adf98657c9a4 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 22:20:06 +0100
|
||||
Subject: [PATCH] [PATCH] ata: Fix pata_mpc52xx.c 'compatible' list
|
||||
|
||||
The list contained an entry to support a non-standard device-tree,
|
||||
this is now handled by fixups in early boot.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
drivers/ata/pata_mpc52xx.c | 4 +---
|
||||
1 files changed, 1 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
|
||||
index 8b7019a..ff40016 100644
|
||||
--- a/drivers/ata/pata_mpc52xx.c
|
||||
+++ b/drivers/ata/pata_mpc52xx.c
|
||||
@@ -509,9 +509,7 @@ mpc52xx_ata_resume(struct of_device *op)
|
||||
|
||||
static struct of_device_id mpc52xx_ata_of_match[] = {
|
||||
{
|
||||
- .compatible = "mpc5200-ata",
|
||||
- },
|
||||
- {
|
||||
+ .type = "ata",
|
||||
.compatible = "mpc52xx-ata",
|
||||
},
|
||||
{},
|
||||
--
|
||||
1.4.4.2
|
||||
|
28
debian/patches/features/powerpc/efika/0013-powerpc-serial-Fix-mpc52xx_uart.c-compatible-list.txt
vendored
Normal file
28
debian/patches/features/powerpc/efika/0013-powerpc-serial-Fix-mpc52xx_uart.c-compatible-list.txt
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
From f3736d1a7f74d7dec888a8a8d8c593ca08a31000 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 22:21:43 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc/serial: Fix mpc52xx_uart.c 'compatible' list
|
||||
|
||||
The list contained an entry to support a non-standard device-tree,
|
||||
this is now handled by fixups in early boot.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
drivers/serial/mpc52xx_uart.c | 1 -
|
||||
1 files changed, 0 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
|
||||
index eef3b02..c20cd81 100644
|
||||
--- a/drivers/serial/mpc52xx_uart.c
|
||||
+++ b/drivers/serial/mpc52xx_uart.c
|
||||
@@ -128,7 +128,6 @@ static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id);
|
||||
#if defined(CONFIG_PPC_MERGE)
|
||||
static struct of_device_id mpc52xx_uart_of_match[] = {
|
||||
{ .type = "serial", .compatible = "mpc52xx-psc-uart", },
|
||||
- { .type = "serial", .compatible = "mpc5200-psc", }, /* Efika only! */
|
||||
{},
|
||||
};
|
||||
#endif
|
||||
--
|
||||
1.4.4.2
|
||||
|
144
debian/patches/features/powerpc/efika/0014-powerpc-Small-cleanup-of-EFIKA-platform.txt
vendored
Normal file
144
debian/patches/features/powerpc/efika/0014-powerpc-Small-cleanup-of-EFIKA-platform.txt
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
From 65cd4fcc30440e903fd99973918373ee4534b70a Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 22:39:18 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Small cleanup of EFIKA platform
|
||||
|
||||
This is just some cleanup to remove the efika.h header that just have
|
||||
2 lines in it and is not really necessary.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/efika-pci.c | 23 ++++++++++++++++-------
|
||||
arch/powerpc/platforms/52xx/efika-setup.c | 7 ++++---
|
||||
arch/powerpc/platforms/52xx/efika.h | 19 -------------------
|
||||
3 files changed, 20 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/efika-pci.c b/arch/powerpc/platforms/52xx/efika-pci.c
|
||||
index 62e05b2..3732dec 100644
|
||||
--- a/arch/powerpc/platforms/52xx/efika-pci.c
|
||||
+++ b/arch/powerpc/platforms/52xx/efika-pci.c
|
||||
@@ -1,3 +1,13 @@
|
||||
+/*
|
||||
+ * Efika 5K2 PCI support thru RTAS
|
||||
+ *
|
||||
+ * Copyright (C) 2006 bplan GmbH
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ *
|
||||
+ */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
@@ -12,7 +22,6 @@
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/rtas.h>
|
||||
|
||||
-#include "efika.h"
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
@@ -62,7 +71,7 @@ void __init efika_pcisetup(void)
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (root == NULL) {
|
||||
- printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
+ printk(KERN_WARNING __FILE__
|
||||
": Unable to find the root node\n");
|
||||
return;
|
||||
}
|
||||
@@ -76,30 +85,30 @@ void __init efika_pcisetup(void)
|
||||
of_node_put(root);
|
||||
|
||||
if (pcictrl == NULL) {
|
||||
- printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
+ printk(KERN_WARNING __FILE__
|
||||
": Unable to find the PCI bridge node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bus_range = get_property(pcictrl, "bus-range", &len);
|
||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
- printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
+ printk(KERN_WARNING __FILE__
|
||||
": Can't get bus-range for %s\n", pcictrl->full_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bus_range[1] == bus_range[0])
|
||||
- printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d",
|
||||
+ printk(KERN_INFO __FILE__ ": PCI bus %d",
|
||||
bus_range[0]);
|
||||
else
|
||||
- printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d",
|
||||
+ printk(KERN_INFO __FILE__ ": PCI buses %d..%d",
|
||||
bus_range[0], bus_range[1]);
|
||||
printk(" controlled by %s\n", pcictrl->full_name);
|
||||
printk("\n");
|
||||
|
||||
hose = pcibios_alloc_controller();
|
||||
if (!hose) {
|
||||
- printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
+ printk(KERN_WARNING __FILE__
|
||||
": Can't allocate PCI controller structure for %s\n",
|
||||
pcictrl->full_name);
|
||||
return;
|
||||
diff --git a/arch/powerpc/platforms/52xx/efika-setup.c b/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
index d61ce84..17bf73a 100644
|
||||
--- a/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
+++ b/arch/powerpc/platforms/52xx/efika-setup.c
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
- *
|
||||
* Efika 5K2 platform setup
|
||||
* Some code really inspired from the lite5200b platform.
|
||||
*
|
||||
@@ -32,7 +31,9 @@
|
||||
#include <asm/of_platform.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
-#include "efika.h"
|
||||
+
|
||||
+extern void __init efika_pcisetup(void);
|
||||
+
|
||||
|
||||
static void efika_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
@@ -103,7 +104,7 @@ static int __init efika_probe(void)
|
||||
|
||||
define_machine(efika)
|
||||
{
|
||||
- .name = EFIKA_PLATFORM_NAME,
|
||||
+ .name = "Efika",
|
||||
.probe = efika_probe,
|
||||
.setup_arch = efika_setup_arch,
|
||||
.init = mpc52xx_declare_of_platform_devices,
|
||||
diff --git a/arch/powerpc/platforms/52xx/efika.h b/arch/powerpc/platforms/52xx/efika.h
|
||||
deleted file mode 100644
|
||||
index 2f060fd..0000000
|
||||
--- a/arch/powerpc/platforms/52xx/efika.h
|
||||
+++ /dev/null
|
||||
@@ -1,19 +0,0 @@
|
||||
-/*
|
||||
- * Efika 5K2 platform setup - Header file
|
||||
- *
|
||||
- * Copyright (C) 2006 bplan GmbH
|
||||
- *
|
||||
- * This file is licensed under the terms of the GNU General Public License
|
||||
- * version 2. This program is licensed "as is" without any warranty of any
|
||||
- * kind, whether express or implied.
|
||||
- *
|
||||
- */
|
||||
-
|
||||
-#ifndef __ARCH_POWERPC_EFIKA__
|
||||
-#define __ARCH_POWERPC_EFIKA__
|
||||
-
|
||||
-#define EFIKA_PLATFORM_NAME "Efika"
|
||||
-
|
||||
-extern void __init efika_pcisetup(void);
|
||||
-
|
||||
-#endif
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
From 90dc591d4c897c7a49191888c1e4d413cc08b8b7 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 23:08:56 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Add a unified uevent handler for bus based on of_device
|
||||
|
||||
This common uevent handler allow the several bus types based on
|
||||
of_device to generate the uevent properly and avoiding
|
||||
code duplication.
|
||||
|
||||
This handlers take a struct device as argument and can therefore
|
||||
be used as the uevent call directly if no special treatment is
|
||||
needed for the bus.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/kernel/of_device.c | 66 +++++++++++++++++++++++++++++++++++++++
|
||||
include/asm-powerpc/of_device.h | 3 ++
|
||||
2 files changed, 69 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
|
||||
index e921514..ac024ad 100644
|
||||
--- a/arch/powerpc/kernel/of_device.c
|
||||
+++ b/arch/powerpc/kernel/of_device.c
|
||||
@@ -120,6 +120,71 @@ void of_device_unregister(struct of_device *ofdev)
|
||||
}
|
||||
|
||||
|
||||
+int of_device_uevent(struct device *dev,
|
||||
+ char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
+{
|
||||
+ struct of_device *ofdev;
|
||||
+ const char *compat;
|
||||
+ char *compat2;
|
||||
+ char compat_buf[128]; /* need to be size of 'compatible' */
|
||||
+ int i = 0, length = 0, seen = 0, cplen, sl;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ofdev = to_of_device(dev);
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_NAME=%s", ofdev->node->name))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_TYPE=%s", ofdev->node->type))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Since the compatible field can contain pretty much anything
|
||||
+ * it's not really legal to split it out with commas. We split it
|
||||
+ * up using a number of environment variables instead. */
|
||||
+
|
||||
+ compat = get_property(ofdev->node, "compatible", &cplen);
|
||||
+ compat2 = compat_buf;
|
||||
+ if (compat)
|
||||
+ memcpy(compat2, compat, cplen);
|
||||
+ while (compat && *compat && cplen > 0) {
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sl = strlen (compat) + 1;
|
||||
+ compat += sl;
|
||||
+ compat2 += sl;
|
||||
+ cplen -= sl;
|
||||
+ seen++;
|
||||
+ compat2[-1] = 'C';
|
||||
+ }
|
||||
+ compat2[seen?-1:0] = 0;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "OF_COMPATIBLE_N=%d", seen))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (add_uevent_var(envp, num_envp, &i,
|
||||
+ buffer, buffer_size, &length,
|
||||
+ "MODALIAS=of:N%sT%sC%s",
|
||||
+ ofdev->node->name, ofdev->node->type,
|
||||
+ compat_buf))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ envp[i] = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
EXPORT_SYMBOL(of_match_node);
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
@@ -127,3 +192,4 @@ EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
+EXPORT_SYMBOL(of_device_uevent);
|
||||
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
|
||||
index a889b20..4f1aabe 100644
|
||||
--- a/include/asm-powerpc/of_device.h
|
||||
+++ b/include/asm-powerpc/of_device.h
|
||||
@@ -32,5 +32,8 @@ extern int of_device_register(struct of_device *ofdev);
|
||||
extern void of_device_unregister(struct of_device *ofdev);
|
||||
extern void of_release_dev(struct device *dev);
|
||||
|
||||
+extern int of_device_uevent(struct device *dev,
|
||||
+ char **envp, int num_envp, char *buffer, int buffer_size);
|
||||
+
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_OF_DEVICE_H */
|
||||
--
|
||||
1.4.4.2
|
||||
|
130
debian/patches/features/powerpc/efika/0016-macintosh-Use-the-new-of_device-common-uevent-handler.txt
vendored
Normal file
130
debian/patches/features/powerpc/efika/0016-macintosh-Use-the-new-of_device-common-uevent-handler.txt
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
From 2507b27c0841752a6f419439896fcb089fa4a5ba Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 23:13:56 +0100
|
||||
Subject: [PATCH] [PATCH] macintosh: Use the new of_device common uevent handler
|
||||
|
||||
The generation of the uevent is now common to all bus using
|
||||
of_device.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
drivers/macintosh/macio_asic.c | 98 +---------------------------------------
|
||||
1 files changed, 1 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
|
||||
index d562160..e851266 100644
|
||||
--- a/drivers/macintosh/macio_asic.c
|
||||
+++ b/drivers/macintosh/macio_asic.c
|
||||
@@ -134,108 +134,12 @@ static int macio_device_resume(struct device * dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int macio_uevent(struct device *dev, char **envp, int num_envp,
|
||||
- char *buffer, int buffer_size)
|
||||
-{
|
||||
- struct macio_dev * macio_dev;
|
||||
- struct of_device * of;
|
||||
- char *scratch;
|
||||
- const char *compat, *compat2;
|
||||
-
|
||||
- int i = 0;
|
||||
- int length, cplen, cplen2, seen = 0;
|
||||
-
|
||||
- if (!dev)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- macio_dev = to_macio_device(dev);
|
||||
- if (!macio_dev)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- of = &macio_dev->ofdev;
|
||||
-
|
||||
- /* stuff we want to pass to /sbin/hotplug */
|
||||
- envp[i++] = scratch = buffer;
|
||||
- length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
|
||||
- ++length;
|
||||
- buffer_size -= length;
|
||||
- if ((buffer_size <= 0) || (i >= num_envp))
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
-
|
||||
- envp[i++] = scratch;
|
||||
- length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
|
||||
- ++length;
|
||||
- buffer_size -= length;
|
||||
- if ((buffer_size <= 0) || (i >= num_envp))
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
-
|
||||
- /* Since the compatible field can contain pretty much anything
|
||||
- * it's not really legal to split it out with commas. We split it
|
||||
- * up using a number of environment variables instead. */
|
||||
-
|
||||
- compat = get_property(of->node, "compatible", &cplen);
|
||||
- compat2 = compat;
|
||||
- cplen2= cplen;
|
||||
- while (compat && cplen > 0) {
|
||||
- envp[i++] = scratch;
|
||||
- length = scnprintf (scratch, buffer_size,
|
||||
- "OF_COMPATIBLE_%d=%s", seen, compat);
|
||||
- ++length;
|
||||
- buffer_size -= length;
|
||||
- if ((buffer_size <= 0) || (i >= num_envp))
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
- length = strlen (compat) + 1;
|
||||
- compat += length;
|
||||
- cplen -= length;
|
||||
- seen++;
|
||||
- }
|
||||
-
|
||||
- envp[i++] = scratch;
|
||||
- length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
|
||||
- ++length;
|
||||
- buffer_size -= length;
|
||||
- if ((buffer_size <= 0) || (i >= num_envp))
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
-
|
||||
- envp[i++] = scratch;
|
||||
- length = scnprintf (scratch, buffer_size, "MODALIAS=of:N%sT%s",
|
||||
- of->node->name, of->node->type);
|
||||
- /* overwrite '\0' */
|
||||
- buffer_size -= length;
|
||||
- if ((buffer_size <= 0) || (i >= num_envp))
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
-
|
||||
- if (!compat2) {
|
||||
- compat2 = "";
|
||||
- cplen2 = 1;
|
||||
- }
|
||||
- while (cplen2 > 0) {
|
||||
- length = snprintf (scratch, buffer_size, "C%s", compat2);
|
||||
- buffer_size -= length;
|
||||
- if (buffer_size <= 0)
|
||||
- return -ENOMEM;
|
||||
- scratch += length;
|
||||
- length = strlen (compat2) + 1;
|
||||
- compat2 += length;
|
||||
- cplen2 -= length;
|
||||
- }
|
||||
-
|
||||
- envp[i] = NULL;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
extern struct device_attribute macio_dev_attrs[];
|
||||
|
||||
struct bus_type macio_bus_type = {
|
||||
.name = "macio",
|
||||
.match = macio_bus_match,
|
||||
- .uevent = macio_uevent,
|
||||
+ .uevent = of_device_uevent,
|
||||
.probe = macio_device_probe,
|
||||
.remove = macio_device_remove,
|
||||
.shutdown = macio_device_shutdown,
|
||||
--
|
||||
1.4.4.2
|
||||
|
29
debian/patches/features/powerpc/efika/0017-powerpc-Add-uevent-handler-for-of_platform_bus.txt
vendored
Normal file
29
debian/patches/features/powerpc/efika/0017-powerpc-Add-uevent-handler-for-of_platform_bus.txt
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
From 846d6cd8584eee7517543be073c8b3fe9fefd065 Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 23:16:07 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Add uevent handler for of_platform_bus
|
||||
|
||||
Adding this handler allow userspace to properly handle the module
|
||||
autoloading. The generation of the uevent itself is now common to
|
||||
all bus using of_device, so not much code here.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/kernel/of_platform.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
|
||||
index b734517..da78e44 100644
|
||||
--- a/arch/powerpc/kernel/of_platform.c
|
||||
+++ b/arch/powerpc/kernel/of_platform.c
|
||||
@@ -133,6 +133,7 @@ static int of_platform_device_resume(struct device * dev)
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.name = "of_platform",
|
||||
.match = of_platform_bus_match,
|
||||
+ .uevent = of_device_uevent,
|
||||
.probe = of_platform_device_probe,
|
||||
.remove = of_platform_device_remove,
|
||||
.suspend = of_platform_device_suspend,
|
||||
--
|
||||
1.4.4.2
|
||||
|
50
debian/patches/features/powerpc/efika/0018-powerpc-Add-uevent-handler-for-ibmebus.txt
vendored
Normal file
50
debian/patches/features/powerpc/efika/0018-powerpc-Add-uevent-handler-for-ibmebus.txt
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
From ddc4a7296f3abd28a902f38ae915224d6d93edca Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Sat, 23 Dec 2006 23:20:58 +0100
|
||||
Subject: [PATCH] [PATCH] powerpc: Add uevent handler for ibmebus
|
||||
|
||||
Adding this handler allow userspace to properly handle the module
|
||||
autoloading. The generation of the uevent itself is now common to
|
||||
all bus using of_device, so not much code here.
|
||||
|
||||
But we still need a small wrapper to filter out the dummy root
|
||||
device node used by this bus.
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
arch/powerpc/kernel/ibmebus.c | 16 ++++++++++++++++
|
||||
1 files changed, 16 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
|
||||
index 82bd2f1..2e8d9fd 100644
|
||||
--- a/arch/powerpc/kernel/ibmebus.c
|
||||
+++ b/arch/powerpc/kernel/ibmebus.c
|
||||
@@ -361,9 +361,25 @@ static int ibmebus_bus_match(struct device *dev, struct device_driver *drv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ibmebus_bus_uevent(struct device *dev,
|
||||
+ char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
+{
|
||||
+ struct ibmebus_dev *ebus_dev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ebus_dev = to_ibmebus_dev(dev);
|
||||
+ if (ebus_dev==ibmebus_bus_device) /* filter dummy root device */
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ return of_device_uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
+}
|
||||
+
|
||||
struct bus_type ibmebus_bus_type = {
|
||||
.name = "ibmebus",
|
||||
.match = ibmebus_bus_match,
|
||||
+ .uevent = ibmebus_bus_uevent,
|
||||
};
|
||||
EXPORT_SYMBOL(ibmebus_bus_type);
|
||||
|
||||
--
|
||||
1.4.4.2
|
||||
|
1439
debian/patches/features/powerpc/efika/0019-MPC5200-Bestcomm-platform-driver.txt
vendored
Normal file
1439
debian/patches/features/powerpc/efika/0019-MPC5200-Bestcomm-platform-driver.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,34 +1,37 @@
|
|||
From 0eae8b0fed7d8342c027e15d2a6d52eae10366e1 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:09:04 +0100
|
||||
Subject: [PATCH] Add MPC5200 ethernet driver
|
||||
From 6b6e09cca4346ea737db427d568843034eb348fa Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Volkov <avolkov@varma-el.com>
|
||||
Date: Fri, 18 Aug 2006 10:02:29 -0600
|
||||
Subject: [PATCH] [PATCH 02/02] Fec MPC5200 eth driver
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Second part. Contain only FEC parts.
|
||||
Depended on previous bestcomm patch.
|
||||
|
||||
Signed-Off-By: Andrey Volkov <avolkov at varma-el.com>
|
||||
---
|
||||
drivers/net/Kconfig | 1 +
|
||||
drivers/net/Makefile | 1 +
|
||||
drivers/net/fec_mpc52xx/Kconfig | 22 +
|
||||
drivers/net/fec_mpc52xx/Kconfig | 23 ++
|
||||
drivers/net/fec_mpc52xx/Makefile | 2 +
|
||||
drivers/net/fec_mpc52xx/fec.c | 817 +++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec.h | 308 ++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec_phy.c | 532 ++++++++++++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec.c | 768 +++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec.h | 308 +++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec_phy.c | 526 +++++++++++++++++++++++++
|
||||
drivers/net/fec_mpc52xx/fec_phy.h | 73 ++++
|
||||
8 files changed, 1756 insertions(+), 0 deletions(-)
|
||||
8 files changed, 1702 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
|
||||
index 6e863aa..c0bf347 100644
|
||||
index 8aa8dd0..0658e92 100644
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -1892,6 +1892,7 @@ config NE_H8300
|
||||
@@ -1902,6 +1902,7 @@ config NE_H8300
|
||||
controller on the Renesas H8/300 processor.
|
||||
|
||||
source "drivers/net/fec_8xx/Kconfig"
|
||||
source "drivers/net/fs_enet/Kconfig"
|
||||
+source "drivers/net/fec_mpc52xx/Kconfig"
|
||||
source "drivers/net/fs_enet/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
|
||||
index f270bc4..a39a931 100644
|
||||
index 4c0d4e5..e6f903d 100644
|
||||
--- a/drivers/net/Makefile
|
||||
+++ b/drivers/net/Makefile
|
||||
@@ -196,6 +196,7 @@ obj-$(CONFIG_SMC91X) += smc91x.o
|
||||
|
@ -37,27 +40,28 @@ index f270bc4..a39a931 100644
|
|||
obj-$(CONFIG_FEC_8XX) += fec_8xx/
|
||||
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx/
|
||||
|
||||
obj-$(CONFIG_ARM) += arm/
|
||||
obj-$(CONFIG_DEV_APPLETALK) += appletalk/
|
||||
obj-$(CONFIG_MACB) += macb.o
|
||||
|
||||
diff --git a/drivers/net/fec_mpc52xx/Kconfig b/drivers/net/fec_mpc52xx/Kconfig
|
||||
new file mode 100644
|
||||
index 0000000..dc3fee6
|
||||
index 0000000..098c3fa
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/fec_mpc52xx/Kconfig
|
||||
@@ -0,0 +1,22 @@
|
||||
@@ -0,0 +1,23 @@
|
||||
+menu "MPC5200 Networking Options"
|
||||
+ depends (PPC_CHRP || PPC_MPC52xx) && NET_ETHERNET
|
||||
+ depends PPC_MPC52xx && NET_ETHERNET
|
||||
+
|
||||
+config FEC_MPC52xx
|
||||
+ bool "FEC Ethernet"
|
||||
+ depends on NET_ETHERNET
|
||||
+ select PPC_BESTCOMM
|
||||
+ select CRC32
|
||||
+ ---help---
|
||||
+ This option enables support for the MPC5200's on-chip
|
||||
+ Fast Ethernet Controller
|
||||
+
|
||||
+config USE_MDIO
|
||||
+ bool "Use external Ethernet MII PHY"
|
||||
+ bool " Use external Ethernet MII PHY"
|
||||
+ select MII
|
||||
+ depends FEC_MPC52xx
|
||||
+ ---help---
|
||||
|
@ -77,10 +81,10 @@ index 0000000..b8ae05c
|
|||
+obj-$(CONFIG_USE_MDIO) += fec_phy.o
|
||||
diff --git a/drivers/net/fec_mpc52xx/fec.c b/drivers/net/fec_mpc52xx/fec.c
|
||||
new file mode 100644
|
||||
index 0000000..5591bb7
|
||||
index 0000000..b5f1559
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/fec_mpc52xx/fec.c
|
||||
@@ -0,0 +1,817 @@
|
||||
@@ -0,0 +1,768 @@
|
||||
+/*
|
||||
+ * drivers/net/fec_mpc52xx/fec.c
|
||||
+ *
|
||||
|
@ -110,40 +114,20 @@ index 0000000..5591bb7
|
|||
+
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/delay.h>
|
||||
+#include <asm/ppcboot.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
+
|
||||
+#ifdef CONFIG_PPC_EFIKA
|
||||
+#include <platforms/efika/bestcomm.h>
|
||||
+#else
|
||||
+#include <syslib/bestcomm/bestcomm.h>
|
||||
+#include <syslib/bestcomm/fec.h>
|
||||
+#endif
|
||||
+
|
||||
+/******************/
|
||||
+/******************/
|
||||
+static unsigned long get_ipbfreq(void)
|
||||
+{
|
||||
+#ifdef CONFIG_PPC_EFIKA
|
||||
+ return (132*1000*1000);
|
||||
+#else
|
||||
+ bd_t *bd = (bd_t *)&__res;
|
||||
+ return bd->bi_ipbfreq
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+/******************/
|
||||
+/******************/
|
||||
+
|
||||
+#include "fec_phy.h"
|
||||
+#include "fec.h"
|
||||
+
|
||||
+#define DRIVER_NAME "mpc52xx-fec"
|
||||
+
|
||||
+static irqreturn_t fec_interrupt(int, void *);
|
||||
+static irqreturn_t fec_rx_interrupt(int, void *);
|
||||
+static irqreturn_t fec_tx_interrupt(int, void *);
|
||||
+static irqreturn_t fec_interrupt(int, void *, struct pt_regs *);
|
||||
+static irqreturn_t fec_rx_interrupt(int, void *, struct pt_regs *);
|
||||
+static irqreturn_t fec_tx_interrupt(int, void *, struct pt_regs *);
|
||||
+static struct net_device_stats *fec_get_stats(struct net_device *);
|
||||
+static void fec_set_multicast_list(struct net_device *dev);
|
||||
+static void fec_reinit(struct net_device *dev);
|
||||
|
@ -336,7 +320,7 @@ index 0000000..5591bb7
|
|||
+
|
||||
+/* This handles BestComm transmit task interrupts
|
||||
+ */
|
||||
+static irqreturn_t fec_tx_interrupt(int irq, void *dev_id)
|
||||
+static irqreturn_t fec_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+{
|
||||
+ struct net_device *dev = dev_id;
|
||||
+ struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
|
@ -362,7 +346,7 @@ index 0000000..5591bb7
|
|||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t fec_rx_interrupt(int irq, void *dev_id)
|
||||
+static irqreturn_t fec_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+{
|
||||
+ struct net_device *dev = dev_id;
|
||||
+ struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
|
@ -419,7 +403,7 @@ index 0000000..5591bb7
|
|||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t fec_interrupt(int irq, void *dev_id)
|
||||
+static irqreturn_t fec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+{
|
||||
+ struct net_device *dev = (struct net_device *)dev_id;
|
||||
+ struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
|
@ -427,24 +411,17 @@ index 0000000..5591bb7
|
|||
+ int ievent;
|
||||
+
|
||||
+ ievent = in_be32(&fec->ievent);
|
||||
+ if (!ievent)
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ out_be32(&fec->ievent, ievent); /* clear pending events */
|
||||
+
|
||||
+ if (ievent & (FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
|
||||
+ if ( net_ratelimit() )
|
||||
+ {
|
||||
+ if (ievent & FEC_IEVENT_RFIFO_ERROR)
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR (%8.8x)\n", ievent);
|
||||
+ if (ievent & FEC_IEVENT_XFIFO_ERROR)
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR (%8.8x)\n", ievent);
|
||||
+ }
|
||||
+ if (ievent & FEC_IEVENT_RFIFO_ERROR)
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR\n");
|
||||
+ if (ievent & FEC_IEVENT_XFIFO_ERROR)
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR\n");
|
||||
+ fec_reinit(dev);
|
||||
+ }
|
||||
+ else if (ievent & FEC_IEVENT_MII)
|
||||
+ fec_mii(dev);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
|
@ -605,7 +582,8 @@ index 0000000..5591bb7
|
|||
+{
|
||||
+ struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
+ struct mpc52xx_fec *fec = priv->fec;
|
||||
+
|
||||
+ bd_t *bd = (bd_t *) &__res;
|
||||
+
|
||||
+ out_be32(&fec->op_pause, 0x00010020);
|
||||
+ out_be32(&fec->rfifo_cntrl, 0x0f000000);
|
||||
+ out_be32(&fec->rfifo_alarm, 0x0000030c);
|
||||
|
@ -616,7 +594,7 @@ index 0000000..5591bb7
|
|||
+ out_be32(&fec->iaddr1, 0x00000000); /* No individual filter */
|
||||
+ out_be32(&fec->iaddr2, 0x00000000); /* No individual filter */
|
||||
+
|
||||
+ priv->phy_speed = ((get_ipbfreq() >> 20) / 5) << 1;
|
||||
+ priv->phy_speed = ((bd->bi_ipbfreq >> 20) / 5) << 1;
|
||||
+
|
||||
+ fec_restart(dev, 0); /* always use half duplex mode only */
|
||||
+ /*
|
||||
|
@ -626,12 +604,13 @@ index 0000000..5591bb7
|
|||
+ fec_update_stat(dev);
|
||||
+}
|
||||
+
|
||||
+static void fec_update_stat(struct net_device *);
|
||||
+
|
||||
+static void fec_reinit(struct net_device *dev)
|
||||
+{
|
||||
+ struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
+ struct mpc52xx_fec *fec = priv->fec;
|
||||
+
|
||||
+ static void fec_update_stat(struct net_device *);
|
||||
+
|
||||
+ netif_stop_queue(dev);
|
||||
+ out_be32(&fec->imask, 0x0);
|
||||
+
|
||||
|
@ -660,31 +639,33 @@ index 0000000..5591bb7
|
|||
+/* ======================================================================== */
|
||||
+
|
||||
+static int __devinit
|
||||
+mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
|
||||
+mpc52xx_fec_probe(struct device *dev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int rv;
|
||||
+ struct platform_device *pdev = to_platform_device(dev);
|
||||
+ struct net_device *ndev;
|
||||
+ struct fec_priv *priv = NULL;
|
||||
+ struct resource mem;
|
||||
+ struct resource *mem;
|
||||
+
|
||||
+ volatile int dbg=0;
|
||||
+ while(dbg)
|
||||
+ __asm("nop");
|
||||
+ /* Reserve FEC control zone */
|
||||
+ rv = of_address_to_resource(op->node, 0, &mem);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Error while parsing device node resource\n" );
|
||||
+ return rv;
|
||||
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if ((mem->end - mem->start + 1) != sizeof(struct mpc52xx_fec)) {
|
||||
+ printk(KERN_ERR DRIVER_NAME
|
||||
+ " - invalid resource size (%lx != %x), check mpc52xx_devices.c\n",
|
||||
+ mem->end - mem->start + 1, sizeof(struct mpc52xx_fec));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec),
|
||||
+ if (!request_mem_region(mem->start, sizeof(struct mpc52xx_fec),
|
||||
+ DRIVER_NAME))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ /* Get the ether ndev & it's private zone */
|
||||
+ ndev = alloc_etherdev(sizeof(struct fec_priv));
|
||||
+ if (!ndev) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not allocate the ethernet device\n" );
|
||||
+ ret = -ENOMEM;
|
||||
+ goto probe_error;
|
||||
+ }
|
||||
|
@ -702,7 +683,7 @@ index 0000000..5591bb7
|
|||
+ ndev->tx_timeout = fec_tx_timeout;
|
||||
+ ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT;
|
||||
+ ndev->flags &= ~IFF_RUNNING;
|
||||
+ ndev->base_addr = mem.start;
|
||||
+ ndev->base_addr = mem->start;
|
||||
+
|
||||
+ priv->rx_fifo = ndev->base_addr + FIELD_OFFSET(mpc52xx_fec,rfifo_data);
|
||||
+ priv->tx_fifo = ndev->base_addr + FIELD_OFFSET(mpc52xx_fec,tfifo_data);
|
||||
|
@ -712,27 +693,18 @@ index 0000000..5591bb7
|
|||
+
|
||||
+ /* ioremap the zones */
|
||||
+ priv->fec = (struct mpc52xx_fec *)
|
||||
+ ioremap(mem.start, sizeof(struct mpc52xx_fec));
|
||||
+ ioremap(mem->start, sizeof(struct mpc52xx_fec));
|
||||
+
|
||||
+ if (!priv->fec) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not remap IO memory at 0x%8.8x\n", mem.start );
|
||||
+ ret = -ENOMEM;
|
||||
+ goto probe_error;
|
||||
+ }
|
||||
+
|
||||
+ /* SDMA init */
|
||||
+#ifdef CONFIG_PPC_EFIKA
|
||||
+ priv->rx_sdma = sdma_fex_rx_preinit(FEC_RX_NUM_BD);
|
||||
+ priv->tx_sdma = sdma_fex_tx_preinit(FEC_TX_NUM_BD);
|
||||
+#else
|
||||
+ priv->rx_sdma = sdma_alloc(FEC_RX_NUM_BD);
|
||||
+ priv->tx_sdma = sdma_alloc(FEC_TX_NUM_BD);
|
||||
+#endif
|
||||
+
|
||||
+ if (!priv->rx_sdma || !priv->tx_sdma) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not init SDMA tasks\n" );
|
||||
+ ret = -ENOMEM;
|
||||
+ goto probe_error;
|
||||
+ }
|
||||
|
@ -746,10 +718,8 @@ index 0000000..5591bb7
|
|||
+ goto probe_error;
|
||||
+
|
||||
+ /* Get the IRQ we need one by one */
|
||||
+ /* Control */
|
||||
+
|
||||
+ ndev->irq = irq_of_parse_and_map(op->node, 0);
|
||||
+
|
||||
+ /* Control */
|
||||
+ ndev->irq = platform_get_irq(pdev, 0);
|
||||
+ if (request_irq(ndev->irq, &fec_interrupt, SA_INTERRUPT,
|
||||
+ DRIVER_NAME "_ctrl", ndev)) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": ctrl interrupt request failed\n");
|
||||
|
@ -758,7 +728,7 @@ index 0000000..5591bb7
|
|||
+ goto probe_error;
|
||||
+ }
|
||||
+
|
||||
+ /* RX */
|
||||
+ /* RX */
|
||||
+ priv->r_irq = sdma_irq(priv->rx_sdma);
|
||||
+ if (request_irq(priv->r_irq, &fec_rx_interrupt, SA_INTERRUPT,
|
||||
+ DRIVER_NAME "_rx", ndev)) {
|
||||
|
@ -768,7 +738,7 @@ index 0000000..5591bb7
|
|||
+ goto probe_error;
|
||||
+ }
|
||||
+
|
||||
+ /* TX */
|
||||
+ /* TX */
|
||||
+ priv->t_irq = sdma_irq(priv->tx_sdma);
|
||||
+ if (request_irq(priv->t_irq, &fec_tx_interrupt, SA_INTERRUPT,
|
||||
+ DRIVER_NAME "_tx", ndev)) {
|
||||
|
@ -796,11 +766,12 @@ index 0000000..5591bb7
|
|||
+ fec_mii_init(ndev);
|
||||
+
|
||||
+ /* We're done ! */
|
||||
+ dev_set_drvdata(&op->dev, ndev);
|
||||
+ dev_set_drvdata(dev, ndev);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Errorx handling - free everything that might be allocated */
|
||||
+
|
||||
+ /* Error handling - free everything that might be allocated */
|
||||
+probe_error:
|
||||
+
|
||||
+ if (ndev) {
|
||||
|
@ -816,18 +787,18 @@ index 0000000..5591bb7
|
|||
+ free_netdev(ndev);
|
||||
+ }
|
||||
+
|
||||
+ release_mem_region(mem.start, sizeof(struct mpc52xx_fec));
|
||||
+ release_mem_region(mem->start, sizeof(struct mpc52xx_fec));
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_fec_remove(struct of_device *op)
|
||||
+mpc52xx_fec_remove(struct device *dev)
|
||||
+{
|
||||
+ struct net_device *ndev;
|
||||
+ struct fec_priv *priv;
|
||||
+
|
||||
+ ndev = (struct net_device *) dev_get_drvdata(&op->dev);
|
||||
+ ndev = (struct net_device *) dev_get_drvdata(dev);
|
||||
+ if (!ndev)
|
||||
+ return 0;
|
||||
+ priv = (struct fec_priv *) ndev->priv;
|
||||
|
@ -844,35 +815,19 @@ index 0000000..5591bb7
|
|||
+
|
||||
+ free_netdev(ndev);
|
||||
+
|
||||
+ dev_set_drvdata(&op->dev, NULL);
|
||||
+ dev_set_drvdata(dev, NULL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct of_device_id mpc52xx_fec_of_match[] = {
|
||||
+ {
|
||||
+ .compatible = "mpc5200-ethernet",
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "mpc52xx-fec",
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static struct of_platform_driver mpc52xx_fec_driver = {
|
||||
+static struct device_driver mpc52xx_fec_driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .match_table = mpc52xx_fec_of_match,
|
||||
+ .bus = &platform_bus_type,
|
||||
+ .probe = mpc52xx_fec_probe,
|
||||
+ .remove = mpc52xx_fec_remove,
|
||||
+#ifdef CONFIG_PM
|
||||
+/* .suspend = mpc52xx_fec_suspend, TODO */
|
||||
+/* .resume = mpc52xx_fec_resume, TODO */
|
||||
+#endif
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
|
@ -882,13 +837,13 @@ index 0000000..5591bb7
|
|||
+static int __init
|
||||
+mpc52xx_fec_init(void)
|
||||
+{
|
||||
+ return of_register_platform_driver(&mpc52xx_fec_driver);
|
||||
+ return driver_register(&mpc52xx_fec_driver);
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+mpc52xx_fec_exit(void)
|
||||
+{
|
||||
+ of_unregister_platform_driver(&mpc52xx_fec_driver);
|
||||
+ driver_unregister(&mpc52xx_fec_driver);
|
||||
+}
|
||||
+
|
||||
+
|
||||
|
@ -1214,10 +1169,10 @@ index 0000000..f9eed36
|
|||
+#endif /* __DRIVERS_NET_MPC52XX_FEC_H__ */
|
||||
diff --git a/drivers/net/fec_mpc52xx/fec_phy.c b/drivers/net/fec_mpc52xx/fec_phy.c
|
||||
new file mode 100644
|
||||
index 0000000..1b2f4e1
|
||||
index 0000000..2a287de
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/fec_mpc52xx/fec_phy.c
|
||||
@@ -0,0 +1,532 @@
|
||||
@@ -0,0 +1,526 @@
|
||||
+/*
|
||||
+ * arch/ppc/52xx_io/fec_phy.c
|
||||
+ *
|
||||
|
@ -1240,14 +1195,8 @@ index 0000000..1b2f4e1
|
|||
+#include <linux/mii.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+
|
||||
+#ifdef CONFIG_PPC_EFIKA
|
||||
+#include <platforms/efika/bestcomm.h>
|
||||
+#else
|
||||
+#include <syslib/bestcomm/bestcomm.h>
|
||||
+#include <syslib/bestcomm/fec.h>
|
||||
+#endif
|
||||
+
|
||||
+#include "fec_phy.h"
|
||||
+#include "fec.h"
|
||||
+
|
||||
|
@ -1457,7 +1406,7 @@ index 0000000..1b2f4e1
|
|||
+ },
|
||||
+ (const phy_cmd_t []) { /* startup */
|
||||
+ /* restart auto-negotiation */
|
||||
+ { mk_mii_write(MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART) ),
|
||||
+ { mk_mii_write(MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART)),
|
||||
+ NULL },
|
||||
+ { mk_mii_end, }
|
||||
+ },
|
||||
|
@ -1830,5 +1779,5 @@ index 0000000..5c23bff
|
|||
+
|
||||
+extern int fec_ioctl(struct net_device *, struct ifreq *rq, int cmd);
|
||||
--
|
||||
1.4.3.2
|
||||
1.4.4.2
|
||||
|
1335
debian/patches/features/powerpc/efika/0021-POWERPC-Copy-bestcomm-support-files-into-arch-powerpc.txt
vendored
Normal file
1335
debian/patches/features/powerpc/efika/0021-POWERPC-Copy-bestcomm-support-files-into-arch-powerpc.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
464
debian/patches/features/powerpc/efika/0022-MPC52xx-PCI-now-working-on-lite5200.-ugly-but-working.txt
vendored
Normal file
464
debian/patches/features/powerpc/efika/0022-MPC52xx-PCI-now-working-on-lite5200.-ugly-but-working.txt
vendored
Normal file
|
@ -0,0 +1,464 @@
|
|||
From c4c2f5cb57335b1b47aa8007b0cfce48cc46fa06 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Tue, 21 Nov 2006 14:41:59 -0700
|
||||
Subject: [PATCH] [MPC52xx] PCI now working on lite5200... ugly, but working
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 334 +++++++++++++++++++++++++++++
|
||||
arch/powerpc/platforms/52xx/mpc52xx_pci.h | 104 +++++++++
|
||||
2 files changed, 438 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
new file mode 100644
|
||||
index 0000000..07dce3c
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
@@ -0,0 +1,334 @@
|
||||
+/*
|
||||
+ * PCI code for the Freescale MPC52xx embedded CPU.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Secret Lab Technologies Ltd.
|
||||
+ * Grant Likely <grant.likely@secretlab.ca>
|
||||
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#define DEBUG
|
||||
+
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+#include "mpc52xx_pci.h"
|
||||
+#include <asm/delay.h>
|
||||
+#include <asm/machdep.h>
|
||||
+#include <linux/kernel.h>
|
||||
+
|
||||
+
|
||||
+/* This macro is defined to activate the workaround for the bug
|
||||
+ 435 of the MPC5200 (L25R). With it activated, we don't do any
|
||||
+ 32 bits configuration access during type-1 cycles */
|
||||
+#define MPC5200_BUG_435_WORKAROUND
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 *val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#ifdef MPC5200_BUG_435_WORKAROUND
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ value = in_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3));
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ value = in_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1));
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ value = in_le16((u16 __iomem *)hose->cfg_data) |
|
||||
+ (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ if (len != 4) {
|
||||
+ value >>= ((offset & 0x3) << 3);
|
||||
+ value &= 0xffffffff >> (32 - (len << 3));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *val = value;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value, mask;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#ifdef MPC5200_BUG_435_WORKAROUND
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ out_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3), val);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1), val);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ out_le16((u16 __iomem *)hose->cfg_data,
|
||||
+ (u16)val);
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) + 1,
|
||||
+ (u16)(val>>16));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ if (len != 4) {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ offset = (offset & 0x3) << 3;
|
||||
+ mask = (0xffffffff >> (32 - (len << 3)));
|
||||
+ mask <<= offset;
|
||||
+
|
||||
+ value &= ~mask;
|
||||
+ val = value | ((val << offset) & mask);
|
||||
+ }
|
||||
+
|
||||
+ out_le32(hose->cfg_data, val);
|
||||
+ }
|
||||
+ mb();
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops mpc52xx_pci_ops = {
|
||||
+ .read = mpc52xx_pci_read_config,
|
||||
+ .write = mpc52xx_pci_write_config
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static void __init
|
||||
+mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
+ struct mpc52xx_pci __iomem *pci_regs)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ u32 tmp;
|
||||
+ int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_setup()\n");
|
||||
+
|
||||
+ pr_debug("iw0btar=%x iw1btar=%x iw2btar=%x iwcr=%x\n",
|
||||
+ in_be32(&pci_regs->iw0btar), in_be32(&pci_regs->iw1btar),
|
||||
+ in_be32(&pci_regs->iw2btar), in_be32(&pci_regs->iwcr));
|
||||
+ pr_debug("tbatr0=%x tbatr1=%x tcr=%x gscr=%x\n",
|
||||
+ in_be32(&pci_regs->tbatr0), in_be32(&pci_regs->tbatr1),
|
||||
+ in_be32(&pci_regs->tcr), in_be32(&pci_regs->gscr));
|
||||
+
|
||||
+ /* Setup control regs */
|
||||
+ tmp = in_be32(&pci_regs->scr);
|
||||
+ tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
+ out_be32(&pci_regs->scr, tmp);
|
||||
+
|
||||
+ /* Setup windows */
|
||||
+ res = &hose->mem_resources[0];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw0btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ res = &hose->mem_resources[1];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw1btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ res = &hose->io_resource;
|
||||
+ if (!res) {
|
||||
+ printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
|
||||
+ return;
|
||||
+ }
|
||||
+ pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
+ ".io_base_phys=%lx\n",
|
||||
+ res->start, res->end, res->flags, hose->io_base_phys);
|
||||
+ out_be32(&pci_regs->iw2btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
+ res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
|
||||
+
|
||||
+ pr_debug("iwcr0=%x iwcr1=%x iwcr2=%x iwcr=%x old_iwcr=%x\n",
|
||||
+ iwcr0, iwcr1, iwcr2,
|
||||
+ MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2),
|
||||
+ in_be32(&pci_regs->iwcr));
|
||||
+ out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
|
||||
+
|
||||
+ out_be32(&pci_regs->tbatr0,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
|
||||
+ out_be32(&pci_regs->tbatr1,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
|
||||
+
|
||||
+ out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
|
||||
+
|
||||
+ /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
|
||||
+ /* Not necessary and can be a bad thing if for example the bootloader
|
||||
+ is displaying a splash screen or ... Just left here for
|
||||
+ documentation purpose if anyone need it */
|
||||
+ tmp = in_be32(&pci_regs->gscr);
|
||||
+#if 0
|
||||
+ out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
|
||||
+ udelay(50);
|
||||
+#endif
|
||||
+ out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
|
||||
+
|
||||
+ pr_debug("iw0btar=%x iw1btar=%x iw2btar=%x iwcr=%x\n",
|
||||
+ in_be32(&pci_regs->iw0btar), in_be32(&pci_regs->iw1btar),
|
||||
+ in_be32(&pci_regs->iw2btar), in_be32(&pci_regs->iwcr));
|
||||
+ pr_debug("tbatr0=%x tbatr1=%x tcr=%x gscr=%x\n",
|
||||
+ in_be32(&pci_regs->tbatr0), in_be32(&pci_regs->tbatr1),
|
||||
+ in_be32(&pci_regs->tcr), in_be32(&pci_regs->gscr));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mpc52xx_pci_fixup_resources(struct pci_dev *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
|
||||
+ dev->vendor, dev->device);
|
||||
+
|
||||
+ /* We don't rely on boot loader for PCI and resets all
|
||||
+ devices */
|
||||
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
+ struct resource *res = &dev->resource[i];
|
||||
+ if (res->end > res->start) { /* Only valid resources */
|
||||
+ res->end -= res->start;
|
||||
+ res->start = 0;
|
||||
+ res->flags |= IORESOURCE_UNSET;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* The PCI Host bridge of MPC52xx has a prefetch memory resource
|
||||
+ fixed to 1Gb. Doesn't fit in the resource system so we remove it */
|
||||
+ if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
|
||||
+ ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
|
||||
+ || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
|
||||
+ struct resource *res = &dev->resource[1];
|
||||
+ res->start = res->end = res->flags = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int __init
|
||||
+mpc52xx_add_bridge(struct device_node *node)
|
||||
+{
|
||||
+ int len;
|
||||
+ struct mpc52xx_pci __iomem *pci_regs;
|
||||
+ struct pci_controller *hose;
|
||||
+ const int *bus_range;
|
||||
+ struct resource rsrc;
|
||||
+
|
||||
+ pr_debug("Adding PCI host bridge %s\n", node->full_name);
|
||||
+
|
||||
+ pci_assign_all_buses = 1;
|
||||
+
|
||||
+ if (of_address_to_resource(node, 0, &rsrc) != 0) {
|
||||
+ printk(KERN_ERR "Can't get %s resources\n", node->full_name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ bus_range = get_property(node, "bus-range", &len);
|
||||
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
+ printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||
+ " bus 0\n", node->full_name);
|
||||
+ }
|
||||
+
|
||||
+ hose = pcibios_alloc_controller();
|
||||
+ if (!hose)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
|
||||
+
|
||||
+ hose->arch_data = node;
|
||||
+ hose->set_cfg_type = 1;
|
||||
+
|
||||
+ hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
+
|
||||
+ hose->bus_offset = 0;
|
||||
+ hose->ops = &mpc52xx_pci_ops;
|
||||
+
|
||||
+ pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
|
||||
+ if (!pci_regs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pci_process_bridge_OF_ranges(hose, node, 0);
|
||||
+
|
||||
+ hose->cfg_addr = &pci_regs->car;
|
||||
+
|
||||
+ hose->cfg_data = hose->io_base_virt;
|
||||
+ hose->io_base_virt = ioremap(hose->io_base_phys,
|
||||
+ hose->io_resource.end + 1 -
|
||||
+ hose->io_resource.start);
|
||||
+ isa_io_base = (unsigned long) hose->io_base_virt;
|
||||
+
|
||||
+ mpc52xx_pci_setup(hose, pci_regs);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.h b/arch/powerpc/platforms/52xx/mpc52xx_pci.h
|
||||
new file mode 100644
|
||||
index 0000000..07a659e
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.h
|
||||
@@ -0,0 +1,104 @@
|
||||
+/*
|
||||
+ * PCI Include file the Freescale MPC52xx embedded cpu chips
|
||||
+ *
|
||||
+ * Inspired from code written by Dale Farnsworth <dfarnsworth@mvista.com>
|
||||
+ * for the 2.4 kernel.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ * Copyright (C) 2003 MontaVista, Software, Inc.
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __SYSLIB_MPC52xx_PCI_H__
|
||||
+#define __SYSLIB_MPC52xx_PCI_H__
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCI windows config */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_TARGET_IO 0xf0000000
|
||||
+#define MPC52xx_PCI_TARGET_MEM 0x00000000
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Structures mapping & Defines for PCI Unit */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_GSCR_BM 0x40000000
|
||||
+#define MPC52xx_PCI_GSCR_PE 0x20000000
|
||||
+#define MPC52xx_PCI_GSCR_SE 0x10000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
|
||||
+#define MPC52xx_PCI_GSCR_BME 0x00004000
|
||||
+#define MPC52xx_PCI_GSCR_PEE 0x00002000
|
||||
+#define MPC52xx_PCI_GSCR_SEE 0x00001000
|
||||
+#define MPC52xx_PCI_GSCR_PR 0x00000001
|
||||
+
|
||||
+
|
||||
+#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
|
||||
+ ( ( (proc_ad) & 0xff000000 ) | \
|
||||
+ ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
|
||||
+ ( ((pci_ad) >> 16) & 0x0000ff00 ) )
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
|
||||
+ ((win1) << 16) | \
|
||||
+ ((win2) << 8))
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_IWCR_ENABLE 0x1
|
||||
+#define MPC52xx_PCI_IWCR_READ 0x0
|
||||
+#define MPC52xx_PCI_IWCR_READ_LINE 0x2
|
||||
+#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
|
||||
+#define MPC52xx_PCI_IWCR_MEM 0x0
|
||||
+#define MPC52xx_PCI_IWCR_IO 0x8
|
||||
+
|
||||
+#define MPC52xx_PCI_TCR_P 0x01000000
|
||||
+#define MPC52xx_PCI_TCR_LD 0x00010000
|
||||
+
|
||||
+#define MPC52xx_PCI_TBATR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_TBATR_ENABLE 0x1
|
||||
+
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
+struct mpc52xx_pci {
|
||||
+ u32 idr; /* PCI + 0x00 */
|
||||
+ u32 scr; /* PCI + 0x04 */
|
||||
+ u32 ccrir; /* PCI + 0x08 */
|
||||
+ u32 cr1; /* PCI + 0x0C */
|
||||
+ u32 bar0; /* PCI + 0x10 */
|
||||
+ u32 bar1; /* PCI + 0x14 */
|
||||
+ u8 reserved1[16]; /* PCI + 0x18 */
|
||||
+ u32 ccpr; /* PCI + 0x28 */
|
||||
+ u32 sid; /* PCI + 0x2C */
|
||||
+ u32 erbar; /* PCI + 0x30 */
|
||||
+ u32 cpr; /* PCI + 0x34 */
|
||||
+ u8 reserved2[4]; /* PCI + 0x38 */
|
||||
+ u32 cr2; /* PCI + 0x3C */
|
||||
+ u8 reserved3[32]; /* PCI + 0x40 */
|
||||
+ u32 gscr; /* PCI + 0x60 */
|
||||
+ u32 tbatr0; /* PCI + 0x64 */
|
||||
+ u32 tbatr1; /* PCI + 0x68 */
|
||||
+ u32 tcr; /* PCI + 0x6C */
|
||||
+ u32 iw0btar; /* PCI + 0x70 */
|
||||
+ u32 iw1btar; /* PCI + 0x74 */
|
||||
+ u32 iw2btar; /* PCI + 0x78 */
|
||||
+ u8 reserved4[4]; /* PCI + 0x7C */
|
||||
+ u32 iwcr; /* PCI + 0x80 */
|
||||
+ u32 icr; /* PCI + 0x84 */
|
||||
+ u32 isr; /* PCI + 0x88 */
|
||||
+ u32 arb; /* PCI + 0x8C */
|
||||
+ u8 reserved5[104]; /* PCI + 0x90 */
|
||||
+ u32 car; /* PCI + 0xF8 */
|
||||
+ u8 reserved6[4]; /* PCI + 0xFC */
|
||||
+};
|
||||
+
|
||||
+#endif /* __ASSEMBLY__ */
|
||||
+
|
||||
+
|
||||
+#endif /* __SYSLIB_MPC52xx_PCI_H__ */
|
||||
--
|
||||
1.4.4.2
|
||||
|
700
debian/patches/features/powerpc/efika/0023-POWERPC-Make-FEC-work-on-the-lite5200.txt
vendored
Normal file
700
debian/patches/features/powerpc/efika/0023-POWERPC-Make-FEC-work-on-the-lite5200.txt
vendored
Normal file
|
@ -0,0 +1,700 @@
|
|||
From 3c687b616fee5d7097e965fce80f8f8b2b6e14cf Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 4 Dec 2006 22:29:03 -0700
|
||||
Subject: [PATCH] [POWERPC] Make FEC work on the lite5200
|
||||
|
||||
This patch may very well break Eth support on the Efika, and it's not
|
||||
very pretty. But is works well enough for an NFS rootfs. This also
|
||||
makes major bestcomm changes by removing Efika-specific bestcomm
|
||||
support and porting the arch/ppc bestcomm support driver which
|
||||
was posted to linuxppc-embedded about a year ago.
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/Kconfig | 5 +
|
||||
arch/powerpc/platforms/52xx/Makefile | 3 +
|
||||
arch/powerpc/platforms/52xx/bestcomm.c | 98 ++++++++++-------------
|
||||
arch/powerpc/platforms/52xx/bestcomm.h | 13 ++-
|
||||
arch/powerpc/platforms/52xx/fec.c | 1 -
|
||||
arch/powerpc/platforms/52xx/lite5200.c | 9 ++
|
||||
drivers/net/fec_mpc52xx/Kconfig | 2 +-
|
||||
drivers/net/fec_mpc52xx/fec.c | 137 +++++++++++++++++++++++++++----
|
||||
drivers/net/fec_mpc52xx/fec_phy.c | 6 ++
|
||||
9 files changed, 196 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
|
||||
index 8699dad..23d7d73 100644
|
||||
--- a/arch/powerpc/Kconfig
|
||||
+++ b/arch/powerpc/Kconfig
|
||||
@@ -429,6 +429,11 @@ config PPC_MPC52xx
|
||||
bool
|
||||
default n
|
||||
|
||||
+config PPC_BESTCOMM
|
||||
+ bool
|
||||
+ depends on PPC_MPC52xx
|
||||
+ default y
|
||||
+
|
||||
config PPC_EFIKA
|
||||
bool "bPlan Efika 5k2. MPC5200B based computer"
|
||||
depends on PPC_MULTIPLATFORM && PPC32
|
||||
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
|
||||
index a46184a..d85ea04 100644
|
||||
--- a/arch/powerpc/platforms/52xx/Makefile
|
||||
+++ b/arch/powerpc/platforms/52xx/Makefile
|
||||
@@ -3,6 +3,9 @@
|
||||
#
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
obj-y += mpc52xx_pic.o mpc52xx_common.o
|
||||
+obj-$(CONFIG_PCI) += mpc52xx_pci.o
|
||||
+obj-$(CONFIG_PPC_BESTCOMM) += bestcomm.o
|
||||
+obj-$(CONFIG_FEC_MPC52xx) += sdma_fec_rx_task.o sdma_fec_tx_task.o fec.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o
|
||||
diff --git a/arch/powerpc/platforms/52xx/bestcomm.c b/arch/powerpc/platforms/52xx/bestcomm.c
|
||||
index ef45e02..9935b01 100644
|
||||
--- a/arch/powerpc/platforms/52xx/bestcomm.c
|
||||
+++ b/arch/powerpc/platforms/52xx/bestcomm.c
|
||||
@@ -16,7 +16,6 @@
|
||||
* Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
|
||||
*/
|
||||
|
||||
-#include <linux/config.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -24,17 +23,19 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
-#include <linux/device.h>
|
||||
|
||||
#include <asm/bug.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
+#include <asm/of_platform.h>
|
||||
|
||||
#include "bestcomm.h"
|
||||
|
||||
-#define DRIVER_NAME "mpc52xx-sdma"
|
||||
+#define DRIVER_NAME "mpc52xx-bestcomm"
|
||||
|
||||
struct sdma_io sdma;
|
||||
+struct device_node *sdma_node;
|
||||
+struct device_node *sram_node;
|
||||
|
||||
static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
@@ -42,7 +43,8 @@ static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
|
||||
void sdma_dump(void)
|
||||
{
|
||||
int i;
|
||||
- printk("** SDMA registers: pa = %08x, va = %08x\n", sdma.base_reg_addr, sdma.io);
|
||||
+ printk("** SDMA registers: pa = %.8lx, va = %p\n",
|
||||
+ sdma.base_reg_addr, sdma.io);
|
||||
printk("** taskBar = %08x\n", sdma.io->taskBar);
|
||||
printk("** currentPointer = %08x\n", sdma.io->currentPointer);
|
||||
printk("** endPointer = %08x\n", sdma.io->endPointer);
|
||||
@@ -254,6 +256,7 @@ struct sdma *sdma_alloc(int queue_size)
|
||||
}
|
||||
|
||||
s->num_bd = queue_size;
|
||||
+ s->node = sdma_node;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -264,29 +267,49 @@ void sdma_free(struct sdma *s)
|
||||
kfree(s);
|
||||
}
|
||||
|
||||
-static int __devinit mpc52xx_sdma_probe(struct device *dev)
|
||||
+static int __init mpc52xx_sdma_init(void)
|
||||
{
|
||||
- struct platform_device *pdev = to_platform_device(dev);
|
||||
int task;
|
||||
u32 *context;
|
||||
u32 *fdt;
|
||||
struct sdma_tdt *tdt;
|
||||
- struct resource *mem_io, *mem_sram;
|
||||
- u32 tdt_pa, var_pa, context_pa, fdt_pa;
|
||||
+ struct resource mem_io, mem_sram;
|
||||
+ u32 tdt_pa, var_pa, context_pa, fdt_pa;
|
||||
int ret = -ENODEV;
|
||||
|
||||
- mem_io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- mem_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
- if (!mem_io || !mem_sram)
|
||||
+ /* Find SDMA registers */
|
||||
+ sdma_node = of_find_compatible_node(NULL, "dma-controller", "mpc52xx-bestcomm");
|
||||
+ if (!sdma_node) {
|
||||
+ printk (KERN_ERR DRIVER_NAME ": could not locate SDRAM controller\n");
|
||||
goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((ret = of_address_to_resource(sdma_node, 0, &mem_io)) != 0) {
|
||||
+ printk(KERN_ERR "Could not get address of SDMA controller\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* Find SRAM location */
|
||||
+ sram_node = of_find_compatible_node(NULL, "sram", "mpc52xx-sram");
|
||||
+ if (!sram_node) {
|
||||
+ printk (KERN_ERR DRIVER_NAME ": could not locate SRAM\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((ret = of_address_to_resource(sram_node, 0, &mem_sram)) != 0) {
|
||||
+ printk(KERN_ERR "Could not get address of SRAM\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- if (!request_mem_region(mem_io->start, mem_io->end - mem_io->start + 1, DRIVER_NAME)) {
|
||||
+ /* Map register regions */
|
||||
+ if (!request_mem_region(mem_io.start, mem_io.end - mem_io.start + 1,
|
||||
+ DRIVER_NAME)) {
|
||||
printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
|
||||
goto out;
|
||||
}
|
||||
- sdma.base_reg_addr = mem_io->start;
|
||||
+ sdma.base_reg_addr = mem_io.start;
|
||||
|
||||
- sdma.io = ioremap_nocache(mem_io->start, sizeof(struct mpc52xx_sdma));
|
||||
+ sdma.io = ioremap_nocache(mem_io.start, sizeof(struct mpc52xx_sdma));
|
||||
|
||||
if (!sdma.io ) {
|
||||
printk(KERN_ERR DRIVER_NAME " - failed to map sdma regs\n");
|
||||
@@ -296,14 +319,14 @@ static int __devinit mpc52xx_sdma_probe(struct device *dev)
|
||||
|
||||
SDMA_DUMP_REGS();
|
||||
|
||||
- sdma.sram_size = mem_sram->end - mem_sram->start + 1;
|
||||
- if (!request_mem_region(mem_sram->start, sdma.sram_size, DRIVER_NAME)) {
|
||||
+ sdma.sram_size = mem_sram.end - mem_sram.start + 1;
|
||||
+ if (!request_mem_region(mem_sram.start, sdma.sram_size, DRIVER_NAME)) {
|
||||
printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
|
||||
goto req_sram_error;
|
||||
}
|
||||
|
||||
- sdma.base_sram_addr = mem_sram->start;
|
||||
- sdma.sram = ioremap_nocache(mem_sram->start, sdma.sram_size);
|
||||
+ sdma.base_sram_addr = mem_sram.start;
|
||||
+ sdma.sram = ioremap_nocache(mem_sram.start, sdma.sram_size);
|
||||
if (!sdma.sram ) {
|
||||
printk(KERN_ERR DRIVER_NAME " - failed to map sdma sram\n");
|
||||
ret = -ENOMEM;
|
||||
@@ -350,50 +373,17 @@ static int __devinit mpc52xx_sdma_probe(struct device *dev)
|
||||
return 0;
|
||||
|
||||
map_sram_error:
|
||||
- release_mem_region(mem_sram->start, sdma.sram_size);
|
||||
+ release_mem_region(mem_sram.start, sdma.sram_size);
|
||||
req_sram_error:
|
||||
iounmap(sdma.io);
|
||||
map_io_error:
|
||||
- release_mem_region(mem_io->start, mem_io->end - mem_io->start + 1);
|
||||
+ release_mem_region(mem_io.start, mem_io.end - mem_io.start + 1);
|
||||
out:
|
||||
printk(KERN_ERR "DMA: MPC52xx BestComm init FAILED !!!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
-static struct device_driver mpc52xx_sdma_driver = {
|
||||
- .owner = THIS_MODULE,
|
||||
- .name = DRIVER_NAME,
|
||||
- .bus = &platform_bus_type,
|
||||
- .probe = mpc52xx_sdma_probe,
|
||||
-/* .remove = mpc52xx_sdma_remove, TODO */
|
||||
-#ifdef CONFIG_PM
|
||||
-/* .suspend = mpc52xx_sdma_suspend, TODO */
|
||||
-/* .resume = mpc52xx_sdma_resume, TODO */
|
||||
-#endif
|
||||
-};
|
||||
-
|
||||
-static int __init
|
||||
-mpc52xx_sdma_init(void)
|
||||
-{
|
||||
- printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
|
||||
- return driver_register(&mpc52xx_sdma_driver);
|
||||
-}
|
||||
-
|
||||
-#ifdef MODULE
|
||||
-static void __exit
|
||||
-mpc52xx_sdma_exit(void)
|
||||
-{
|
||||
- driver_unregister(&mpc52xx_sdma_driver);
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-#ifndef MODULE
|
||||
- subsys_initcall(mpc52xx_sdma_init);
|
||||
-#else
|
||||
- module_init(mpc52xx_sdma_init);
|
||||
- module_exit(mpc52xx_sdma_exit);
|
||||
-#endif
|
||||
+subsys_initcall(mpc52xx_sdma_init);
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
|
||||
diff --git a/arch/powerpc/platforms/52xx/bestcomm.h b/arch/powerpc/platforms/52xx/bestcomm.h
|
||||
index 14bf397..bd2619d 100644
|
||||
--- a/arch/powerpc/platforms/52xx/bestcomm.h
|
||||
+++ b/arch/powerpc/platforms/52xx/bestcomm.h
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef __BESTCOMM_BESTCOMM_H__
|
||||
#define __BESTCOMM_BESTCOMM_H__
|
||||
|
||||
+#include "mpc52xx_pic.h"
|
||||
+
|
||||
/* Buffer Descriptor definitions */
|
||||
struct sdma_bd {
|
||||
u32 status;
|
||||
@@ -70,6 +72,7 @@ struct sdma {
|
||||
u16 num_bd;
|
||||
s16 tasknum;
|
||||
u32 flags;
|
||||
+ struct device_node *node;
|
||||
};
|
||||
|
||||
#define SDMA_FLAGS_NONE 0x0000
|
||||
@@ -116,7 +119,9 @@ struct sdma_tdt {
|
||||
|
||||
static inline void sdma_enable_task(int task)
|
||||
{
|
||||
- DPRINTK("***DMA enable task (%d): tdt = %08x\n",task, sdma.tdt);
|
||||
+ u16 reg;
|
||||
+
|
||||
+ DPRINTK("***DMA enable task (%d): tdt = %p\n",task, sdma.tdt);
|
||||
DPRINTK("***tdt->start = %08x\n",sdma.tdt[task].start);
|
||||
DPRINTK("***tdt->stop = %08x\n",sdma.tdt[task].stop);
|
||||
DPRINTK("***tdt->var = %08x\n",sdma.tdt[task].var);
|
||||
@@ -127,8 +132,8 @@ static inline void sdma_enable_task(int task)
|
||||
DPRINTK("***tdt->litbase = %08x\n",sdma.tdt[task].litbase);
|
||||
DPRINTK("***--------------\n");
|
||||
|
||||
- u16 reg = in_be16(&sdma.io->tcr[task]);
|
||||
- DPRINTK("***enable task: &sdma.io->tcr=%08x, reg = %04x\n", &sdma.io->tcr, reg);
|
||||
+ reg = in_be16(&sdma.io->tcr[task]);
|
||||
+ DPRINTK("***enable task: &sdma.io->tcr=%p, reg = %04x\n", &sdma.io->tcr, reg);
|
||||
out_be16(&sdma.io->tcr[task], reg | TASK_ENABLE);
|
||||
}
|
||||
|
||||
@@ -141,7 +146,7 @@ static inline void sdma_disable_task(int task)
|
||||
|
||||
static inline int sdma_irq(struct sdma *s)
|
||||
{
|
||||
- return MPC52xx_SDMA_IRQ_BASE + s->tasknum;
|
||||
+ return irq_of_parse_and_map(s->node, s->tasknum);
|
||||
}
|
||||
|
||||
static inline void sdma_enable(struct sdma *s)
|
||||
diff --git a/arch/powerpc/platforms/52xx/fec.c b/arch/powerpc/platforms/52xx/fec.c
|
||||
index 8756856..90df6f4 100644
|
||||
--- a/arch/powerpc/platforms/52xx/fec.c
|
||||
+++ b/arch/powerpc/platforms/52xx/fec.c
|
||||
@@ -16,7 +16,6 @@
|
||||
* Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
|
||||
*/
|
||||
|
||||
-#include <linux/config.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
index 0f21bab..f1bbe24 100644
|
||||
--- a/arch/powerpc/platforms/52xx/lite5200.c
|
||||
+++ b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
@@ -107,6 +107,15 @@ static void __init lite52xx_setup_arch(void)
|
||||
mpc52xx_setup_cpu(); /* Generic */
|
||||
lite52xx_setup_cpu(); /* Platorm specific */
|
||||
|
||||
+#ifdef CONFIG_PCI
|
||||
+ np = of_find_node_by_type(np, "pci");
|
||||
+ if (np)
|
||||
+ mpc52xx_add_bridge(np);
|
||||
+
|
||||
+ //ppc_md.pci_swizzle = common_swizzle;
|
||||
+ //ppc_md.pci_exclude_device = mpc52xx_exclude_device;
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (initrd_start)
|
||||
ROOT_DEV = Root_RAM0;
|
||||
diff --git a/drivers/net/fec_mpc52xx/Kconfig b/drivers/net/fec_mpc52xx/Kconfig
|
||||
index 098c3fa..b6bce55 100644
|
||||
--- a/drivers/net/fec_mpc52xx/Kconfig
|
||||
+++ b/drivers/net/fec_mpc52xx/Kconfig
|
||||
@@ -11,7 +11,7 @@ config FEC_MPC52xx
|
||||
Fast Ethernet Controller
|
||||
|
||||
config USE_MDIO
|
||||
- bool " Use external Ethernet MII PHY"
|
||||
+ bool "Use external Ethernet MII PHY"
|
||||
select MII
|
||||
depends FEC_MPC52xx
|
||||
---help---
|
||||
diff --git a/drivers/net/fec_mpc52xx/fec.c b/drivers/net/fec_mpc52xx/fec.c
|
||||
index b5f1559..894da79 100644
|
||||
--- a/drivers/net/fec_mpc52xx/fec.c
|
||||
+++ b/drivers/net/fec_mpc52xx/fec.c
|
||||
@@ -30,17 +30,24 @@
|
||||
#include <asm/ppcboot.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+#include <asm/of_device.h>
|
||||
+#include <asm/of_platform.h>
|
||||
+#include <platforms/52xx/bestcomm.h>
|
||||
+#include <platforms/52xx/fec.h>
|
||||
+#else
|
||||
#include <syslib/bestcomm/bestcomm.h>
|
||||
#include <syslib/bestcomm/fec.h>
|
||||
+#endif
|
||||
|
||||
#include "fec_phy.h"
|
||||
#include "fec.h"
|
||||
|
||||
#define DRIVER_NAME "mpc52xx-fec"
|
||||
|
||||
-static irqreturn_t fec_interrupt(int, void *, struct pt_regs *);
|
||||
-static irqreturn_t fec_rx_interrupt(int, void *, struct pt_regs *);
|
||||
-static irqreturn_t fec_tx_interrupt(int, void *, struct pt_regs *);
|
||||
+static irqreturn_t fec_interrupt(int, void *);
|
||||
+static irqreturn_t fec_rx_interrupt(int, void *);
|
||||
+static irqreturn_t fec_tx_interrupt(int, void *);
|
||||
static struct net_device_stats *fec_get_stats(struct net_device *);
|
||||
static void fec_set_multicast_list(struct net_device *dev);
|
||||
static void fec_reinit(struct net_device *dev);
|
||||
@@ -233,7 +240,7 @@ static int fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
/* This handles BestComm transmit task interrupts
|
||||
*/
|
||||
-static irqreturn_t fec_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+static irqreturn_t fec_tx_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = dev_id;
|
||||
struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
@@ -259,7 +266,7 @@ static irqreturn_t fec_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static irqreturn_t fec_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+static irqreturn_t fec_rx_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = dev_id;
|
||||
struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
@@ -316,7 +323,7 @@ static irqreturn_t fec_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static irqreturn_t fec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
+static irqreturn_t fec_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
@@ -324,13 +331,18 @@ static irqreturn_t fec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
int ievent;
|
||||
|
||||
ievent = in_be32(&fec->ievent);
|
||||
+ if (!ievent)
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
out_be32(&fec->ievent, ievent); /* clear pending events */
|
||||
|
||||
if (ievent & (FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
|
||||
- if (ievent & FEC_IEVENT_RFIFO_ERROR)
|
||||
- printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR\n");
|
||||
- if (ievent & FEC_IEVENT_XFIFO_ERROR)
|
||||
- printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR\n");
|
||||
+ if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR (%.8x)\n",
|
||||
+ ievent);
|
||||
+ if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
|
||||
+ printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR (%.8x)\n",
|
||||
+ ievent);
|
||||
fec_reinit(dev);
|
||||
}
|
||||
else if (ievent & FEC_IEVENT_MII)
|
||||
@@ -495,7 +507,9 @@ static void fec_hw_init(struct net_device *dev)
|
||||
{
|
||||
struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
struct mpc52xx_fec *fec = priv->fec;
|
||||
+#if !defined(CONFIG_PPC_MERGE)
|
||||
bd_t *bd = (bd_t *) &__res;
|
||||
+#endif
|
||||
|
||||
out_be32(&fec->op_pause, 0x00010020);
|
||||
out_be32(&fec->rfifo_cntrl, 0x0f000000);
|
||||
@@ -507,7 +521,9 @@ static void fec_hw_init(struct net_device *dev)
|
||||
out_be32(&fec->iaddr1, 0x00000000); /* No individual filter */
|
||||
out_be32(&fec->iaddr2, 0x00000000); /* No individual filter */
|
||||
|
||||
+#if !defined(CONFIG_PPC_MERGE)
|
||||
priv->phy_speed = ((bd->bi_ipbfreq >> 20) / 5) << 1;
|
||||
+#endif
|
||||
|
||||
fec_restart(dev, 0); /* always use half duplex mode only */
|
||||
/*
|
||||
@@ -522,7 +538,6 @@ static void fec_reinit(struct net_device *dev)
|
||||
{
|
||||
struct fec_priv *priv = (struct fec_priv *)dev->priv;
|
||||
struct mpc52xx_fec *fec = priv->fec;
|
||||
- static void fec_update_stat(struct net_device *);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
out_be32(&fec->imask, 0x0);
|
||||
@@ -551,19 +566,38 @@ static void fec_reinit(struct net_device *dev)
|
||||
/* Platform Driver */
|
||||
/* ======================================================================== */
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+static int __devinit
|
||||
+mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
|
||||
+#else
|
||||
static int __devinit
|
||||
mpc52xx_fec_probe(struct device *dev)
|
||||
+#endif
|
||||
{
|
||||
int ret;
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ int rv;
|
||||
+ struct resource __mem;
|
||||
+ struct resource *mem = &__mem;
|
||||
+#else
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
+ struct resource *mem;
|
||||
+#endif
|
||||
struct net_device *ndev;
|
||||
struct fec_priv *priv = NULL;
|
||||
- struct resource *mem;
|
||||
|
||||
volatile int dbg=0;
|
||||
while(dbg)
|
||||
__asm("nop");
|
||||
/* Reserve FEC control zone */
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ rv = of_address_to_resource(op->node, 0, mem);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Error while parsing device node resource\n" );
|
||||
+ return rv;
|
||||
+ }
|
||||
+#else
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if ((mem->end - mem->start + 1) != sizeof(struct mpc52xx_fec)) {
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
@@ -571,7 +605,8 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
mem->end - mem->start + 1, sizeof(struct mpc52xx_fec));
|
||||
return -EINVAL;
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
+
|
||||
if (!request_mem_region(mem->start, sizeof(struct mpc52xx_fec),
|
||||
DRIVER_NAME))
|
||||
return -EBUSY;
|
||||
@@ -579,6 +614,8 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
/* Get the ether ndev & it's private zone */
|
||||
ndev = alloc_etherdev(sizeof(struct fec_priv));
|
||||
if (!ndev) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not allocate the ethernet device\n" );
|
||||
ret = -ENOMEM;
|
||||
goto probe_error;
|
||||
}
|
||||
@@ -609,6 +646,8 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
ioremap(mem->start, sizeof(struct mpc52xx_fec));
|
||||
|
||||
if (!priv->fec) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not remap IO memory at 0x%8.8x\n", mem->start );
|
||||
ret = -ENOMEM;
|
||||
goto probe_error;
|
||||
}
|
||||
@@ -618,6 +657,8 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
priv->tx_sdma = sdma_alloc(FEC_TX_NUM_BD);
|
||||
|
||||
if (!priv->rx_sdma || !priv->tx_sdma) {
|
||||
+ printk(KERN_ERR DRIVER_NAME ": "
|
||||
+ "Can not init SDMA tasks\n" );
|
||||
ret = -ENOMEM;
|
||||
goto probe_error;
|
||||
}
|
||||
@@ -631,8 +672,13 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
goto probe_error;
|
||||
|
||||
/* Get the IRQ we need one by one */
|
||||
- /* Control */
|
||||
+ /* Control */
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ ndev->irq = irq_of_parse_and_map(op->node, 0);
|
||||
+#else
|
||||
ndev->irq = platform_get_irq(pdev, 0);
|
||||
+#endif
|
||||
+
|
||||
if (request_irq(ndev->irq, &fec_interrupt, SA_INTERRUPT,
|
||||
DRIVER_NAME "_ctrl", ndev)) {
|
||||
printk(KERN_ERR DRIVER_NAME ": ctrl interrupt request failed\n");
|
||||
@@ -641,26 +687,32 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
goto probe_error;
|
||||
}
|
||||
|
||||
- /* RX */
|
||||
+ /* RX */
|
||||
priv->r_irq = sdma_irq(priv->rx_sdma);
|
||||
if (request_irq(priv->r_irq, &fec_rx_interrupt, SA_INTERRUPT,
|
||||
DRIVER_NAME "_rx", ndev)) {
|
||||
- printk(KERN_ERR DRIVER_NAME ": rx interrupt request failed\n");
|
||||
+ printk(KERN_ERR DRIVER_NAME ": rx request_irq(0x%x) failed\n",
|
||||
+ priv->r_irq);
|
||||
ret = -EBUSY;
|
||||
priv->r_irq = -1; /* Don't try to free it */
|
||||
goto probe_error;
|
||||
}
|
||||
|
||||
- /* TX */
|
||||
+ /* TX */
|
||||
priv->t_irq = sdma_irq(priv->tx_sdma);
|
||||
if (request_irq(priv->t_irq, &fec_tx_interrupt, SA_INTERRUPT,
|
||||
DRIVER_NAME "_tx", ndev)) {
|
||||
- printk(KERN_ERR DRIVER_NAME ": tx interrupt request failed\n");
|
||||
+ printk(KERN_ERR DRIVER_NAME ": tx request_irq(0x%x) failed\n",
|
||||
+ priv->t_irq);
|
||||
ret = -EBUSY;
|
||||
priv->t_irq = -1; /* Don't try to free it */
|
||||
goto probe_error;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
|
||||
+#endif
|
||||
+
|
||||
/* MAC address init */
|
||||
if (memcmp(mpc52xx_fec_mac_addr, null_mac, 6) != 0)
|
||||
memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
|
||||
@@ -679,7 +731,11 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
fec_mii_init(ndev);
|
||||
|
||||
/* We're done ! */
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ dev_set_drvdata(&op->dev, ndev);
|
||||
+#else
|
||||
dev_set_drvdata(dev, ndev);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -705,13 +761,22 @@ probe_error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+static int
|
||||
+mpc52xx_fec_remove(struct of_device *op)
|
||||
+#else
|
||||
static int
|
||||
mpc52xx_fec_remove(struct device *dev)
|
||||
+#endif
|
||||
{
|
||||
struct net_device *ndev;
|
||||
struct fec_priv *priv;
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ ndev = (struct net_device *) dev_get_drvdata(&op->dev);
|
||||
+#else
|
||||
ndev = (struct net_device *) dev_get_drvdata(dev);
|
||||
+#endif
|
||||
if (!ndev)
|
||||
return 0;
|
||||
priv = (struct fec_priv *) ndev->priv;
|
||||
@@ -728,10 +793,37 @@ mpc52xx_fec_remove(struct device *dev)
|
||||
|
||||
free_netdev(ndev);
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ dev_set_drvdata(&op->dev, NULL);
|
||||
+#else
|
||||
dev_set_drvdata(dev, NULL);
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+static struct of_device_id mpc52xx_fec_of_match[] = {
|
||||
+ { .compatible = "mpc5200-ethernet", },
|
||||
+ { .compatible = "mpc52xx-fec", },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static struct of_platform_driver mpc52xx_fec_driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .match_table = mpc52xx_fec_of_match,
|
||||
+ .probe = mpc52xx_fec_probe,
|
||||
+ .remove = mpc52xx_fec_remove,
|
||||
+#ifdef CONFIG_PM
|
||||
+/* .suspend = mpc52xx_fec_suspend, TODO */
|
||||
+/* .resume = mpc52xx_fec_resume, TODO */
|
||||
+#endif
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+#else
|
||||
static struct device_driver mpc52xx_fec_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.bus = &platform_bus_type,
|
||||
@@ -742,6 +834,7 @@ static struct device_driver mpc52xx_fec_driver = {
|
||||
/* .resume = mpc52xx_fec_resume, TODO */
|
||||
#endif
|
||||
};
|
||||
+#endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Module */
|
||||
@@ -750,13 +843,21 @@ static struct device_driver mpc52xx_fec_driver = {
|
||||
static int __init
|
||||
mpc52xx_fec_init(void)
|
||||
{
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ return of_register_platform_driver(&mpc52xx_fec_driver);
|
||||
+#else
|
||||
return driver_register(&mpc52xx_fec_driver);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void __exit
|
||||
mpc52xx_fec_exit(void)
|
||||
{
|
||||
+#if defined(CONFIG_PPC_MERGE)
|
||||
+ of_unregister_platform_driver(&mpc52xx_fec_driver);
|
||||
+#else
|
||||
driver_unregister(&mpc52xx_fec_driver);
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
diff --git a/drivers/net/fec_mpc52xx/fec_phy.c b/drivers/net/fec_mpc52xx/fec_phy.c
|
||||
index 2a287de..25e0409 100644
|
||||
--- a/drivers/net/fec_mpc52xx/fec_phy.c
|
||||
+++ b/drivers/net/fec_mpc52xx/fec_phy.c
|
||||
@@ -20,8 +20,14 @@
|
||||
#include <linux/mii.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
+
|
||||
+#ifdef CONFIG_PPC_MERGE
|
||||
+#include <platforms/52xx/bestcomm.h>
|
||||
+#else
|
||||
#include <syslib/bestcomm/bestcomm.h>
|
||||
#include <syslib/bestcomm/fec.h>
|
||||
+#endif
|
||||
+
|
||||
#include "fec_phy.h"
|
||||
#include "fec.h"
|
||||
|
||||
--
|
||||
1.4.4.2
|
||||
|
26
debian/patches/features/powerpc/efika/0024-Add-missing-function-prototype.txt
vendored
Normal file
26
debian/patches/features/powerpc/efika/0024-Add-missing-function-prototype.txt
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
From 4ad1395745f590eba1b5220c8dd3ca6541f49db7 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 4 Dec 2006 22:55:49 -0700
|
||||
Subject: [PATCH] Add missing function prototype
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
include/asm-powerpc/mpc52xx.h | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
|
||||
index 4560d72..7afd5bf 100644
|
||||
--- a/include/asm-powerpc/mpc52xx.h
|
||||
+++ b/include/asm-powerpc/mpc52xx.h
|
||||
@@ -249,6 +249,8 @@ extern void mpc52xx_declare_of_platform_devices(void);
|
||||
extern void mpc52xx_init_irq(void);
|
||||
extern unsigned int mpc52xx_get_irq(void);
|
||||
|
||||
+extern int __init mpc52xx_add_bridge(struct device_node *node);
|
||||
+
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_POWERPC_MPC52xx_H__ */
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
From 6d3cbf9a4549928be8ed15cf6a3576c217723895 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas DET <nd@bplan-gmbh.de>
|
||||
Date: Fri, 24 Nov 2006 13:22:22 +0100
|
||||
Subject: [PATCH] Added RTAS support for 32bit PowerPC
|
||||
From 95f80c44731c46261b0ba334b35ee803f21ef60b Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 4 Dec 2006 23:01:13 -0700
|
||||
Subject: [PATCH] [POWERPC] Misc EFIKA fixups for rtas/chrp
|
||||
|
||||
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
|
||||
---
|
||||
arch/powerpc/kernel/proc_ppc64.c | 9 ---------
|
||||
arch/powerpc/kernel/rtas-proc.c | 36 ++++++++++++++++++++++++++----------
|
||||
2 files changed, 26 insertions(+), 19 deletions(-)
|
||||
arch/powerpc/kernel/proc_ppc64.c | 9 --------
|
||||
arch/powerpc/kernel/rtas-proc.c | 36 +++++++++++++++++++++++++---------
|
||||
arch/powerpc/platforms/chrp/setup.c | 9 ++++++++
|
||||
3 files changed, 35 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
|
||||
index f598cb5..9b9c32d 100644
|
||||
index dd7001c..fa54220 100644
|
||||
--- a/arch/powerpc/kernel/proc_ppc64.c
|
||||
+++ b/arch/powerpc/kernel/proc_ppc64.c
|
||||
@@ -51,15 +51,6 @@ static int __init proc_ppc64_create(void
|
||||
@@ -51,15 +51,6 @@ static int __init proc_ppc64_create(void)
|
||||
if (!root)
|
||||
return 1;
|
||||
|
||||
|
@ -33,7 +33,7 @@ diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
|
|||
index 2fe82ab..4c06c32 100644
|
||||
--- a/arch/powerpc/kernel/rtas-proc.c
|
||||
+++ b/arch/powerpc/kernel/rtas-proc.c
|
||||
@@ -253,43 +253,59 @@ static void get_location_code(struct seq
|
||||
@@ -253,43 +253,59 @@ static void get_location_code(struct seq_file *m,
|
||||
static void check_location_string(struct seq_file *m, const char *c);
|
||||
static void check_location(struct seq_file *m, const char *c);
|
||||
|
||||
|
@ -103,6 +103,31 @@ index 2fe82ab..4c06c32 100644
|
|||
if (entry)
|
||||
entry->proc_fops = &ppc_rtas_rmo_buf_ops;
|
||||
|
||||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
|
||||
index e1f51d4..ec4515c 100644
|
||||
--- a/arch/powerpc/platforms/chrp/setup.c
|
||||
+++ b/arch/powerpc/platforms/chrp/setup.c
|
||||
@@ -580,11 +580,20 @@ static int __init chrp_probe(void)
|
||||
{
|
||||
char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"device_type", NULL);
|
||||
+
|
||||
+ char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
+ "model", NULL);
|
||||
if (dtype == NULL)
|
||||
return 0;
|
||||
if (strcmp(dtype, "chrp"))
|
||||
return 0;
|
||||
|
||||
+ /*
|
||||
+ * Filter out efika because it has its own platform
|
||||
+ */
|
||||
+ if (model && (strcmp(model, "EFIKA5K2") == 0) )
|
||||
+ return 0;
|
||||
+
|
||||
ISA_DMA_THRESHOLD = ~0L;
|
||||
DMA_MODE_READ = 0x44;
|
||||
DMA_MODE_WRITE = 0x48;
|
||||
--
|
||||
1.4.3.2
|
||||
1.4.4.2
|
||||
|
911
debian/patches/features/powerpc/efika/0026-POWERPC-Cleanup-mpc52xx-PCI-support.txt
vendored
Normal file
911
debian/patches/features/powerpc/efika/0026-POWERPC-Cleanup-mpc52xx-PCI-support.txt
vendored
Normal file
|
@ -0,0 +1,911 @@
|
|||
From 78aaa3476bf62a50d85a9753bf1ef82fd296ca73 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 11 Dec 2006 22:41:49 -0700
|
||||
Subject: [PATCH] [POWERPC] Cleanup mpc52xx PCI support
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/Kconfig | 17 ++-
|
||||
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 334 ------------------------
|
||||
arch/powerpc/platforms/52xx/mpc52xx_pci.h | 104 --------
|
||||
arch/powerpc/platforms/52xx/pci.c | 404 +++++++++++++++++++++++++++++
|
||||
4 files changed, 420 insertions(+), 439 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
|
||||
index 23d7d73..ec17225 100644
|
||||
--- a/arch/powerpc/Kconfig
|
||||
+++ b/arch/powerpc/Kconfig
|
||||
@@ -429,6 +429,21 @@ config PPC_MPC52xx
|
||||
bool
|
||||
default n
|
||||
|
||||
+config PPC_MPC5200
|
||||
+ bool
|
||||
+ select PPC_MPC52xx
|
||||
+ default n
|
||||
+
|
||||
+config PPC_MPC5200_BUGFIX
|
||||
+ bool "MPC5200 (L25R) bugfix support"
|
||||
+ depends on PPC_MPC5200
|
||||
+ default n
|
||||
+ help
|
||||
+ Enable workarounds for original MPC5200 errata. This is not required
|
||||
+ for MPC5200B based boards.
|
||||
+
|
||||
+ It is safe to say 'Y' here
|
||||
+
|
||||
config PPC_BESTCOMM
|
||||
bool
|
||||
depends on PPC_MPC52xx
|
||||
@@ -446,7 +461,7 @@ config PPC_EFIKA
|
||||
config PPC_LITE5200
|
||||
bool "Freescale Lite5200 Eval Board"
|
||||
depends on PPC_MULTIPLATFORM && PPC32
|
||||
- select PPC_MPC52xx
|
||||
+ select PPC_MPC5200
|
||||
default n
|
||||
|
||||
config PPC_PMAC
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
deleted file mode 100644
|
||||
index 07dce3c..0000000
|
||||
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
+++ /dev/null
|
||||
@@ -1,334 +0,0 @@
|
||||
-/*
|
||||
- * PCI code for the Freescale MPC52xx embedded CPU.
|
||||
- *
|
||||
- * Copyright (C) 2004 Secret Lab Technologies Ltd.
|
||||
- * Grant Likely <grant.likely@secretlab.ca>
|
||||
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
- *
|
||||
- * This file is licensed under the terms of the GNU General Public License
|
||||
- * version 2. This program is licensed "as is" without any warranty of any
|
||||
- * kind, whether express or implied.
|
||||
- */
|
||||
-
|
||||
-#define DEBUG
|
||||
-
|
||||
-#include <asm/pci.h>
|
||||
-#include <asm/mpc52xx.h>
|
||||
-#include "mpc52xx_pci.h"
|
||||
-#include <asm/delay.h>
|
||||
-#include <asm/machdep.h>
|
||||
-#include <linux/kernel.h>
|
||||
-
|
||||
-
|
||||
-/* This macro is defined to activate the workaround for the bug
|
||||
- 435 of the MPC5200 (L25R). With it activated, we don't do any
|
||||
- 32 bits configuration access during type-1 cycles */
|
||||
-#define MPC5200_BUG_435_WORKAROUND
|
||||
-
|
||||
-
|
||||
-static int
|
||||
-mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
- int offset, int len, u32 *val)
|
||||
-{
|
||||
- struct pci_controller *hose = bus->sysdata;
|
||||
- u32 value;
|
||||
-
|
||||
- if (ppc_md.pci_exclude_device)
|
||||
- if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
- return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
-
|
||||
- out_be32(hose->cfg_addr,
|
||||
- (1 << 31) |
|
||||
- ((bus->number - hose->bus_offset) << 16) |
|
||||
- (devfn << 8) |
|
||||
- (offset & 0xfc));
|
||||
- mb();
|
||||
-
|
||||
-#ifdef MPC5200_BUG_435_WORKAROUND
|
||||
- if (bus->number != hose->bus_offset) {
|
||||
- switch (len) {
|
||||
- case 1:
|
||||
- value = in_8(((u8 __iomem *)hose->cfg_data) +
|
||||
- (offset & 3));
|
||||
- break;
|
||||
- case 2:
|
||||
- value = in_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
- ((offset>>1) & 1));
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- value = in_le16((u16 __iomem *)hose->cfg_data) |
|
||||
- (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- value = in_le32(hose->cfg_data);
|
||||
-
|
||||
- if (len != 4) {
|
||||
- value >>= ((offset & 0x3) << 3);
|
||||
- value &= 0xffffffff >> (32 - (len << 3));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- *val = value;
|
||||
-
|
||||
- out_be32(hose->cfg_addr, 0);
|
||||
- mb();
|
||||
-
|
||||
- return PCIBIOS_SUCCESSFUL;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
- int offset, int len, u32 val)
|
||||
-{
|
||||
- struct pci_controller *hose = bus->sysdata;
|
||||
- u32 value, mask;
|
||||
-
|
||||
- if (ppc_md.pci_exclude_device)
|
||||
- if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
- return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
-
|
||||
- out_be32(hose->cfg_addr,
|
||||
- (1 << 31) |
|
||||
- ((bus->number - hose->bus_offset) << 16) |
|
||||
- (devfn << 8) |
|
||||
- (offset & 0xfc));
|
||||
- mb();
|
||||
-
|
||||
-#ifdef MPC5200_BUG_435_WORKAROUND
|
||||
- if (bus->number != hose->bus_offset) {
|
||||
- switch (len) {
|
||||
- case 1:
|
||||
- out_8(((u8 __iomem *)hose->cfg_data) +
|
||||
- (offset & 3), val);
|
||||
- break;
|
||||
- case 2:
|
||||
- out_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
- ((offset>>1) & 1), val);
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- out_le16((u16 __iomem *)hose->cfg_data,
|
||||
- (u16)val);
|
||||
- out_le16(((u16 __iomem *)hose->cfg_data) + 1,
|
||||
- (u16)(val>>16));
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- if (len != 4) {
|
||||
- value = in_le32(hose->cfg_data);
|
||||
-
|
||||
- offset = (offset & 0x3) << 3;
|
||||
- mask = (0xffffffff >> (32 - (len << 3)));
|
||||
- mask <<= offset;
|
||||
-
|
||||
- value &= ~mask;
|
||||
- val = value | ((val << offset) & mask);
|
||||
- }
|
||||
-
|
||||
- out_le32(hose->cfg_data, val);
|
||||
- }
|
||||
- mb();
|
||||
-
|
||||
- out_be32(hose->cfg_addr, 0);
|
||||
- mb();
|
||||
-
|
||||
- return PCIBIOS_SUCCESSFUL;
|
||||
-}
|
||||
-
|
||||
-static struct pci_ops mpc52xx_pci_ops = {
|
||||
- .read = mpc52xx_pci_read_config,
|
||||
- .write = mpc52xx_pci_write_config
|
||||
-};
|
||||
-
|
||||
-
|
||||
-static void __init
|
||||
-mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
- struct mpc52xx_pci __iomem *pci_regs)
|
||||
-{
|
||||
- struct resource *res;
|
||||
- u32 tmp;
|
||||
- int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
|
||||
-
|
||||
- pr_debug("mpc52xx_pci_setup()\n");
|
||||
-
|
||||
- pr_debug("iw0btar=%x iw1btar=%x iw2btar=%x iwcr=%x\n",
|
||||
- in_be32(&pci_regs->iw0btar), in_be32(&pci_regs->iw1btar),
|
||||
- in_be32(&pci_regs->iw2btar), in_be32(&pci_regs->iwcr));
|
||||
- pr_debug("tbatr0=%x tbatr1=%x tcr=%x gscr=%x\n",
|
||||
- in_be32(&pci_regs->tbatr0), in_be32(&pci_regs->tbatr1),
|
||||
- in_be32(&pci_regs->tcr), in_be32(&pci_regs->gscr));
|
||||
-
|
||||
- /* Setup control regs */
|
||||
- tmp = in_be32(&pci_regs->scr);
|
||||
- tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
- out_be32(&pci_regs->scr, tmp);
|
||||
-
|
||||
- /* Setup windows */
|
||||
- res = &hose->mem_resources[0];
|
||||
- if (res->flags) {
|
||||
- pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
- res->start, res->end, res->flags);
|
||||
- out_be32(&pci_regs->iw0btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
- if (res->flags & IORESOURCE_PREFETCH)
|
||||
- iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
- else
|
||||
- iwcr0 |= MPC52xx_PCI_IWCR_READ;
|
||||
- }
|
||||
-
|
||||
- res = &hose->mem_resources[1];
|
||||
- if (res->flags) {
|
||||
- pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
- res->start, res->end, res->flags);
|
||||
- out_be32(&pci_regs->iw1btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
- if (res->flags & IORESOURCE_PREFETCH)
|
||||
- iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
- else
|
||||
- iwcr1 |= MPC52xx_PCI_IWCR_READ;
|
||||
- }
|
||||
-
|
||||
- res = &hose->io_resource;
|
||||
- if (!res) {
|
||||
- printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
|
||||
- return;
|
||||
- }
|
||||
- pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
- ".io_base_phys=%lx\n",
|
||||
- res->start, res->end, res->flags, hose->io_base_phys);
|
||||
- out_be32(&pci_regs->iw2btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
- res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
|
||||
-
|
||||
- pr_debug("iwcr0=%x iwcr1=%x iwcr2=%x iwcr=%x old_iwcr=%x\n",
|
||||
- iwcr0, iwcr1, iwcr2,
|
||||
- MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2),
|
||||
- in_be32(&pci_regs->iwcr));
|
||||
- out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
|
||||
-
|
||||
- out_be32(&pci_regs->tbatr0,
|
||||
- MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
|
||||
- out_be32(&pci_regs->tbatr1,
|
||||
- MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
|
||||
-
|
||||
- out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
|
||||
-
|
||||
- /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
|
||||
- /* Not necessary and can be a bad thing if for example the bootloader
|
||||
- is displaying a splash screen or ... Just left here for
|
||||
- documentation purpose if anyone need it */
|
||||
- tmp = in_be32(&pci_regs->gscr);
|
||||
-#if 0
|
||||
- out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
|
||||
- udelay(50);
|
||||
-#endif
|
||||
- out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
|
||||
-
|
||||
- pr_debug("iw0btar=%x iw1btar=%x iw2btar=%x iwcr=%x\n",
|
||||
- in_be32(&pci_regs->iw0btar), in_be32(&pci_regs->iw1btar),
|
||||
- in_be32(&pci_regs->iw2btar), in_be32(&pci_regs->iwcr));
|
||||
- pr_debug("tbatr0=%x tbatr1=%x tcr=%x gscr=%x\n",
|
||||
- in_be32(&pci_regs->tbatr0), in_be32(&pci_regs->tbatr1),
|
||||
- in_be32(&pci_regs->tcr), in_be32(&pci_regs->gscr));
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mpc52xx_pci_fixup_resources(struct pci_dev *dev)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
|
||||
- dev->vendor, dev->device);
|
||||
-
|
||||
- /* We don't rely on boot loader for PCI and resets all
|
||||
- devices */
|
||||
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
- struct resource *res = &dev->resource[i];
|
||||
- if (res->end > res->start) { /* Only valid resources */
|
||||
- res->end -= res->start;
|
||||
- res->start = 0;
|
||||
- res->flags |= IORESOURCE_UNSET;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* The PCI Host bridge of MPC52xx has a prefetch memory resource
|
||||
- fixed to 1Gb. Doesn't fit in the resource system so we remove it */
|
||||
- if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
|
||||
- ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
|
||||
- || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
|
||||
- struct resource *res = &dev->resource[1];
|
||||
- res->start = res->end = res->flags = 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-int __init
|
||||
-mpc52xx_add_bridge(struct device_node *node)
|
||||
-{
|
||||
- int len;
|
||||
- struct mpc52xx_pci __iomem *pci_regs;
|
||||
- struct pci_controller *hose;
|
||||
- const int *bus_range;
|
||||
- struct resource rsrc;
|
||||
-
|
||||
- pr_debug("Adding PCI host bridge %s\n", node->full_name);
|
||||
-
|
||||
- pci_assign_all_buses = 1;
|
||||
-
|
||||
- if (of_address_to_resource(node, 0, &rsrc) != 0) {
|
||||
- printk(KERN_ERR "Can't get %s resources\n", node->full_name);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- bus_range = get_property(node, "bus-range", &len);
|
||||
- if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
- printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||
- " bus 0\n", node->full_name);
|
||||
- }
|
||||
-
|
||||
- hose = pcibios_alloc_controller();
|
||||
- if (!hose)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
|
||||
-
|
||||
- hose->arch_data = node;
|
||||
- hose->set_cfg_type = 1;
|
||||
-
|
||||
- hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
-
|
||||
- hose->bus_offset = 0;
|
||||
- hose->ops = &mpc52xx_pci_ops;
|
||||
-
|
||||
- pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
|
||||
- if (!pci_regs)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- pci_process_bridge_OF_ranges(hose, node, 0);
|
||||
-
|
||||
- hose->cfg_addr = &pci_regs->car;
|
||||
-
|
||||
- hose->cfg_data = hose->io_base_virt;
|
||||
- hose->io_base_virt = ioremap(hose->io_base_phys,
|
||||
- hose->io_resource.end + 1 -
|
||||
- hose->io_resource.start);
|
||||
- isa_io_base = (unsigned long) hose->io_base_virt;
|
||||
-
|
||||
- mpc52xx_pci_setup(hose, pci_regs);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.h b/arch/powerpc/platforms/52xx/mpc52xx_pci.h
|
||||
deleted file mode 100644
|
||||
index 07a659e..0000000
|
||||
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.h
|
||||
+++ /dev/null
|
||||
@@ -1,104 +0,0 @@
|
||||
-/*
|
||||
- * PCI Include file the Freescale MPC52xx embedded cpu chips
|
||||
- *
|
||||
- * Inspired from code written by Dale Farnsworth <dfarnsworth@mvista.com>
|
||||
- * for the 2.4 kernel.
|
||||
- *
|
||||
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
- * Copyright (C) 2003 MontaVista, Software, Inc.
|
||||
- *
|
||||
- * This file is licensed under the terms of the GNU General Public License
|
||||
- * version 2. This program is licensed "as is" without any warranty of any
|
||||
- * kind, whether express or implied.
|
||||
- */
|
||||
-
|
||||
-#ifndef __SYSLIB_MPC52xx_PCI_H__
|
||||
-#define __SYSLIB_MPC52xx_PCI_H__
|
||||
-
|
||||
-/* ======================================================================== */
|
||||
-/* PCI windows config */
|
||||
-/* ======================================================================== */
|
||||
-
|
||||
-#define MPC52xx_PCI_TARGET_IO 0xf0000000
|
||||
-#define MPC52xx_PCI_TARGET_MEM 0x00000000
|
||||
-
|
||||
-
|
||||
-/* ======================================================================== */
|
||||
-/* Structures mapping & Defines for PCI Unit */
|
||||
-/* ======================================================================== */
|
||||
-
|
||||
-#define MPC52xx_PCI_GSCR_BM 0x40000000
|
||||
-#define MPC52xx_PCI_GSCR_PE 0x20000000
|
||||
-#define MPC52xx_PCI_GSCR_SE 0x10000000
|
||||
-#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
|
||||
-#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
|
||||
-#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
|
||||
-#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
|
||||
-#define MPC52xx_PCI_GSCR_BME 0x00004000
|
||||
-#define MPC52xx_PCI_GSCR_PEE 0x00002000
|
||||
-#define MPC52xx_PCI_GSCR_SEE 0x00001000
|
||||
-#define MPC52xx_PCI_GSCR_PR 0x00000001
|
||||
-
|
||||
-
|
||||
-#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
|
||||
- ( ( (proc_ad) & 0xff000000 ) | \
|
||||
- ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
|
||||
- ( ((pci_ad) >> 16) & 0x0000ff00 ) )
|
||||
-
|
||||
-#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
|
||||
- ((win1) << 16) | \
|
||||
- ((win2) << 8))
|
||||
-
|
||||
-#define MPC52xx_PCI_IWCR_DISABLE 0x0
|
||||
-#define MPC52xx_PCI_IWCR_ENABLE 0x1
|
||||
-#define MPC52xx_PCI_IWCR_READ 0x0
|
||||
-#define MPC52xx_PCI_IWCR_READ_LINE 0x2
|
||||
-#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
|
||||
-#define MPC52xx_PCI_IWCR_MEM 0x0
|
||||
-#define MPC52xx_PCI_IWCR_IO 0x8
|
||||
-
|
||||
-#define MPC52xx_PCI_TCR_P 0x01000000
|
||||
-#define MPC52xx_PCI_TCR_LD 0x00010000
|
||||
-
|
||||
-#define MPC52xx_PCI_TBATR_DISABLE 0x0
|
||||
-#define MPC52xx_PCI_TBATR_ENABLE 0x1
|
||||
-
|
||||
-
|
||||
-#ifndef __ASSEMBLY__
|
||||
-
|
||||
-struct mpc52xx_pci {
|
||||
- u32 idr; /* PCI + 0x00 */
|
||||
- u32 scr; /* PCI + 0x04 */
|
||||
- u32 ccrir; /* PCI + 0x08 */
|
||||
- u32 cr1; /* PCI + 0x0C */
|
||||
- u32 bar0; /* PCI + 0x10 */
|
||||
- u32 bar1; /* PCI + 0x14 */
|
||||
- u8 reserved1[16]; /* PCI + 0x18 */
|
||||
- u32 ccpr; /* PCI + 0x28 */
|
||||
- u32 sid; /* PCI + 0x2C */
|
||||
- u32 erbar; /* PCI + 0x30 */
|
||||
- u32 cpr; /* PCI + 0x34 */
|
||||
- u8 reserved2[4]; /* PCI + 0x38 */
|
||||
- u32 cr2; /* PCI + 0x3C */
|
||||
- u8 reserved3[32]; /* PCI + 0x40 */
|
||||
- u32 gscr; /* PCI + 0x60 */
|
||||
- u32 tbatr0; /* PCI + 0x64 */
|
||||
- u32 tbatr1; /* PCI + 0x68 */
|
||||
- u32 tcr; /* PCI + 0x6C */
|
||||
- u32 iw0btar; /* PCI + 0x70 */
|
||||
- u32 iw1btar; /* PCI + 0x74 */
|
||||
- u32 iw2btar; /* PCI + 0x78 */
|
||||
- u8 reserved4[4]; /* PCI + 0x7C */
|
||||
- u32 iwcr; /* PCI + 0x80 */
|
||||
- u32 icr; /* PCI + 0x84 */
|
||||
- u32 isr; /* PCI + 0x88 */
|
||||
- u32 arb; /* PCI + 0x8C */
|
||||
- u8 reserved5[104]; /* PCI + 0x90 */
|
||||
- u32 car; /* PCI + 0xF8 */
|
||||
- u8 reserved6[4]; /* PCI + 0xFC */
|
||||
-};
|
||||
-
|
||||
-#endif /* __ASSEMBLY__ */
|
||||
-
|
||||
-
|
||||
-#endif /* __SYSLIB_MPC52xx_PCI_H__ */
|
||||
diff --git a/arch/powerpc/platforms/52xx/pci.c b/arch/powerpc/platforms/52xx/pci.c
|
||||
new file mode 100644
|
||||
index 0000000..14940af
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/platforms/52xx/pci.c
|
||||
@@ -0,0 +1,404 @@
|
||||
+/*
|
||||
+ * PCI code for the Freescale MPC52xx embedded CPU.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Secret Lab Technologies Ltd.
|
||||
+ * Grant Likely <grant.likely@secretlab.ca>
|
||||
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#undef DEBUG
|
||||
+
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+#include <asm/delay.h>
|
||||
+#include <asm/machdep.h>
|
||||
+#include <linux/kernel.h>
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCI windows config */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_TARGET_IO 0xf0000000
|
||||
+#define MPC52xx_PCI_TARGET_MEM 0x00000000
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Structures mapping & Defines for PCI Unit */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_GSCR_BM 0x40000000
|
||||
+#define MPC52xx_PCI_GSCR_PE 0x20000000
|
||||
+#define MPC52xx_PCI_GSCR_SE 0x10000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
|
||||
+#define MPC52xx_PCI_GSCR_BME 0x00004000
|
||||
+#define MPC52xx_PCI_GSCR_PEE 0x00002000
|
||||
+#define MPC52xx_PCI_GSCR_SEE 0x00001000
|
||||
+#define MPC52xx_PCI_GSCR_PR 0x00000001
|
||||
+
|
||||
+
|
||||
+#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
|
||||
+ ( ( (proc_ad) & 0xff000000 ) | \
|
||||
+ ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
|
||||
+ ( ((pci_ad) >> 16) & 0x0000ff00 ) )
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
|
||||
+ ((win1) << 16) | \
|
||||
+ ((win2) << 8))
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_IWCR_ENABLE 0x1
|
||||
+#define MPC52xx_PCI_IWCR_READ 0x0
|
||||
+#define MPC52xx_PCI_IWCR_READ_LINE 0x2
|
||||
+#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
|
||||
+#define MPC52xx_PCI_IWCR_MEM 0x0
|
||||
+#define MPC52xx_PCI_IWCR_IO 0x8
|
||||
+
|
||||
+#define MPC52xx_PCI_TCR_P 0x01000000
|
||||
+#define MPC52xx_PCI_TCR_LD 0x00010000
|
||||
+
|
||||
+#define MPC52xx_PCI_TBATR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_TBATR_ENABLE 0x1
|
||||
+
|
||||
+struct mpc52xx_pci {
|
||||
+ u32 idr; /* PCI + 0x00 */
|
||||
+ u32 scr; /* PCI + 0x04 */
|
||||
+ u32 ccrir; /* PCI + 0x08 */
|
||||
+ u32 cr1; /* PCI + 0x0C */
|
||||
+ u32 bar0; /* PCI + 0x10 */
|
||||
+ u32 bar1; /* PCI + 0x14 */
|
||||
+ u8 reserved1[16]; /* PCI + 0x18 */
|
||||
+ u32 ccpr; /* PCI + 0x28 */
|
||||
+ u32 sid; /* PCI + 0x2C */
|
||||
+ u32 erbar; /* PCI + 0x30 */
|
||||
+ u32 cpr; /* PCI + 0x34 */
|
||||
+ u8 reserved2[4]; /* PCI + 0x38 */
|
||||
+ u32 cr2; /* PCI + 0x3C */
|
||||
+ u8 reserved3[32]; /* PCI + 0x40 */
|
||||
+ u32 gscr; /* PCI + 0x60 */
|
||||
+ u32 tbatr0; /* PCI + 0x64 */
|
||||
+ u32 tbatr1; /* PCI + 0x68 */
|
||||
+ u32 tcr; /* PCI + 0x6C */
|
||||
+ u32 iw0btar; /* PCI + 0x70 */
|
||||
+ u32 iw1btar; /* PCI + 0x74 */
|
||||
+ u32 iw2btar; /* PCI + 0x78 */
|
||||
+ u8 reserved4[4]; /* PCI + 0x7C */
|
||||
+ u32 iwcr; /* PCI + 0x80 */
|
||||
+ u32 icr; /* PCI + 0x84 */
|
||||
+ u32 isr; /* PCI + 0x88 */
|
||||
+ u32 arb; /* PCI + 0x8C */
|
||||
+ u8 reserved5[104]; /* PCI + 0x90 */
|
||||
+ u32 car; /* PCI + 0xF8 */
|
||||
+ u8 reserved6[4]; /* PCI + 0xFC */
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 *val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
+ * Don't do 32 bits config access during type-1 cycles */
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ value = in_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3));
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ value = in_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1));
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ value = in_le16((u16 __iomem *)hose->cfg_data) |
|
||||
+ (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ if (len != 4) {
|
||||
+ value >>= ((offset & 0x3) << 3);
|
||||
+ value &= 0xffffffff >> (32 - (len << 3));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *val = value;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value, mask;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
+ * Don't do 32 bits config access during type-1 cycles */
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ out_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3), val);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1), val);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ out_le16((u16 __iomem *)hose->cfg_data,
|
||||
+ (u16)val);
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) + 1,
|
||||
+ (u16)(val>>16));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ if (len != 4) {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ offset = (offset & 0x3) << 3;
|
||||
+ mask = (0xffffffff >> (32 - (len << 3)));
|
||||
+ mask <<= offset;
|
||||
+
|
||||
+ value &= ~mask;
|
||||
+ val = value | ((val << offset) & mask);
|
||||
+ }
|
||||
+
|
||||
+ out_le32(hose->cfg_data, val);
|
||||
+ }
|
||||
+ mb();
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops mpc52xx_pci_ops = {
|
||||
+ .read = mpc52xx_pci_read_config,
|
||||
+ .write = mpc52xx_pci_write_config
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static void __init
|
||||
+mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
+ struct mpc52xx_pci __iomem *pci_regs)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ u32 tmp;
|
||||
+ int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs);
|
||||
+
|
||||
+ /* pci_process_bridge_OF_ranges() found all our addresses for us;
|
||||
+ * now store them in the right places */
|
||||
+ hose->cfg_addr = &pci_regs->car;
|
||||
+ hose->cfg_data = hose->io_base_virt;
|
||||
+ hose->io_base_virt = ioremap(hose->io_base_phys,
|
||||
+ hose->io_resource.end + 1 -
|
||||
+ hose->io_resource.start);
|
||||
+ isa_io_base = (unsigned long) hose->io_base_virt;
|
||||
+
|
||||
+ /* Control regs */
|
||||
+ tmp = in_be32(&pci_regs->scr);
|
||||
+ tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
+ out_be32(&pci_regs->scr, tmp);
|
||||
+
|
||||
+ /* Memory windows */
|
||||
+ res = &hose->mem_resources[0];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw0btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ res = &hose->mem_resources[1];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw1btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ /* IO resources */
|
||||
+ res = &hose->io_resource;
|
||||
+ if (!res) {
|
||||
+ printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
|
||||
+ return;
|
||||
+ }
|
||||
+ pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
+ ".io_base_phys=%lx\n",
|
||||
+ res->start, res->end, res->flags, hose->io_base_phys);
|
||||
+ out_be32(&pci_regs->iw2btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
+ res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
|
||||
+
|
||||
+ /* Set all the IWCR fields at once; they're in the same reg */
|
||||
+ out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
|
||||
+
|
||||
+ out_be32(&pci_regs->tbatr0,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
|
||||
+ out_be32(&pci_regs->tbatr1,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
|
||||
+
|
||||
+ out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
|
||||
+
|
||||
+#if 0
|
||||
+ /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
|
||||
+ /* Not necessary and can be a bad thing if for example the bootloader
|
||||
+ is displaying a splash screen or ... Just left here for
|
||||
+ documentation purpose if anyone need it */
|
||||
+ tmp = in_be32(&pci_regs->gscr);
|
||||
+ out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
|
||||
+ udelay(50);
|
||||
+ out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mpc52xx_pci_fixup_resources(struct pci_dev *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
|
||||
+ dev->vendor, dev->device);
|
||||
+
|
||||
+ /* We don't rely on boot loader for PCI and resets all
|
||||
+ devices */
|
||||
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
+ struct resource *res = &dev->resource[i];
|
||||
+ if (res->end > res->start) { /* Only valid resources */
|
||||
+ res->end -= res->start;
|
||||
+ res->start = 0;
|
||||
+ res->flags |= IORESOURCE_UNSET;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* The PCI Host bridge of MPC52xx has a prefetch memory resource
|
||||
+ fixed to 1Gb. Doesn't fit in the resource system so we remove it */
|
||||
+ if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
|
||||
+ ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
|
||||
+ || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
|
||||
+ struct resource *res = &dev->resource[1];
|
||||
+ res->start = res->end = res->flags = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int __init
|
||||
+mpc52xx_add_bridge(struct device_node *node)
|
||||
+{
|
||||
+ int len;
|
||||
+ struct mpc52xx_pci __iomem *pci_regs;
|
||||
+ struct pci_controller *hose;
|
||||
+ const int *bus_range;
|
||||
+ struct resource rsrc;
|
||||
+
|
||||
+ pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
|
||||
+
|
||||
+ pci_assign_all_buses = 1;
|
||||
+
|
||||
+ if (of_address_to_resource(node, 0, &rsrc) != 0) {
|
||||
+ printk(KERN_ERR "Can't get %s resources\n", node->full_name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ bus_range = get_property(node, "bus-range", &len);
|
||||
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
+ printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n",
|
||||
+ node->full_name);
|
||||
+ bus_range = NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* There are some PCI quirks on the 52xx, register the hook to
|
||||
+ * fix them. */
|
||||
+ ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
|
||||
+
|
||||
+ /* Alloc and initialize the pci controller. Values in the device
|
||||
+ * tree are needed to configure the 52xx PCI controller. Rather
|
||||
+ * than parse the tree here, let pci_process_bridge_OF_ranges()
|
||||
+ * do it for us and extract the values after the fact */
|
||||
+ hose = pcibios_alloc_controller();
|
||||
+ if (!hose)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hose->arch_data = node;
|
||||
+ hose->set_cfg_type = 1;
|
||||
+
|
||||
+ hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
+
|
||||
+ hose->bus_offset = 0;
|
||||
+ hose->ops = &mpc52xx_pci_ops;
|
||||
+
|
||||
+ pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
|
||||
+ if (!pci_regs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pci_process_bridge_OF_ranges(hose, node, 0);
|
||||
+
|
||||
+ /* Finish setting up PCI using values obtained by
|
||||
+ * pci_proces_bridge_OF_ranges */
|
||||
+ mpc52xx_pci_setup(hose, pci_regs);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
From 5145742e15b45e96c623f571dee421306dc95a3e Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 11 Dec 2006 22:45:39 -0700
|
||||
Subject: [PATCH] [POWERPC] Change name of mpc52xx pci support file in Makefile
|
||||
|
||||
Oops, missed a bit in the previous patch
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/Makefile | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
|
||||
index d85ea04..a7c646a 100644
|
||||
--- a/arch/powerpc/platforms/52xx/Makefile
|
||||
+++ b/arch/powerpc/platforms/52xx/Makefile
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
obj-y += mpc52xx_pic.o mpc52xx_common.o
|
||||
-obj-$(CONFIG_PCI) += mpc52xx_pci.o
|
||||
+obj-$(CONFIG_PCI) += pci.o
|
||||
obj-$(CONFIG_PPC_BESTCOMM) += bestcomm.o
|
||||
obj-$(CONFIG_FEC_MPC52xx) += sdma_fec_rx_task.o sdma_fec_tx_task.o fec.o
|
||||
endif
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
From 2086d309f8b8de0b41119596d43f2a7bfe028a89 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 11 Dec 2006 22:46:59 -0700
|
||||
Subject: [PATCH] [POWERPC] Change link order so mpc52xx-fec always shows up as eth0
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
drivers/net/Makefile | 2 +-
|
||||
drivers/net/fec_mpc52xx/fec.c | 2 ++
|
||||
2 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
|
||||
index e6f903d..95f0963 100644
|
||||
--- a/drivers/net/Makefile
|
||||
+++ b/drivers/net/Makefile
|
||||
@@ -24,6 +24,7 @@ ucc_geth_driver-objs := ucc_geth.o ucc_geth_phy.o
|
||||
obj-$(CONFIG_PLIP) += plip.o
|
||||
|
||||
obj-$(CONFIG_ROADRUNNER) += rrunner.o
|
||||
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx/
|
||||
|
||||
obj-$(CONFIG_HAPPYMEAL) += sunhme.o
|
||||
obj-$(CONFIG_SUNLANCE) += sunlance.o
|
||||
@@ -196,7 +197,6 @@ obj-$(CONFIG_SMC91X) += smc91x.o
|
||||
obj-$(CONFIG_SMC911X) += smc911x.o
|
||||
obj-$(CONFIG_DM9000) += dm9000.o
|
||||
obj-$(CONFIG_FEC_8XX) += fec_8xx/
|
||||
-obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx/
|
||||
|
||||
obj-$(CONFIG_MACB) += macb.o
|
||||
|
||||
diff --git a/drivers/net/fec_mpc52xx/fec.c b/drivers/net/fec_mpc52xx/fec.c
|
||||
index 894da79..30cef2b 100644
|
||||
--- a/drivers/net/fec_mpc52xx/fec.c
|
||||
+++ b/drivers/net/fec_mpc52xx/fec.c
|
||||
@@ -731,6 +731,8 @@ mpc52xx_fec_probe(struct device *dev)
|
||||
fec_mii_init(ndev);
|
||||
|
||||
/* We're done ! */
|
||||
+ printk(KERN_INFO "%s: mpc52xx-fec at %#lx,",
|
||||
+ ndev->name, (long)mem->start);
|
||||
#if defined(CONFIG_PPC_MERGE)
|
||||
dev_set_drvdata(&op->dev, ndev);
|
||||
#else
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
From 08bb999d4f8b866a570775db5788cd84edafd3f5 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 11 Dec 2006 23:00:24 -0700
|
||||
Subject: [PATCH] [POWERPC] Fixup pr_print format for mpc52xx pci support
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/pci.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/pci.c b/arch/powerpc/platforms/52xx/pci.c
|
||||
index 14940af..b732fdc 100644
|
||||
--- a/arch/powerpc/platforms/52xx/pci.c
|
||||
+++ b/arch/powerpc/platforms/52xx/pci.c
|
||||
@@ -285,8 +285,8 @@ mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
return;
|
||||
}
|
||||
pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
- ".io_base_phys=%lx\n",
|
||||
- res->start, res->end, res->flags, hose->io_base_phys);
|
||||
+ ".io_base_phys=0x%p\n",
|
||||
+ res->start, res->end, res->flags, (void*)hose->io_base_phys);
|
||||
out_be32(&pci_regs->iw2btar,
|
||||
MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
res->start,
|
||||
--
|
||||
1.4.4.2
|
||||
|
871
debian/patches/features/powerpc/efika/0030-POWERPC-Add-mpc52xx-lite5200-PCI-support.txt
vendored
Normal file
871
debian/patches/features/powerpc/efika/0030-POWERPC-Add-mpc52xx-lite5200-PCI-support.txt
vendored
Normal file
|
@ -0,0 +1,871 @@
|
|||
From 56aad819c662c854466a8c454c948e79dd2f0777 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@secretlab.ca>
|
||||
Date: Mon, 11 Dec 2006 23:23:40 -0700
|
||||
Subject: [PATCH] [POWERPC] Add mpc52xx/lite5200 PCI support
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
|
||||
---
|
||||
arch/powerpc/platforms/52xx/Makefile | 2 +-
|
||||
arch/powerpc/platforms/52xx/lite5200.c | 3 -
|
||||
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 412 +++++++++++++++++++++++++++++
|
||||
arch/powerpc/platforms/52xx/pci.c | 404 ----------------------------
|
||||
4 files changed, 413 insertions(+), 408 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
|
||||
index a7c646a..d85ea04 100644
|
||||
--- a/arch/powerpc/platforms/52xx/Makefile
|
||||
+++ b/arch/powerpc/platforms/52xx/Makefile
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
obj-y += mpc52xx_pic.o mpc52xx_common.o
|
||||
-obj-$(CONFIG_PCI) += pci.o
|
||||
+obj-$(CONFIG_PCI) += mpc52xx_pci.o
|
||||
obj-$(CONFIG_PPC_BESTCOMM) += bestcomm.o
|
||||
obj-$(CONFIG_FEC_MPC52xx) += sdma_fec_rx_task.o sdma_fec_tx_task.o fec.o
|
||||
endif
|
||||
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
index f1bbe24..cdb16bf 100644
|
||||
--- a/arch/powerpc/platforms/52xx/lite5200.c
|
||||
+++ b/arch/powerpc/platforms/52xx/lite5200.c
|
||||
@@ -111,9 +111,6 @@ static void __init lite52xx_setup_arch(void)
|
||||
np = of_find_node_by_type(np, "pci");
|
||||
if (np)
|
||||
mpc52xx_add_bridge(np);
|
||||
-
|
||||
- //ppc_md.pci_swizzle = common_swizzle;
|
||||
- //ppc_md.pci_exclude_device = mpc52xx_exclude_device;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
new file mode 100644
|
||||
index 0000000..faf161b
|
||||
--- /dev/null
|
||||
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
|
||||
@@ -0,0 +1,412 @@
|
||||
+/*
|
||||
+ * PCI code for the Freescale MPC52xx embedded CPU.
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Secret Lab Technologies Ltd.
|
||||
+ * Grant Likely <grant.likely@secretlab.ca>
|
||||
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#undef DEBUG
|
||||
+
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/mpc52xx.h>
|
||||
+#include <asm/delay.h>
|
||||
+#include <asm/machdep.h>
|
||||
+#include <linux/kernel.h>
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCI windows config */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_TARGET_IO 0xf0000000
|
||||
+#define MPC52xx_PCI_TARGET_MEM 0x00000000
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Structures mapping & Defines for PCI Unit */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+#define MPC52xx_PCI_GSCR_BM 0x40000000
|
||||
+#define MPC52xx_PCI_GSCR_PE 0x20000000
|
||||
+#define MPC52xx_PCI_GSCR_SE 0x10000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
|
||||
+#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
|
||||
+#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
|
||||
+#define MPC52xx_PCI_GSCR_BME 0x00004000
|
||||
+#define MPC52xx_PCI_GSCR_PEE 0x00002000
|
||||
+#define MPC52xx_PCI_GSCR_SEE 0x00001000
|
||||
+#define MPC52xx_PCI_GSCR_PR 0x00000001
|
||||
+
|
||||
+
|
||||
+#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
|
||||
+ ( ( (proc_ad) & 0xff000000 ) | \
|
||||
+ ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
|
||||
+ ( ((pci_ad) >> 16) & 0x0000ff00 ) )
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
|
||||
+ ((win1) << 16) | \
|
||||
+ ((win2) << 8))
|
||||
+
|
||||
+#define MPC52xx_PCI_IWCR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_IWCR_ENABLE 0x1
|
||||
+#define MPC52xx_PCI_IWCR_READ 0x0
|
||||
+#define MPC52xx_PCI_IWCR_READ_LINE 0x2
|
||||
+#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
|
||||
+#define MPC52xx_PCI_IWCR_MEM 0x0
|
||||
+#define MPC52xx_PCI_IWCR_IO 0x8
|
||||
+
|
||||
+#define MPC52xx_PCI_TCR_P 0x01000000
|
||||
+#define MPC52xx_PCI_TCR_LD 0x00010000
|
||||
+
|
||||
+#define MPC52xx_PCI_TBATR_DISABLE 0x0
|
||||
+#define MPC52xx_PCI_TBATR_ENABLE 0x1
|
||||
+
|
||||
+struct mpc52xx_pci {
|
||||
+ u32 idr; /* PCI + 0x00 */
|
||||
+ u32 scr; /* PCI + 0x04 */
|
||||
+ u32 ccrir; /* PCI + 0x08 */
|
||||
+ u32 cr1; /* PCI + 0x0C */
|
||||
+ u32 bar0; /* PCI + 0x10 */
|
||||
+ u32 bar1; /* PCI + 0x14 */
|
||||
+ u8 reserved1[16]; /* PCI + 0x18 */
|
||||
+ u32 ccpr; /* PCI + 0x28 */
|
||||
+ u32 sid; /* PCI + 0x2C */
|
||||
+ u32 erbar; /* PCI + 0x30 */
|
||||
+ u32 cpr; /* PCI + 0x34 */
|
||||
+ u8 reserved2[4]; /* PCI + 0x38 */
|
||||
+ u32 cr2; /* PCI + 0x3C */
|
||||
+ u8 reserved3[32]; /* PCI + 0x40 */
|
||||
+ u32 gscr; /* PCI + 0x60 */
|
||||
+ u32 tbatr0; /* PCI + 0x64 */
|
||||
+ u32 tbatr1; /* PCI + 0x68 */
|
||||
+ u32 tcr; /* PCI + 0x6C */
|
||||
+ u32 iw0btar; /* PCI + 0x70 */
|
||||
+ u32 iw1btar; /* PCI + 0x74 */
|
||||
+ u32 iw2btar; /* PCI + 0x78 */
|
||||
+ u8 reserved4[4]; /* PCI + 0x7C */
|
||||
+ u32 iwcr; /* PCI + 0x80 */
|
||||
+ u32 icr; /* PCI + 0x84 */
|
||||
+ u32 isr; /* PCI + 0x88 */
|
||||
+ u32 arb; /* PCI + 0x8C */
|
||||
+ u8 reserved5[104]; /* PCI + 0x90 */
|
||||
+ u32 car; /* PCI + 0xF8 */
|
||||
+ u8 reserved6[4]; /* PCI + 0xFC */
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCI configuration acess */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 *val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
+ * Don't do 32 bits config access during type-1 cycles */
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ value = in_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3));
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ value = in_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1));
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ value = in_le16((u16 __iomem *)hose->cfg_data) |
|
||||
+ (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ if (len != 4) {
|
||||
+ value >>= ((offset & 0x3) << 3);
|
||||
+ value &= 0xffffffff >> (32 - (len << 3));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *val = value;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset, int len, u32 val)
|
||||
+{
|
||||
+ struct pci_controller *hose = bus->sysdata;
|
||||
+ u32 value, mask;
|
||||
+
|
||||
+ if (ppc_md.pci_exclude_device)
|
||||
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ out_be32(hose->cfg_addr,
|
||||
+ (1 << 31) |
|
||||
+ ((bus->number - hose->bus_offset) << 16) |
|
||||
+ (devfn << 8) |
|
||||
+ (offset & 0xfc));
|
||||
+ mb();
|
||||
+
|
||||
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
+ if (bus->number != hose->bus_offset) {
|
||||
+ /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
+ * Don't do 32 bits config access during type-1 cycles */
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ out_8(((u8 __iomem *)hose->cfg_data) +
|
||||
+ (offset & 3), val);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
+ ((offset>>1) & 1), val);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ out_le16((u16 __iomem *)hose->cfg_data,
|
||||
+ (u16)val);
|
||||
+ out_le16(((u16 __iomem *)hose->cfg_data) + 1,
|
||||
+ (u16)(val>>16));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ if (len != 4) {
|
||||
+ value = in_le32(hose->cfg_data);
|
||||
+
|
||||
+ offset = (offset & 0x3) << 3;
|
||||
+ mask = (0xffffffff >> (32 - (len << 3)));
|
||||
+ mask <<= offset;
|
||||
+
|
||||
+ value &= ~mask;
|
||||
+ val = value | ((val << offset) & mask);
|
||||
+ }
|
||||
+
|
||||
+ out_le32(hose->cfg_data, val);
|
||||
+ }
|
||||
+ mb();
|
||||
+
|
||||
+ out_be32(hose->cfg_addr, 0);
|
||||
+ mb();
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops mpc52xx_pci_ops = {
|
||||
+ .read = mpc52xx_pci_read_config,
|
||||
+ .write = mpc52xx_pci_write_config
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCI setup */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static void __init
|
||||
+mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
+ struct mpc52xx_pci __iomem *pci_regs)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+ u32 tmp;
|
||||
+ int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs);
|
||||
+
|
||||
+ /* pci_process_bridge_OF_ranges() found all our addresses for us;
|
||||
+ * now store them in the right places */
|
||||
+ hose->cfg_addr = &pci_regs->car;
|
||||
+ hose->cfg_data = hose->io_base_virt;
|
||||
+
|
||||
+ /* Control regs */
|
||||
+ tmp = in_be32(&pci_regs->scr);
|
||||
+ tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
+ out_be32(&pci_regs->scr, tmp);
|
||||
+
|
||||
+ /* Memory windows */
|
||||
+ res = &hose->mem_resources[0];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw0btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr0 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ res = &hose->mem_resources[1];
|
||||
+ if (res->flags) {
|
||||
+ pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
+ res->start, res->end, res->flags);
|
||||
+ out_be32(&pci_regs->iw1btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
+ if (res->flags & IORESOURCE_PREFETCH)
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
+ else
|
||||
+ iwcr1 |= MPC52xx_PCI_IWCR_READ;
|
||||
+ }
|
||||
+
|
||||
+ /* IO resources */
|
||||
+ res = &hose->io_resource;
|
||||
+ if (!res) {
|
||||
+ printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
|
||||
+ return;
|
||||
+ }
|
||||
+ pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
+ ".io_base_phys=0x%p\n",
|
||||
+ res->start, res->end, res->flags, (void*)hose->io_base_phys);
|
||||
+ out_be32(&pci_regs->iw2btar,
|
||||
+ MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
+ res->start,
|
||||
+ res->end - res->start + 1));
|
||||
+ iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
|
||||
+
|
||||
+ /* Set all the IWCR fields at once; they're in the same reg */
|
||||
+ out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
|
||||
+
|
||||
+ out_be32(&pci_regs->tbatr0,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
|
||||
+ out_be32(&pci_regs->tbatr1,
|
||||
+ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
|
||||
+
|
||||
+ out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
|
||||
+
|
||||
+ tmp = in_be32(&pci_regs->gscr);
|
||||
+#if 0
|
||||
+ /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
|
||||
+ /* Not necessary and can be a bad thing if for example the bootloader
|
||||
+ is displaying a splash screen or ... Just left here for
|
||||
+ documentation purpose if anyone need it */
|
||||
+ out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
|
||||
+ udelay(50);
|
||||
+#endif
|
||||
+
|
||||
+ /* Make sure the PCI bridge is out of reset */
|
||||
+ out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mpc52xx_pci_fixup_resources(struct pci_dev *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
|
||||
+ dev->vendor, dev->device);
|
||||
+
|
||||
+ /* We don't rely on boot loader for PCI and resets all
|
||||
+ devices */
|
||||
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
+ struct resource *res = &dev->resource[i];
|
||||
+ if (res->end > res->start) { /* Only valid resources */
|
||||
+ res->end -= res->start;
|
||||
+ res->start = 0;
|
||||
+ res->flags |= IORESOURCE_UNSET;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* The PCI Host bridge of MPC52xx has a prefetch memory resource
|
||||
+ fixed to 1Gb. Doesn't fit in the resource system so we remove it */
|
||||
+ if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
|
||||
+ ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
|
||||
+ || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
|
||||
+ struct resource *res = &dev->resource[1];
|
||||
+ res->start = res->end = res->flags = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int __init
|
||||
+mpc52xx_add_bridge(struct device_node *node)
|
||||
+{
|
||||
+ int len;
|
||||
+ struct mpc52xx_pci __iomem *pci_regs;
|
||||
+ struct pci_controller *hose;
|
||||
+ const int *bus_range;
|
||||
+ struct resource rsrc;
|
||||
+
|
||||
+ pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
|
||||
+
|
||||
+ pci_assign_all_buses = 1;
|
||||
+
|
||||
+ if (of_address_to_resource(node, 0, &rsrc) != 0) {
|
||||
+ printk(KERN_ERR "Can't get %s resources\n", node->full_name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ bus_range = get_property(node, "bus-range", &len);
|
||||
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
+ printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n",
|
||||
+ node->full_name);
|
||||
+ bus_range = NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* There are some PCI quirks on the 52xx, register the hook to
|
||||
+ * fix them. */
|
||||
+ ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
|
||||
+
|
||||
+ /* Alloc and initialize the pci controller. Values in the device
|
||||
+ * tree are needed to configure the 52xx PCI controller. Rather
|
||||
+ * than parse the tree here, let pci_process_bridge_OF_ranges()
|
||||
+ * do it for us and extract the values after the fact */
|
||||
+ hose = pcibios_alloc_controller();
|
||||
+ if (!hose)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hose->arch_data = node;
|
||||
+ hose->set_cfg_type = 1;
|
||||
+
|
||||
+ hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
+
|
||||
+ hose->bus_offset = 0;
|
||||
+ hose->ops = &mpc52xx_pci_ops;
|
||||
+
|
||||
+ pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
|
||||
+ if (!pci_regs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pci_process_bridge_OF_ranges(hose, node, 1);
|
||||
+
|
||||
+ /* Finish setting up PCI using values obtained by
|
||||
+ * pci_proces_bridge_OF_ranges */
|
||||
+ mpc52xx_pci_setup(hose, pci_regs);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/arch/powerpc/platforms/52xx/pci.c b/arch/powerpc/platforms/52xx/pci.c
|
||||
deleted file mode 100644
|
||||
index b732fdc..0000000
|
||||
--- a/arch/powerpc/platforms/52xx/pci.c
|
||||
+++ /dev/null
|
||||
@@ -1,404 +0,0 @@
|
||||
-/*
|
||||
- * PCI code for the Freescale MPC52xx embedded CPU.
|
||||
- *
|
||||
- * Copyright (C) 2004 Secret Lab Technologies Ltd.
|
||||
- * Grant Likely <grant.likely@secretlab.ca>
|
||||
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
- *
|
||||
- * This file is licensed under the terms of the GNU General Public License
|
||||
- * version 2. This program is licensed "as is" without any warranty of any
|
||||
- * kind, whether express or implied.
|
||||
- */
|
||||
-
|
||||
-#undef DEBUG
|
||||
-
|
||||
-#include <asm/pci.h>
|
||||
-#include <asm/mpc52xx.h>
|
||||
-#include <asm/delay.h>
|
||||
-#include <asm/machdep.h>
|
||||
-#include <linux/kernel.h>
|
||||
-
|
||||
-
|
||||
-/* ======================================================================== */
|
||||
-/* PCI windows config */
|
||||
-/* ======================================================================== */
|
||||
-
|
||||
-#define MPC52xx_PCI_TARGET_IO 0xf0000000
|
||||
-#define MPC52xx_PCI_TARGET_MEM 0x00000000
|
||||
-
|
||||
-/* ======================================================================== */
|
||||
-/* Structures mapping & Defines for PCI Unit */
|
||||
-/* ======================================================================== */
|
||||
-
|
||||
-#define MPC52xx_PCI_GSCR_BM 0x40000000
|
||||
-#define MPC52xx_PCI_GSCR_PE 0x20000000
|
||||
-#define MPC52xx_PCI_GSCR_SE 0x10000000
|
||||
-#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
|
||||
-#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
|
||||
-#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
|
||||
-#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
|
||||
-#define MPC52xx_PCI_GSCR_BME 0x00004000
|
||||
-#define MPC52xx_PCI_GSCR_PEE 0x00002000
|
||||
-#define MPC52xx_PCI_GSCR_SEE 0x00001000
|
||||
-#define MPC52xx_PCI_GSCR_PR 0x00000001
|
||||
-
|
||||
-
|
||||
-#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
|
||||
- ( ( (proc_ad) & 0xff000000 ) | \
|
||||
- ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
|
||||
- ( ((pci_ad) >> 16) & 0x0000ff00 ) )
|
||||
-
|
||||
-#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
|
||||
- ((win1) << 16) | \
|
||||
- ((win2) << 8))
|
||||
-
|
||||
-#define MPC52xx_PCI_IWCR_DISABLE 0x0
|
||||
-#define MPC52xx_PCI_IWCR_ENABLE 0x1
|
||||
-#define MPC52xx_PCI_IWCR_READ 0x0
|
||||
-#define MPC52xx_PCI_IWCR_READ_LINE 0x2
|
||||
-#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
|
||||
-#define MPC52xx_PCI_IWCR_MEM 0x0
|
||||
-#define MPC52xx_PCI_IWCR_IO 0x8
|
||||
-
|
||||
-#define MPC52xx_PCI_TCR_P 0x01000000
|
||||
-#define MPC52xx_PCI_TCR_LD 0x00010000
|
||||
-
|
||||
-#define MPC52xx_PCI_TBATR_DISABLE 0x0
|
||||
-#define MPC52xx_PCI_TBATR_ENABLE 0x1
|
||||
-
|
||||
-struct mpc52xx_pci {
|
||||
- u32 idr; /* PCI + 0x00 */
|
||||
- u32 scr; /* PCI + 0x04 */
|
||||
- u32 ccrir; /* PCI + 0x08 */
|
||||
- u32 cr1; /* PCI + 0x0C */
|
||||
- u32 bar0; /* PCI + 0x10 */
|
||||
- u32 bar1; /* PCI + 0x14 */
|
||||
- u8 reserved1[16]; /* PCI + 0x18 */
|
||||
- u32 ccpr; /* PCI + 0x28 */
|
||||
- u32 sid; /* PCI + 0x2C */
|
||||
- u32 erbar; /* PCI + 0x30 */
|
||||
- u32 cpr; /* PCI + 0x34 */
|
||||
- u8 reserved2[4]; /* PCI + 0x38 */
|
||||
- u32 cr2; /* PCI + 0x3C */
|
||||
- u8 reserved3[32]; /* PCI + 0x40 */
|
||||
- u32 gscr; /* PCI + 0x60 */
|
||||
- u32 tbatr0; /* PCI + 0x64 */
|
||||
- u32 tbatr1; /* PCI + 0x68 */
|
||||
- u32 tcr; /* PCI + 0x6C */
|
||||
- u32 iw0btar; /* PCI + 0x70 */
|
||||
- u32 iw1btar; /* PCI + 0x74 */
|
||||
- u32 iw2btar; /* PCI + 0x78 */
|
||||
- u8 reserved4[4]; /* PCI + 0x7C */
|
||||
- u32 iwcr; /* PCI + 0x80 */
|
||||
- u32 icr; /* PCI + 0x84 */
|
||||
- u32 isr; /* PCI + 0x88 */
|
||||
- u32 arb; /* PCI + 0x8C */
|
||||
- u8 reserved5[104]; /* PCI + 0x90 */
|
||||
- u32 car; /* PCI + 0xF8 */
|
||||
- u8 reserved6[4]; /* PCI + 0xFC */
|
||||
-};
|
||||
-
|
||||
-static int
|
||||
-mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
- int offset, int len, u32 *val)
|
||||
-{
|
||||
- struct pci_controller *hose = bus->sysdata;
|
||||
- u32 value;
|
||||
-
|
||||
- if (ppc_md.pci_exclude_device)
|
||||
- if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
- return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
-
|
||||
- out_be32(hose->cfg_addr,
|
||||
- (1 << 31) |
|
||||
- ((bus->number - hose->bus_offset) << 16) |
|
||||
- (devfn << 8) |
|
||||
- (offset & 0xfc));
|
||||
- mb();
|
||||
-
|
||||
-#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
- if (bus->number != hose->bus_offset) {
|
||||
- /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
- * Don't do 32 bits config access during type-1 cycles */
|
||||
- switch (len) {
|
||||
- case 1:
|
||||
- value = in_8(((u8 __iomem *)hose->cfg_data) +
|
||||
- (offset & 3));
|
||||
- break;
|
||||
- case 2:
|
||||
- value = in_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
- ((offset>>1) & 1));
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- value = in_le16((u16 __iomem *)hose->cfg_data) |
|
||||
- (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- value = in_le32(hose->cfg_data);
|
||||
-
|
||||
- if (len != 4) {
|
||||
- value >>= ((offset & 0x3) << 3);
|
||||
- value &= 0xffffffff >> (32 - (len << 3));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- *val = value;
|
||||
-
|
||||
- out_be32(hose->cfg_addr, 0);
|
||||
- mb();
|
||||
-
|
||||
- return PCIBIOS_SUCCESSFUL;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
- int offset, int len, u32 val)
|
||||
-{
|
||||
- struct pci_controller *hose = bus->sysdata;
|
||||
- u32 value, mask;
|
||||
-
|
||||
- if (ppc_md.pci_exclude_device)
|
||||
- if (ppc_md.pci_exclude_device(bus->number, devfn))
|
||||
- return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
-
|
||||
- out_be32(hose->cfg_addr,
|
||||
- (1 << 31) |
|
||||
- ((bus->number - hose->bus_offset) << 16) |
|
||||
- (devfn << 8) |
|
||||
- (offset & 0xfc));
|
||||
- mb();
|
||||
-
|
||||
-#if defined(CONFIG_PPC_MPC5200_BUGFIX)
|
||||
- if (bus->number != hose->bus_offset) {
|
||||
- /* workaround for the bug 435 of the MPC5200 (L25R);
|
||||
- * Don't do 32 bits config access during type-1 cycles */
|
||||
- switch (len) {
|
||||
- case 1:
|
||||
- out_8(((u8 __iomem *)hose->cfg_data) +
|
||||
- (offset & 3), val);
|
||||
- break;
|
||||
- case 2:
|
||||
- out_le16(((u16 __iomem *)hose->cfg_data) +
|
||||
- ((offset>>1) & 1), val);
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- out_le16((u16 __iomem *)hose->cfg_data,
|
||||
- (u16)val);
|
||||
- out_le16(((u16 __iomem *)hose->cfg_data) + 1,
|
||||
- (u16)(val>>16));
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- if (len != 4) {
|
||||
- value = in_le32(hose->cfg_data);
|
||||
-
|
||||
- offset = (offset & 0x3) << 3;
|
||||
- mask = (0xffffffff >> (32 - (len << 3)));
|
||||
- mask <<= offset;
|
||||
-
|
||||
- value &= ~mask;
|
||||
- val = value | ((val << offset) & mask);
|
||||
- }
|
||||
-
|
||||
- out_le32(hose->cfg_data, val);
|
||||
- }
|
||||
- mb();
|
||||
-
|
||||
- out_be32(hose->cfg_addr, 0);
|
||||
- mb();
|
||||
-
|
||||
- return PCIBIOS_SUCCESSFUL;
|
||||
-}
|
||||
-
|
||||
-static struct pci_ops mpc52xx_pci_ops = {
|
||||
- .read = mpc52xx_pci_read_config,
|
||||
- .write = mpc52xx_pci_write_config
|
||||
-};
|
||||
-
|
||||
-
|
||||
-static void __init
|
||||
-mpc52xx_pci_setup(struct pci_controller *hose,
|
||||
- struct mpc52xx_pci __iomem *pci_regs)
|
||||
-{
|
||||
- struct resource *res;
|
||||
- u32 tmp;
|
||||
- int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
|
||||
-
|
||||
- pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs);
|
||||
-
|
||||
- /* pci_process_bridge_OF_ranges() found all our addresses for us;
|
||||
- * now store them in the right places */
|
||||
- hose->cfg_addr = &pci_regs->car;
|
||||
- hose->cfg_data = hose->io_base_virt;
|
||||
- hose->io_base_virt = ioremap(hose->io_base_phys,
|
||||
- hose->io_resource.end + 1 -
|
||||
- hose->io_resource.start);
|
||||
- isa_io_base = (unsigned long) hose->io_base_virt;
|
||||
-
|
||||
- /* Control regs */
|
||||
- tmp = in_be32(&pci_regs->scr);
|
||||
- tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
- out_be32(&pci_regs->scr, tmp);
|
||||
-
|
||||
- /* Memory windows */
|
||||
- res = &hose->mem_resources[0];
|
||||
- if (res->flags) {
|
||||
- pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
- res->start, res->end, res->flags);
|
||||
- out_be32(&pci_regs->iw0btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
- if (res->flags & IORESOURCE_PREFETCH)
|
||||
- iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
- else
|
||||
- iwcr0 |= MPC52xx_PCI_IWCR_READ;
|
||||
- }
|
||||
-
|
||||
- res = &hose->mem_resources[1];
|
||||
- if (res->flags) {
|
||||
- pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
|
||||
- res->start, res->end, res->flags);
|
||||
- out_be32(&pci_regs->iw1btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
|
||||
- if (res->flags & IORESOURCE_PREFETCH)
|
||||
- iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
|
||||
- else
|
||||
- iwcr1 |= MPC52xx_PCI_IWCR_READ;
|
||||
- }
|
||||
-
|
||||
- /* IO resources */
|
||||
- res = &hose->io_resource;
|
||||
- if (!res) {
|
||||
- printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
|
||||
- return;
|
||||
- }
|
||||
- pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
|
||||
- ".io_base_phys=0x%p\n",
|
||||
- res->start, res->end, res->flags, (void*)hose->io_base_phys);
|
||||
- out_be32(&pci_regs->iw2btar,
|
||||
- MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
|
||||
- res->start,
|
||||
- res->end - res->start + 1));
|
||||
- iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
|
||||
-
|
||||
- /* Set all the IWCR fields at once; they're in the same reg */
|
||||
- out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
|
||||
-
|
||||
- out_be32(&pci_regs->tbatr0,
|
||||
- MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
|
||||
- out_be32(&pci_regs->tbatr1,
|
||||
- MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
|
||||
-
|
||||
- out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
|
||||
-
|
||||
-#if 0
|
||||
- /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
|
||||
- /* Not necessary and can be a bad thing if for example the bootloader
|
||||
- is displaying a splash screen or ... Just left here for
|
||||
- documentation purpose if anyone need it */
|
||||
- tmp = in_be32(&pci_regs->gscr);
|
||||
- out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
|
||||
- udelay(50);
|
||||
- out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mpc52xx_pci_fixup_resources(struct pci_dev *dev)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
|
||||
- dev->vendor, dev->device);
|
||||
-
|
||||
- /* We don't rely on boot loader for PCI and resets all
|
||||
- devices */
|
||||
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
- struct resource *res = &dev->resource[i];
|
||||
- if (res->end > res->start) { /* Only valid resources */
|
||||
- res->end -= res->start;
|
||||
- res->start = 0;
|
||||
- res->flags |= IORESOURCE_UNSET;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* The PCI Host bridge of MPC52xx has a prefetch memory resource
|
||||
- fixed to 1Gb. Doesn't fit in the resource system so we remove it */
|
||||
- if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
|
||||
- ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
|
||||
- || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
|
||||
- struct resource *res = &dev->resource[1];
|
||||
- res->start = res->end = res->flags = 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-int __init
|
||||
-mpc52xx_add_bridge(struct device_node *node)
|
||||
-{
|
||||
- int len;
|
||||
- struct mpc52xx_pci __iomem *pci_regs;
|
||||
- struct pci_controller *hose;
|
||||
- const int *bus_range;
|
||||
- struct resource rsrc;
|
||||
-
|
||||
- pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
|
||||
-
|
||||
- pci_assign_all_buses = 1;
|
||||
-
|
||||
- if (of_address_to_resource(node, 0, &rsrc) != 0) {
|
||||
- printk(KERN_ERR "Can't get %s resources\n", node->full_name);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- bus_range = get_property(node, "bus-range", &len);
|
||||
- if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
- printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n",
|
||||
- node->full_name);
|
||||
- bus_range = NULL;
|
||||
- }
|
||||
-
|
||||
- /* There are some PCI quirks on the 52xx, register the hook to
|
||||
- * fix them. */
|
||||
- ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
|
||||
-
|
||||
- /* Alloc and initialize the pci controller. Values in the device
|
||||
- * tree are needed to configure the 52xx PCI controller. Rather
|
||||
- * than parse the tree here, let pci_process_bridge_OF_ranges()
|
||||
- * do it for us and extract the values after the fact */
|
||||
- hose = pcibios_alloc_controller();
|
||||
- if (!hose)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- hose->arch_data = node;
|
||||
- hose->set_cfg_type = 1;
|
||||
-
|
||||
- hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
-
|
||||
- hose->bus_offset = 0;
|
||||
- hose->ops = &mpc52xx_pci_ops;
|
||||
-
|
||||
- pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
|
||||
- if (!pci_regs)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- pci_process_bridge_OF_ranges(hose, node, 0);
|
||||
-
|
||||
- /* Finish setting up PCI using values obtained by
|
||||
- * pci_proces_bridge_OF_ranges */
|
||||
- mpc52xx_pci_setup(hose, pci_regs);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
--
|
||||
1.4.4.2
|
||||
|
828
debian/patches/features/powerpc/efika/0031-sound-Add-support-for-the-MPC52xx-PSC-AC97-Link.txt
vendored
Normal file
828
debian/patches/features/powerpc/efika/0031-sound-Add-support-for-the-MPC52xx-PSC-AC97-Link.txt
vendored
Normal file
|
@ -0,0 +1,828 @@
|
|||
From 46e8903e34759728afd11dd11c481e6a94e6b06d Mon Sep 17 00:00:00 2001
|
||||
From: Sylvain Munaut <tnt@246tNt.com>
|
||||
Date: Mon, 18 Dec 2006 22:51:38 +0100
|
||||
Subject: [PATCH] [PATCH] sound: Add support for the MPC52xx PSC AC97 Link
|
||||
|
||||
Messy driver, to be cleaned ... a lot ...
|
||||
|
||||
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
|
||||
---
|
||||
include/asm-ppc/mpc52xx_psc.h | 10 +-
|
||||
sound/ppc/Kconfig | 16 +
|
||||
sound/ppc/Makefile | 3 +
|
||||
sound/ppc/mpc52xx_ac97.c | 738 +++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 765 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/asm-ppc/mpc52xx_psc.h b/include/asm-ppc/mpc52xx_psc.h
|
||||
index 9d850b2..c82b8d4 100644
|
||||
--- a/include/asm-ppc/mpc52xx_psc.h
|
||||
+++ b/include/asm-ppc/mpc52xx_psc.h
|
||||
@@ -28,6 +28,10 @@
|
||||
#define MPC52xx_PSC_MAXNUM 6
|
||||
|
||||
/* Programmable Serial Controller (PSC) status register bits */
|
||||
+#define MPC52xx_PSC_SR_UNEX_RX 0x0001
|
||||
+#define MPC52xx_PSC_SR_DATA_VAL 0x0002
|
||||
+#define MPC52xx_PSC_SR_DATA_OVR 0x0004
|
||||
+#define MPC52xx_PSC_SR_CMDSEND 0x0008
|
||||
#define MPC52xx_PSC_SR_CDE 0x0080
|
||||
#define MPC52xx_PSC_SR_RXRDY 0x0100
|
||||
#define MPC52xx_PSC_SR_RXFULL 0x0200
|
||||
@@ -132,8 +136,10 @@ struct mpc52xx_psc {
|
||||
u8 reserved5[3];
|
||||
u8 ctlr; /* PSC + 0x1c */
|
||||
u8 reserved6[3];
|
||||
- u16 ccr; /* PSC + 0x20 */
|
||||
- u8 reserved7[14];
|
||||
+ u32 ccr; /* PSC + 0x20 */
|
||||
+ u32 ac97_slots; /* PSC + 0x24 */
|
||||
+ u32 ac97_cmd; /* PSC + 0x28 */
|
||||
+ u32 ac97_data; /* PSC + 0x2c */
|
||||
u8 ivr; /* PSC + 0x30 */
|
||||
u8 reserved8[3];
|
||||
u8 ip; /* PSC + 0x34 */
|
||||
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
|
||||
index a3fb149..afd58f7 100644
|
||||
--- a/sound/ppc/Kconfig
|
||||
+++ b/sound/ppc/Kconfig
|
||||
@@ -33,3 +33,19 @@ config SND_POWERMAC_AUTO_DRC
|
||||
option.
|
||||
|
||||
endmenu
|
||||
+
|
||||
+
|
||||
+# ALSA ppc drivers
|
||||
+
|
||||
+menu "ALSA PPC devices"
|
||||
+ depends on SND!=n && PPC
|
||||
+
|
||||
+config SND_PPC_MPC52xx_AC97
|
||||
+ tristate "Freescale MPC52xx AC97 interface support"
|
||||
+ depends on SND && PPC_MPC52xx
|
||||
+ select SND_AC97_CODEC
|
||||
+ help
|
||||
+ Say Y or M if you want to support any AC97 codec attached to
|
||||
+ the Freescqle MPC52xx AC97 interface.
|
||||
+
|
||||
+endmenu
|
||||
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
|
||||
index 4d95c65..c29cb9b 100644
|
||||
--- a/sound/ppc/Makefile
|
||||
+++ b/sound/ppc/Makefile
|
||||
@@ -4,6 +4,9 @@
|
||||
#
|
||||
|
||||
snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
|
||||
+snd-mpc52xx-ac97-objs := mpc52xx_ac97.o
|
||||
|
||||
# Toplevel Module Dependency
|
||||
obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
|
||||
+
|
||||
+obj-$(CONFIG_SND_PPC_MPC52xx_AC97) += snd-mpc52xx-ac97.o
|
||||
diff --git a/sound/ppc/mpc52xx_ac97.c b/sound/ppc/mpc52xx_ac97.c
|
||||
new file mode 100644
|
||||
index 0000000..a4f008e
|
||||
--- /dev/null
|
||||
+++ b/sound/ppc/mpc52xx_ac97.c
|
||||
@@ -0,0 +1,738 @@
|
||||
+/*
|
||||
+ * Driver for the PSC of the Freescale MPC52xx configured as AC97 interface
|
||||
+ *
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
|
||||
+ *
|
||||
+ * This file is licensed under the terms of the GNU General Public License
|
||||
+ * version 2. This program is licensed "as is" without any warranty of any
|
||||
+ * kind, whether express or implied.
|
||||
+ */
|
||||
+
|
||||
+#define DEBUG
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+#include <sound/driver.h>
|
||||
+#include <sound/core.h>
|
||||
+#include <sound/initval.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/ac97_codec.h>
|
||||
+
|
||||
+#include <asm/of_platform.h>
|
||||
+#include <asm/mpc52xx_psc.h>
|
||||
+
|
||||
+
|
||||
+#define DRV_NAME "mpc52xx-psc-ac97"
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Structs / Defines */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+/* Private structure */
|
||||
+struct mpc52xx_ac97_priv {
|
||||
+ struct device *dev;
|
||||
+ resource_size_t mem_start;
|
||||
+ resource_size_t mem_len;
|
||||
+ int irq;
|
||||
+ struct mpc52xx_psc __iomem *psc;
|
||||
+ struct snd_card *card;
|
||||
+ struct snd_pcm *pcm;
|
||||
+ struct snd_ac97 *ac97;
|
||||
+
|
||||
+ struct snd_pcm_substream *substream_playback;
|
||||
+ unsigned int buf_pos;
|
||||
+};
|
||||
+
|
||||
+/* Register bit definition (AC97 mode specific) */
|
||||
+#define PSC_AC97_SLOT_BIT(n) (1<<(12-n))
|
||||
+#define PSC_AC97_SLOTS_XMIT_SHIFT 16
|
||||
+#define PSC_AC97_SLOTS_RECV_SHIFT 0
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* ISR routine */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static irqreturn_t
|
||||
+mpc52xx_ac97_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = dev_id;
|
||||
+
|
||||
+ static int icnt = 0;
|
||||
+ #if 0
|
||||
+ {
|
||||
+ unsigned int val;
|
||||
+// val = in_be32(&priv->psc->ac97_data);
|
||||
+ printk(KERN_INFO "mpc52xx_ac97_irq fired (isr=%04x, status=%04x) %08x\n", in_be16(&priv->psc->mpc52xx_psc_imr), in_be16(&priv->psc->mpc52xx_psc_status), val);
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_ERR_STAT);
|
||||
+ }
|
||||
+ #endif
|
||||
+
|
||||
+ /* Anti Crash during dev ;) */
|
||||
+ #if 0
|
||||
+ if ((icnt++) > 50000)
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0);
|
||||
+ #endif
|
||||
+
|
||||
+ /* Copy 64 data into the buffer */
|
||||
+ if (in_be16(&priv->psc->mpc52xx_psc_imr) & 0x0100) {
|
||||
+ if (priv->substream_playback) {
|
||||
+ struct snd_pcm_runtime *rt;
|
||||
+
|
||||
+ rt = priv->substream_playback->runtime;
|
||||
+
|
||||
+ if (snd_pcm_playback_hw_avail(rt) < bytes_to_frames(rt,128)) {
|
||||
+ int i;
|
||||
+ /* Push silence */
|
||||
+ for (i=0; i<64; i++)
|
||||
+ out_be32(&priv->psc->mpc52xx_psc_buffer_32, 0x00000800);
|
||||
+ printk(KERN_DEBUG "pushed silence ...\n");
|
||||
+ } else {
|
||||
+ int i;
|
||||
+ unsigned short *data;
|
||||
+
|
||||
+ data = (unsigned short *)
|
||||
+ (&rt->dma_area[frames_to_bytes(rt, priv->buf_pos)]);
|
||||
+
|
||||
+ for (i=0; i<64; i++)
|
||||
+ out_be32(&priv->psc->mpc52xx_psc_buffer_32,
|
||||
+ (((unsigned int)data[i]) << 16) | 0x00000000);
|
||||
+ /* Setting the sof bit looks useless */
|
||||
+
|
||||
+ priv->buf_pos += bytes_to_frames(rt,128);;
|
||||
+ if (priv->buf_pos >= rt->buffer_size)
|
||||
+ priv->buf_pos = 0;
|
||||
+
|
||||
+ snd_pcm_period_elapsed(priv->substream_playback);
|
||||
+ }
|
||||
+ } else {
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0);
|
||||
+ printk(KERN_DEBUG "Interrupt with no stream ...\n");
|
||||
+ }
|
||||
+ } else {
|
||||
+ printk(KERN_ERR "Spurious int\n");
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* PCM interface */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+/* HW desc */
|
||||
+
|
||||
+static struct snd_pcm_hardware mpc52xx_ac97_hw = {
|
||||
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
+ SNDRV_PCM_INFO_MMAP |
|
||||
+ SNDRV_PCM_INFO_MMAP_VALID,
|
||||
+ .formats = SNDRV_PCM_FMTBIT_S16_BE,
|
||||
+ .rates = SNDRV_PCM_RATE_8000_48000,
|
||||
+ .rate_min = 8000,
|
||||
+ .rate_max = 48000,
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 2, /* Support for more ? */
|
||||
+ .buffer_bytes_max = 128*1024,
|
||||
+ .period_bytes_min = 128, /* 32, */
|
||||
+ .period_bytes_max = 128, /* 16*1024, */
|
||||
+ .periods_min = 8,
|
||||
+ .periods_max = 256,
|
||||
+ .fifo_size = 512,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* Playback */
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_playback_open(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_playback_open(%p)\n", substream);
|
||||
+
|
||||
+ substream->runtime->hw = mpc52xx_ac97_hw;
|
||||
+
|
||||
+ priv->substream_playback = substream;
|
||||
+ priv->buf_pos = 0; /* FIXME Do that where ? */
|
||||
+
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_playback_close(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_playback_close(%p)\n", substream);
|
||||
+ priv->substream_playback = NULL;
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_playback_prepare(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_playback_prepare(%p)\n", substream);
|
||||
+
|
||||
+ /* FIXME, need a spinlock to protect access */
|
||||
+ if (substream->runtime->channels == 1)
|
||||
+ out_be32(&priv->psc->ac97_slots, 0x01000000);
|
||||
+ else
|
||||
+ out_be32(&priv->psc->ac97_slots, 0x03000000);
|
||||
+
|
||||
+ snd_ac97_set_rate(priv->ac97, AC97_PCM_FRONT_DAC_RATE, substream->runtime->rate);
|
||||
+
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Capture */
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_capture_open(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_capture_close(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_capture_prepare(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ return 0; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Common */
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ int rv;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_hw_params(%p)\n", substream);
|
||||
+
|
||||
+ rv = snd_pcm_lib_malloc_pages(substream,
|
||||
+ params_buffer_bytes(params));
|
||||
+ if (rv < 0) {
|
||||
+ printk(KERN_ERR "hw params failes\n"); /* FIXME */
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_DEBUG "%d %d %d\n", params_buffer_bytes(params), params_period_bytes(params), params_periods(params));
|
||||
+
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_hw_free(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_hw_free(%p)\n", substream);
|
||||
+
|
||||
+ return snd_pcm_lib_free_pages(substream);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+ int rv = 0;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "mpc52xx_ac97_trigger(%p,%d)\n", substream, cmd);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ /* Enable TX interrupt */
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0x0100); // 0x0100
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ /* Disable TX interrupt */
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0x0000);
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ rv = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* FIXME */
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static snd_pcm_uframes_t
|
||||
+mpc52xx_ac97_pointer(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = substream->pcm->private_data;
|
||||
+
|
||||
+// dev_dbg(priv->dev, "mpc52xx_ac97_pointer(%p)\n", substream);
|
||||
+
|
||||
+ if (substream->runtime->channels == 1)
|
||||
+ return priv->buf_pos; /* FIXME */
|
||||
+ else
|
||||
+ return priv->buf_pos >> 1; /* FIXME */
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Ops */
|
||||
+
|
||||
+static struct snd_pcm_ops mpc52xx_ac97_playback_ops = {
|
||||
+ .open = mpc52xx_ac97_playback_open,
|
||||
+ .close = mpc52xx_ac97_playback_close,
|
||||
+ .ioctl = snd_pcm_lib_ioctl,
|
||||
+ .hw_params = mpc52xx_ac97_hw_params,
|
||||
+ .hw_free = mpc52xx_ac97_hw_free,
|
||||
+ .prepare = mpc52xx_ac97_playback_prepare,
|
||||
+ .trigger = mpc52xx_ac97_trigger,
|
||||
+ .pointer = mpc52xx_ac97_pointer,
|
||||
+};
|
||||
+
|
||||
+static struct snd_pcm_ops mpc52xx_ac97_capture_ops = {
|
||||
+ .open = mpc52xx_ac97_capture_open,
|
||||
+ .close = mpc52xx_ac97_capture_close,
|
||||
+ .ioctl = snd_pcm_lib_ioctl,
|
||||
+ .hw_params = mpc52xx_ac97_hw_params,
|
||||
+ .hw_free = mpc52xx_ac97_hw_free,
|
||||
+ .prepare = mpc52xx_ac97_capture_prepare,
|
||||
+ .trigger = mpc52xx_ac97_trigger,
|
||||
+ .pointer = mpc52xx_ac97_pointer,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* AC97 Bus interface */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static unsigned short
|
||||
+mpc52xx_ac97_bus_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = ac97->private_data;
|
||||
+ int timeout;
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "ac97 read: reg %04x\n", reg);
|
||||
+
|
||||
+ /* Wait for it to be ready */
|
||||
+ timeout = 1000;
|
||||
+ while ((--timeout) && (in_be16(&priv->psc->mpc52xx_psc_status) &
|
||||
+ MPC52xx_PSC_SR_CMDSEND) )
|
||||
+ udelay(10);
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ printk(KERN_ERR DRV_NAME ": timeout on ac97 bus (rdy)\n");
|
||||
+ return 0xffff;
|
||||
+ }
|
||||
+
|
||||
+ /* Do the read */
|
||||
+ out_be32(&priv->psc->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24));
|
||||
+
|
||||
+ /* Wait for the answer */
|
||||
+ timeout = 1000;
|
||||
+ while ((--timeout) && !(in_be16(&priv->psc->mpc52xx_psc_status) &
|
||||
+ MPC52xx_PSC_SR_DATA_VAL) )
|
||||
+ udelay(10);
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ printk(KERN_ERR DRV_NAME ": timeout on ac97 read (val)\n");
|
||||
+ return 0xffff;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the data */
|
||||
+ val = in_be32(&priv->psc->ac97_data);
|
||||
+ if ( ((val>>24) & 0x7f) != reg ) {
|
||||
+ printk(KERN_ERR DRV_NAME ": reg echo error on ac97 read\n");
|
||||
+ return 0xffff;
|
||||
+ }
|
||||
+ val = (val >> 8) & 0xffff;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "ac97 read ok: reg %04x val %04x\n",
|
||||
+ reg, val);
|
||||
+
|
||||
+ return (unsigned short) val;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mpc52xx_ac97_bus_write(struct snd_ac97 *ac97,
|
||||
+ unsigned short reg, unsigned short val)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = ac97->private_data;
|
||||
+ int timeout;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "ac97 write: reg %04x val %04x\n",
|
||||
+ reg, val);
|
||||
+
|
||||
+ /* Wait for it to be ready */
|
||||
+ timeout = 1000;
|
||||
+ while ((--timeout) && (in_be16(&priv->psc->mpc52xx_psc_status) &
|
||||
+ MPC52xx_PSC_SR_CMDSEND) )
|
||||
+ udelay(10);
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ printk(KERN_ERR DRV_NAME ": timeout on ac97 write\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Write data */
|
||||
+ out_be32(&priv->psc->ac97_cmd, ((reg & 0x7f) << 24) | (val << 8));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mpc52xx_ac97_bus_reset(struct snd_ac97 *ac97)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv = ac97->private_data;
|
||||
+
|
||||
+ dev_dbg(priv->dev, "ac97 codec reset\n");
|
||||
+
|
||||
+ /* Do a cold reset */
|
||||
+ out_8(&priv->psc->op1, 0x03);
|
||||
+ udelay(10);
|
||||
+ out_8(&priv->psc->op0, 0x02);
|
||||
+ udelay(50);
|
||||
+
|
||||
+ /* PSC recover from cold reset (cfr user manual, not sure if useful) */
|
||||
+ out_be32(&priv->psc->sicr, in_be32(&priv->psc->sicr));
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct snd_ac97_bus_ops mpc52xx_ac97_bus_ops = {
|
||||
+ .read = mpc52xx_ac97_bus_read,
|
||||
+ .write = mpc52xx_ac97_bus_write,
|
||||
+ .reset = mpc52xx_ac97_bus_reset,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Sound driver setup */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_setup_pcm(struct mpc52xx_ac97_priv *priv)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = snd_pcm_new(priv->card, DRV_NAME "-pcm", 0, 1, 1, &priv->pcm);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME ": snd_pcm_new failed\n");
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ rv = snd_pcm_lib_preallocate_pages_for_all(priv->pcm,
|
||||
+ SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL),
|
||||
+ 128*1024, 128*1024);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME
|
||||
+ ": snd_pcm_lib_preallocate_pages_for_all failed\n");
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ snd_pcm_set_ops(priv->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
+ &mpc52xx_ac97_playback_ops);
|
||||
+ snd_pcm_set_ops(priv->pcm, SNDRV_PCM_STREAM_CAPTURE,
|
||||
+ &mpc52xx_ac97_capture_ops);
|
||||
+
|
||||
+ priv->pcm->private_data = priv;
|
||||
+ priv->pcm->info_flags = 0;
|
||||
+
|
||||
+ strcpy(priv->pcm->name, "Freescale MPC52xx PSC-AC97 PCM");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_setup_mixer(struct mpc52xx_ac97_priv *priv)
|
||||
+{
|
||||
+ struct snd_ac97_bus *ac97_bus;
|
||||
+ struct snd_ac97_template ac97_template;
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = snd_ac97_bus(priv->card, 0, &mpc52xx_ac97_bus_ops, NULL, &ac97_bus);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME ": snd_ac97_bus failed\n");
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
|
||||
+ ac97_template.private_data = priv;
|
||||
+
|
||||
+ rv = snd_ac97_mixer(ac97_bus, &ac97_template, &priv->ac97);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME ": snd_ac97_mixer failed\n");
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_hwinit(struct mpc52xx_ac97_priv *priv)
|
||||
+{
|
||||
+ /* Reset everything first by safety */
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_RX);
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_TX);
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_ERR_STAT);
|
||||
+
|
||||
+ /* Do a cold reset of codec */
|
||||
+ out_8(&priv->psc->op1, 0x03);
|
||||
+ udelay(10);
|
||||
+ out_8(&priv->psc->op0, 0x02);
|
||||
+ udelay(50);
|
||||
+
|
||||
+ /* Configure AC97 enhanced mode */
|
||||
+ out_be32(&priv->psc->sicr, 0x03010000);
|
||||
+
|
||||
+ /* No slots active */
|
||||
+ out_be32(&priv->psc->ac97_slots, 0x00000000);
|
||||
+
|
||||
+ /* No IRQ */
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0x0000);
|
||||
+
|
||||
+ /* FIFO levels */
|
||||
+ out_8(&priv->psc->rfcntl, 0x07);
|
||||
+ out_8(&priv->psc->tfcntl, 0x07);
|
||||
+ out_be16(&priv->psc->rfalarm, 0x80);
|
||||
+ out_be16(&priv->psc->tfalarm, 0x80);
|
||||
+
|
||||
+ /* Go */
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_TX_ENABLE);
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RX_ENABLE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_hwshutdown(struct mpc52xx_ac97_priv *priv)
|
||||
+{
|
||||
+ /* No IRQ */
|
||||
+ out_be16(&priv->psc->mpc52xx_psc_imr, 0x0000);
|
||||
+
|
||||
+ /* Disable TB & RX */
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_RX);
|
||||
+ out_8(&priv->psc->command,MPC52xx_PSC_RST_TX);
|
||||
+
|
||||
+ /* FIXME : Reset or put codec in low power ? */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* OF Platform Driver */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static int __devinit
|
||||
+mpc52xx_ac97_probe(struct of_device *op, const struct of_device_id *match)
|
||||
+{
|
||||
+ struct device_node *dn = op->node;
|
||||
+ struct mpc52xx_ac97_priv *priv;
|
||||
+ struct snd_card *card;
|
||||
+ struct resource res;
|
||||
+ int rv;
|
||||
+
|
||||
+ dev_dbg(&op->dev, "probing MPC52xx PSC AC97 driver\n");
|
||||
+
|
||||
+ /* Get card structure */
|
||||
+ rv = -ENOMEM;
|
||||
+ card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
||||
+ THIS_MODULE, sizeof(struct mpc52xx_ac97_priv));
|
||||
+ if (!card)
|
||||
+ goto err_early;
|
||||
+
|
||||
+ priv = card->private_data;
|
||||
+
|
||||
+ /* Init our private structure */
|
||||
+ priv->card = card;
|
||||
+ priv->dev = &op->dev;
|
||||
+
|
||||
+ /* Get resources (mem,irq,...) */
|
||||
+ rv = of_address_to_resource(dn, 0, &res);
|
||||
+ if (rv)
|
||||
+ goto err_early;
|
||||
+
|
||||
+ priv->mem_start = res.start;
|
||||
+ priv->mem_len = res.end - res.start + 1;
|
||||
+
|
||||
+ if (!request_mem_region(priv->mem_start, priv->mem_len, DRV_NAME)) {
|
||||
+ printk(KERN_ERR DRV_NAME ": request_mem_region failed\n");
|
||||
+ rv = -EBUSY;
|
||||
+ goto err_early;
|
||||
+ }
|
||||
+
|
||||
+ priv->psc = ioremap(priv->mem_start, priv->mem_len);
|
||||
+ if (!priv->psc) {
|
||||
+ printk(KERN_ERR DRV_NAME ": ioremap failed\n");
|
||||
+ rv = -ENOMEM;
|
||||
+ goto err_iomap;
|
||||
+ }
|
||||
+
|
||||
+ priv->irq = irq_of_parse_and_map(dn, 0);
|
||||
+ if (priv->irq == NO_IRQ) {
|
||||
+ printk(KERN_ERR DRV_NAME ": irq_of_parse_and_map failed\n");
|
||||
+ rv = -EBUSY;
|
||||
+ goto err_irqmap;
|
||||
+ }
|
||||
+
|
||||
+ /* Low level HW Init */
|
||||
+ mpc52xx_ac97_hwinit(priv);
|
||||
+
|
||||
+ /* Request IRQ now that we're 'stable' */
|
||||
+ rv = request_irq(priv->irq, mpc52xx_ac97_irq, 0, DRV_NAME, priv);
|
||||
+ if (rv < 0) {
|
||||
+ printk(KERN_ERR DRV_NAME ": request_irq failed\n");
|
||||
+ goto err_irqreq;
|
||||
+ }
|
||||
+
|
||||
+ /* Prepare sound stuff */
|
||||
+ rv = mpc52xx_ac97_setup_mixer(priv);
|
||||
+ if (rv)
|
||||
+ goto err_late;
|
||||
+
|
||||
+ rv = mpc52xx_ac97_setup_pcm(priv);
|
||||
+ if (rv)
|
||||
+ goto err_late;
|
||||
+
|
||||
+ /* Finally register the card */
|
||||
+ snprintf(card->shortname, sizeof(card->shortname), DRV_NAME);
|
||||
+ snprintf(card->longname, sizeof(card->longname),
|
||||
+ "Freescale MPC52xx PSC-AC97 (%s)", card->mixername);
|
||||
+
|
||||
+ rv = snd_card_register(card);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME ": snd_card_register failed\n");
|
||||
+ goto err_late;
|
||||
+ }
|
||||
+
|
||||
+ dev_set_drvdata(&op->dev, priv);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_late:
|
||||
+ free_irq(priv->irq, priv);
|
||||
+err_irqreq:
|
||||
+ mpc52xx_ac97_hwshutdown(priv);
|
||||
+ irq_dispose_mapping(priv->irq);
|
||||
+err_irqmap:
|
||||
+ iounmap(priv->psc);
|
||||
+err_iomap:
|
||||
+ release_mem_region(priv->mem_start, priv->mem_len);
|
||||
+err_early:
|
||||
+ if (card)
|
||||
+ snd_card_free(card);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mpc52xx_ac97_remove(struct of_device *op)
|
||||
+{
|
||||
+ struct mpc52xx_ac97_priv *priv;
|
||||
+
|
||||
+ dev_dbg(&op->dev, "removing MPC52xx PSC AC97 driver\n");
|
||||
+
|
||||
+ priv = dev_get_drvdata(&op->dev);
|
||||
+ if (priv) {
|
||||
+ /* Sound subsys shutdown */
|
||||
+ snd_card_free(priv->card);
|
||||
+
|
||||
+ /* Low level HW shutdown */
|
||||
+ mpc52xx_ac97_hwshutdown(priv);
|
||||
+
|
||||
+ /* Release resources */
|
||||
+ iounmap(priv->psc);
|
||||
+ free_irq(priv->irq, priv);
|
||||
+ irq_dispose_mapping(priv->irq);
|
||||
+ release_mem_region(priv->mem_start, priv->mem_len);
|
||||
+ }
|
||||
+
|
||||
+ dev_set_drvdata(&op->dev, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct of_device_id mpc52xx_ac97_of_match[] = {
|
||||
+ {
|
||||
+/* .type = "ac97", FIXME Efika ... */
|
||||
+ .compatible = "mpc5200b-psc-ac97", /* B only for now */
|
||||
+ },
|
||||
+};
|
||||
+/* Prevent autoload during developpment phase ... */
|
||||
+/* MODULE_DEVICE_TABLE(of, mpc52xx_ac97_of_match); */
|
||||
+
|
||||
+
|
||||
+static struct of_platform_driver mpc52xx_ac97_of_driver = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = DRV_NAME,
|
||||
+ .match_table = mpc52xx_ac97_of_match,
|
||||
+ .probe = mpc52xx_ac97_probe,
|
||||
+ .remove = mpc52xx_ac97_remove,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* ======================================================================== */
|
||||
+/* Module */
|
||||
+/* ======================================================================== */
|
||||
+
|
||||
+static int __init
|
||||
+mpc52xx_ac97_init(void)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ /* FIXME BIG FAT EFIKA HACK */
|
||||
+ {
|
||||
+ void *mbar;
|
||||
+ mbar = ioremap(0xf0000000, 0x100000);
|
||||
+ printk(KERN_INFO "EFIKA HACK: port_config %08x\n", in_be32(mbar + 0xb00));
|
||||
+ out_be32(mbar + 0xb00, 0x01051124);
|
||||
+ printk(KERN_INFO "EFIKA HACK: port_config %08x\n", in_be32(mbar + 0xb00));
|
||||
+ iounmap(mbar);
|
||||
+ }
|
||||
+ /* ------------------------ */
|
||||
+
|
||||
+ printk(KERN_INFO "Sound: MPC52xx PSC AC97 driver\n");
|
||||
+
|
||||
+ rv = of_register_platform_driver(&mpc52xx_ac97_of_driver);
|
||||
+ if (rv) {
|
||||
+ printk(KERN_ERR DRV_NAME ": "
|
||||
+ "of_register_platform_driver failed (%i)\n", rv);
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+mpc52xx_ac97_exit(void)
|
||||
+{
|
||||
+ of_unregister_platform_driver(&mpc52xx_ac97_of_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(mpc52xx_ac97_init);
|
||||
+module_exit(mpc52xx_ac97_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
|
||||
+MODULE_DESCRIPTION(DRV_NAME ": Freescale MPC52xx PSC AC97 driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
From 49029f815b10175dcec09152929d53efe0ed510c Mon Sep 17 00:00:00 2001
|
||||
From: Sven Luther <sven@tael.(none)>
|
||||
Date: Tue, 9 Jan 2007 11:12:51 +0100
|
||||
Subject: [PATCH] Fix the bestcomm interrupt property, fixes the ethernet driver.
|
||||
|
||||
---
|
||||
arch/powerpc/kernel/prom_init.c | 85 +++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 85 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
|
||||
index 520ef42..a1cf18e 100644
|
||||
--- a/arch/powerpc/kernel/prom_init.c
|
||||
+++ b/arch/powerpc/kernel/prom_init.c
|
||||
@@ -2117,11 +2117,96 @@ static void __init fixup_device_tree_pmac(void)
|
||||
#define fixup_device_tree_pmac()
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_PPC_EFIKA
|
||||
+/* The current fw of the Efika has a device tree needs quite a few
|
||||
+ * fixups to be compliant with the mpc52xx bindings. It's currently
|
||||
+ * unknown if it will ever be compliant (come on bPlan ...) so we do fixups.
|
||||
+ * NOTE that we (barely) tolerate it because the EFIKA was out before
|
||||
+ * the bindings were finished, for any new boards -> RTFM ! */
|
||||
+
|
||||
+struct subst_entry {
|
||||
+ char *path;
|
||||
+ char *property;
|
||||
+ void *value;
|
||||
+ int value_len;
|
||||
+};
|
||||
+
|
||||
+static void __init fixup_device_tree_efika(void)
|
||||
+{
|
||||
+ /* Substitution table */
|
||||
+ #define prop_cstr(x) x, sizeof(x)
|
||||
+ int prop_sound_irq[3] = { 2, 2, 0 };
|
||||
+ int prop_bcomm_irq[48];
|
||||
+ struct subst_entry efika_subst_table[] = {
|
||||
+ { "/", "device_type", prop_cstr("efika") },
|
||||
+ { "/builtin", "compatible", prop_cstr("soc") },
|
||||
+ { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc52xx-ata"), },
|
||||
+ { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc52xx-bestcomm") },
|
||||
+ { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
|
||||
+ { "/builtin/ethernet", "compatible", prop_cstr("mpc5200b-fec\0mpc52xx-fec") },
|
||||
+ { "/builtin/pic", "compatible", prop_cstr("mpc5200b-pic\0mpc52xx-pic") },
|
||||
+ { "/builtin/serial", "compatible", prop_cstr("mpc5200b-psc-uart\0mpc52xx-psc-uart") },
|
||||
+ { "/builtin/sound", "compatible", prop_cstr("mpc5200b-psc-ac97\0mpc52xx-psc-ac97") },
|
||||
+ { "/builtin/sound", "interrupts", prop_sound_irq, sizeof(prop_sound_irq) },
|
||||
+ { "/builtin/sram", "compatible", prop_cstr("mpc5200b-sram\0mpc52xx-sram") },
|
||||
+ { "/builtin/sram", "device_type", prop_cstr("sram") },
|
||||
+ {}
|
||||
+ };
|
||||
+ #undef prop_cstr
|
||||
+
|
||||
+ /* Vars */
|
||||
+ u32 node;
|
||||
+ char prop[64];
|
||||
+ int rv, i;
|
||||
+
|
||||
+ /* Check if we're really running on a EFIKA */
|
||||
+ node = call_prom("finddevice", 1, 1, ADDR("/"));
|
||||
+ if (!PHANDLE_VALID(node))
|
||||
+ return;
|
||||
+
|
||||
+ rv = prom_getprop(node, "model", prop, sizeof(prop));
|
||||
+ if (rv == PROM_ERROR)
|
||||
+ return;
|
||||
+ if (strcmp(prop, "EFIKA5K2"))
|
||||
+ return;
|
||||
+
|
||||
+ prom_printf("Applying EFIKA device tree fixups\n");
|
||||
+
|
||||
+ /* Fill the prop_bcomm_irq */
|
||||
+ for (i=0; i<16; i++) {
|
||||
+ prop_bcomm_irq[3*i ] = 3;
|
||||
+ prop_bcomm_irq[3*i+1] = i;
|
||||
+ prop_bcomm_irq[3*i+2] = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Process substitution table */
|
||||
+ for (i=0; efika_subst_table[i].path; i++) {
|
||||
+ struct subst_entry *se = &efika_subst_table[i];
|
||||
+
|
||||
+ node = call_prom("finddevice", 1, 1, ADDR(se->path));
|
||||
+ if (!PHANDLE_VALID(node)) {
|
||||
+ prom_printf("fixup_device_tree_efika: ",
|
||||
+ "skipped entry %x - not found\n", i);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ rv = prom_setprop(node, se->path, se->property,
|
||||
+ se->value, se->value_len );
|
||||
+ if (rv == PROM_ERROR)
|
||||
+ prom_printf("fixup_device_tree_efika: ",
|
||||
+ "skipped entry %x - setprop error\n", i);
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+#define fixup_device_tree_efika()
|
||||
+#endif
|
||||
+
|
||||
static void __init fixup_device_tree(void)
|
||||
{
|
||||
fixup_device_tree_maple();
|
||||
fixup_device_tree_chrp();
|
||||
fixup_device_tree_pmac();
|
||||
+ fixup_device_tree_efika();
|
||||
}
|
||||
|
||||
static void __init prom_find_boot_cpu(void)
|
||||
--
|
||||
1.4.4.2
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
+ debian/kernelvariables.patch
|
||||
+ debian/doc-build-parallel.patch
|
||||
+ debian/scripts-kconfig-reportoldconfig.patch
|
||||
#+ debian/powerpc-mkvmlinuz-support-ppc.patch
|
||||
#+ debian/powerpc-mkvmlinuz-support-powerpc.patch
|
||||
+ debian/powerpc-mkvmlinuz-support-ppc.patch
|
||||
+ debian/powerpc-mkvmlinuz-support-powerpc.patch
|
||||
|
||||
+ bugfix/powerpc/build-links.patch
|
||||
+ bugfix/powerpc/mv643xx-hotplug-support.patch
|
||||
|
@ -26,3 +26,35 @@
|
|||
+ features/arm/ixp4xx-net-driver-improve-mac-handling.patch
|
||||
+ bugfix/Makefile-localversion-backup.patch
|
||||
+ bugfix/drivers-bus_to_virt.patch
|
||||
|
||||
+ features/powerpc/efika/0001-powerpc-serial-Dispose-irq-mapping-when-done-in-mpc52xx_serial.c.txt
|
||||
+ features/powerpc/efika/0002-powerpc-52xx-Don-t-use-device_initcall-to-probe-of_platform_bus.txt
|
||||
+ features/powerpc/efika/0004-powerpc-Use-common-52xx-of_platform-probe-code-for-EFIKA.txt
|
||||
+ features/powerpc/efika/0005-powerpc-Restore-proper-link-order-in-platform.txt
|
||||
+ features/powerpc/efika/0006-Rework-the-OHCI-quirk-mecanism-as-suggested-by-David.txt
|
||||
+ features/powerpc/efika/0007-Implement-support-for-split-endian-OHCI.txt
|
||||
+ features/powerpc/efika/0008-ohci-Rework-bus-glue-integration-to-allow-several-at-once.txt
|
||||
+ features/powerpc/efika/0009-ohci-Add-support-for-OHCI-controller-on-the-of_platform-bus.txt
|
||||
+ features/powerpc/efika/0010-libata-Add-support-for-the-MPC52xx-ATA-controller.txt
|
||||
+ features/powerpc/efika/0011-ohci-Whitespace-and-typo-fix-in-ohci-ppc-of.c.txt
|
||||
+ features/powerpc/efika/0012-ata-Fix-pata_mpc52xx.c-compatible-list.txt
|
||||
+ features/powerpc/efika/0013-powerpc-serial-Fix-mpc52xx_uart.c-compatible-list.txt
|
||||
+ features/powerpc/efika/0014-powerpc-Small-cleanup-of-EFIKA-platform.txt
|
||||
+ features/powerpc/efika/0015-powerpc-Add-a-unified-uevent-handler-for-bus-based-on-of_device.txt
|
||||
+ features/powerpc/efika/0016-macintosh-Use-the-new-of_device-common-uevent-handler.txt
|
||||
+ features/powerpc/efika/0017-powerpc-Add-uevent-handler-for-of_platform_bus.txt
|
||||
+ features/powerpc/efika/0018-powerpc-Add-uevent-handler-for-ibmebus.txt
|
||||
+ features/powerpc/efika/0019-MPC5200-Bestcomm-platform-driver.txt
|
||||
+ features/powerpc/efika/0020-Fec-MPC5200-eth-driver.txt
|
||||
+ features/powerpc/efika/0021-POWERPC-Copy-bestcomm-support-files-into-arch-powerpc.txt
|
||||
+ features/powerpc/efika/0022-MPC52xx-PCI-now-working-on-lite5200.-ugly-but-working.txt
|
||||
+ features/powerpc/efika/0023-POWERPC-Make-FEC-work-on-the-lite5200.txt
|
||||
+ features/powerpc/efika/0024-Add-missing-function-prototype.txt
|
||||
+ features/powerpc/efika/0025-POWERPC-Misc-EFIKA-fixups-for-rtas-chrp.txt
|
||||
+ features/powerpc/efika/0026-POWERPC-Cleanup-mpc52xx-PCI-support.txt
|
||||
+ features/powerpc/efika/0027-POWERPC-Change-name-of-mpc52xx-pci-support-file-in-Makefile.txt
|
||||
+ features/powerpc/efika/0028-POWERPC-Change-link-order-so-mpc52xx-fec-always-shows-up-as-eth0.txt
|
||||
+ features/powerpc/efika/0029-POWERPC-Fixup-pr_print-format-for-mpc52xx-pci-support.txt
|
||||
+ features/powerpc/efika/0030-POWERPC-Add-mpc52xx-lite5200-PCI-support.txt
|
||||
+ features/powerpc/efika/0031-sound-Add-support-for-the-MPC52xx-PSC-AC97-Link.txt
|
||||
+ features/powerpc/efika/0033-Fix-the-bestcomm-interrupt-property-fixes-the-ethernet-driver.txt
|
||||
|
|
Loading…
Reference in New Issue