LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
From: Albert Herranz @ 2010-02-28 14:08 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, linux-usb; +Cc: Albert Herranz
In-Reply-To: <1267366082-15248-1-git-send-email-albert_herranz@yahoo.es>

The HCD_NO_COHERENT_MEM USB host controller driver flag can be enabled
to instruct the USB stack to avoid allocating coherent memory for USB
buffers.

This flag is useful to overcome some esoteric memory access restrictions
found in some platforms.
For example, the Nintendo Wii video game console is a NOT_COHERENT_CACHE
platform that is unable to safely perform non-32 bit uncached writes
to RAM because the byte enables are not connected to the bus.
Thus, in that platform, "coherent" DMA buffers cannot be directly used
by the kernel code unless it guarantees that all write accesses
to said buffers are done in 32 bit chunks (which is not the case in the
USB subsystem).

To avoid this unwanted behaviour HCD_NO_COHERENT_MEM can be enabled at
the HCD controller, causing USB buffer allocations to be satisfied from
normal kernel memory. In this case, the USB stack will make sure that
the buffers get properly mapped/unmapped for DMA transfers using the DMA
streaming mapping API.

Note that other parts of the USB stack may also use coherent memory,
like for example the hardware descriptors used in the EHCI controllers.
This needs to be checked and addressed separately. In the EHCI example,
hardware descriptors are accessed in 32-bit (or 64-bit) chunks, causing
no problems in the described scenario.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
---
 drivers/usb/core/buffer.c |   15 ++++++++-----
 drivers/usb/core/hcd.c    |   50 +++++++++++++++++++++++++++++++++++++-------
 drivers/usb/core/hcd.h    |   13 ++++++-----
 3 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 3ba2fff..fede7a0 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -53,8 +53,9 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 	char		name[16];
 	int 		i, size;
 
-	if (!hcd->self.controller->dma_mask &&
-	    !(hcd->driver->flags & HCD_LOCAL_MEM))
+	if ((!hcd->self.controller->dma_mask &&
+	    !(hcd->driver->flags & HCD_LOCAL_MEM)) ||
+	    (hcd->driver->flags & HCD_NO_COHERENT_MEM))
 		return 0;
 
 	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
@@ -109,8 +110,9 @@ void *hcd_buffer_alloc(
 	int 			i;
 
 	/* some USB hosts just use PIO */
-	if (!bus->controller->dma_mask &&
-	    !(hcd->driver->flags & HCD_LOCAL_MEM)) {
+	if ((!bus->controller->dma_mask &&
+	    !(hcd->driver->flags & HCD_LOCAL_MEM)) ||
+	    (hcd->driver->flags & HCD_NO_COHERENT_MEM)) {
 		*dma = ~(dma_addr_t) 0;
 		return kmalloc(size, mem_flags);
 	}
@@ -135,8 +137,9 @@ void hcd_buffer_free(
 	if (!addr)
 		return;
 
-	if (!bus->controller->dma_mask &&
-	    !(hcd->driver->flags & HCD_LOCAL_MEM)) {
+	if ((!bus->controller->dma_mask &&
+	    !(hcd->driver->flags & HCD_LOCAL_MEM)) ||
+	    (hcd->driver->flags & HCD_NO_COHERENT_MEM)) {
 		kfree(addr);
 		return;
 	}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 80995ef..c2596c5 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1260,6 +1260,34 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
 	*dma_handle = 0;
 }
 
+static int urb_needs_setup_dma_map(struct usb_hcd *hcd, struct urb *urb)
+{
+	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
+	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+		urb->setup_dma == ~(dma_addr_t)0);
+}
+
+static int urb_needs_setup_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
+{
+	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
+	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+		urb->setup_dma && urb->setup_dma != ~(dma_addr_t)0);
+}
+
+static int urb_needs_transfer_dma_map(struct usb_hcd *hcd, struct urb *urb)
+{
+	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
+	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+		urb->transfer_dma == ~(dma_addr_t)0);
+}
+
+static int urb_needs_transfer_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
+{
+	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
+	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+		urb->transfer_dma && urb->transfer_dma != ~(dma_addr_t)0);
+}
+
 static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 			   gfp_t mem_flags)
 {
@@ -1275,7 +1303,7 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 		return 0;
 
 	if (usb_endpoint_xfer_control(&urb->ep->desc)
-	    && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+	    && urb_needs_setup_dma_map(hcd, urb)) {
 		if (hcd->self.uses_dma) {
 			urb->setup_dma = dma_map_single(
 					hcd->self.controller,
@@ -1296,7 +1324,7 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 
 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 	if (ret == 0 && urb->transfer_buffer_length != 0
-	    && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+	    && urb_needs_transfer_dma_map(hcd, urb)) {
 		if (hcd->self.uses_dma) {
 			urb->transfer_dma = dma_map_single (
 					hcd->self.controller,
@@ -1334,12 +1362,15 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 		return;
 
 	if (usb_endpoint_xfer_control(&urb->ep->desc)
-	    && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
-		if (hcd->self.uses_dma)
+	    && urb_needs_setup_dma_unmap(hcd, urb)) {
+		if (hcd->self.uses_dma) {
 			dma_unmap_single(hcd->self.controller, urb->setup_dma,
 					sizeof(struct usb_ctrlrequest),
 					DMA_TO_DEVICE);
-		else if (hcd->driver->flags & HCD_LOCAL_MEM)
+			if ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+			    (urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+				urb->setup_dma = ~(dma_addr_t)0;
+		} else if (hcd->driver->flags & HCD_LOCAL_MEM)
 			hcd_free_coherent(urb->dev->bus, &urb->setup_dma,
 					(void **)&urb->setup_packet,
 					sizeof(struct usb_ctrlrequest),
@@ -1348,13 +1379,16 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 
 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 	if (urb->transfer_buffer_length != 0
-	    && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
-		if (hcd->self.uses_dma)
+	    && urb_needs_transfer_dma_unmap(hcd, urb)) {
+		if (hcd->self.uses_dma) {
 			dma_unmap_single(hcd->self.controller,
 					urb->transfer_dma,
 					urb->transfer_buffer_length,
 					dir);
-		else if (hcd->driver->flags & HCD_LOCAL_MEM)
+			if ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
+			    (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+				urb->transfer_dma = ~(dma_addr_t)0;
+		} else if (hcd->driver->flags & HCD_LOCAL_MEM)
 			hcd_free_coherent(urb->dev->bus, &urb->transfer_dma,
 					&urb->transfer_buffer,
 					urb->transfer_buffer_length,
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index bbe2b92..cde42f3 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -183,12 +183,13 @@ struct hc_driver {
 	irqreturn_t	(*irq) (struct usb_hcd *hcd);
 
 	int	flags;
-#define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
-#define	HCD_LOCAL_MEM	0x0002		/* HC needs local memory */
-#define	HCD_USB11	0x0010		/* USB 1.1 */
-#define	HCD_USB2	0x0020		/* USB 2.0 */
-#define	HCD_USB3	0x0040		/* USB 3.0 */
-#define	HCD_MASK	0x0070
+#define	HCD_MEMORY		0x0001	/* HC regs use memory (else I/O) */
+#define	HCD_LOCAL_MEM		0x0002	/* HC needs local memory */
+#define	HCD_NO_COHERENT_MEM	0x0004	/* HC avoids use of "coherent" mem */
+#define	HCD_USB11		0x0010	/* USB 1.1 */
+#define	HCD_USB2		0x0020	/* USB 2.0 */
+#define	HCD_USB3		0x0040	/* USB 3.0 */
+#define	HCD_MASK		0x0070
 
 	/* called to init HCD and root hub */
 	int	(*reset) (struct usb_hcd *hcd);
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH v2 9/9] wii: hollywood ehci controller support
From: Albert Herranz @ 2010-02-28 14:08 UTC (permalink / raw)
  To: linuxppc-dev, linux-arm-kernel, linux-usb; +Cc: Albert Herranz
In-Reply-To: <1267366082-15248-1-git-send-email-albert_herranz@yahoo.es>

Add support for the USB Enhanced Host Controller Interface included
in the "Hollywood" chipset of the Nintendo Wii video game console.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
---
 arch/powerpc/platforms/embedded6xx/Kconfig |    1 +
 drivers/usb/host/Kconfig                   |    8 +
 drivers/usb/host/ehci-hcd.c                |    5 +
 drivers/usb/host/ehci-hlwd.c               |  233 ++++++++++++++++++++++++++++
 drivers/usb/host/ehci.h                    |   23 +++
 5 files changed, 270 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/host/ehci-hlwd.c

diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 4d33755..0eb56a7 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -121,6 +121,7 @@ config WII
 	select GAMECUBE_COMMON
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_DMABOUNCE
+	select USB_ARCH_HAS_EHCI
 	help
 	  Select WII if configuring for the Nintendo Wii.
 	  More information at: <http://gc-linux.sourceforge.net/>
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2678a16..342954f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -131,6 +131,14 @@ config USB_EHCI_HCD_PPC_OF
 	  Enables support for the USB controller present on the PowerPC
 	  OpenFirmware platform bus.
 
+config USB_EHCI_HCD_HLWD
+	bool "Nintendo Wii (Hollywood) EHCI USB controller support"
+	depends on USB_EHCI_HCD && WII
+	default y
+	---help---
+	  Say Y here to support the EHCI USB controller found in the
+	  Hollywood chipset of the Nintendo Wii video game console.
+
 config USB_W90X900_EHCI
 	bool "W90X900(W90P910) EHCI support"
 	depends on USB_EHCI_HCD && ARCH_W90X900
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 1ec3857..395c6a1 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1133,6 +1133,11 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_HCD_HLWD
+#include "ehci-hlwd.c"
+#define OF_PLATFORM_DRIVER	ehci_hcd_hlwd_driver
+#endif
+
 #ifdef CONFIG_XPS_USB_HCD_XILINX
 #include "ehci-xilinx-of.c"
 #define OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
diff --git a/drivers/usb/host/ehci-hlwd.c b/drivers/usb/host/ehci-hlwd.c
new file mode 100644
index 0000000..129e96b
--- /dev/null
+++ b/drivers/usb/host/ehci-hlwd.c
@@ -0,0 +1,233 @@
+/*
+ * drivers/usb/host/ehci-hlwd.c
+ *
+ * Nintendo Wii (Hollywood) USB Enhanced Host Controller Interface.
+ * Copyright (C) 2009-2010 The GameCube Linux Team
+ * Copyright (C) 2009,2010 Albert Herranz
+ *
+ * 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.
+ *
+ * Based on ehci-ppc-of.c
+ *
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for PPC On-Chip EHCI driver on the of_platform bus
+ * Tested on AMCC PPC 440EPx
+ *
+ * Valentine Barshak <vbarshak@ru.mvista.com>
+ *
+ * Based on "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de>
+ * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/signal.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/wii.h>
+
+#define DRV_MODULE_NAME "ehci-hlwd"
+#define DRV_DESCRIPTION "Nintendo Wii EHCI Host Controller"
+#define DRV_AUTHOR      "Albert Herranz"
+
+/*
+ * Non-standard registers.
+ */
+#define HLWD_EHCI_CTL		0x00cc	/* Controller Control */
+#define HLWD_EHCI_CTL_INTE	(1<<15)	/* Notify EHCI interrupts */
+
+/* called during probe() after chip reset completes */
+static int ehci_hlwd_reset(struct usb_hcd *hcd)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	int error;
+
+	dbg_hcs_params(ehci, "reset");
+	dbg_hcc_params(ehci, "reset");
+
+	error = ehci_halt(ehci);
+	if (error)
+		goto out;
+
+	error = ehci_init(hcd);
+	if (error)
+		goto out;
+
+	/* enable notification of EHCI interrupts */
+	setbits32(hcd->regs + HLWD_EHCI_CTL, HLWD_EHCI_CTL_INTE);
+
+	ehci->sbrn = 0x20;
+	error = ehci_reset(ehci);
+	ehci_port_power(ehci, 0);
+out:
+	return error;
+}
+
+static const struct hc_driver ehci_hlwd_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Nintendo Wii EHCI Host Controller",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_USB2 | HCD_NO_COHERENT_MEM,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= ehci_hlwd_reset,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+#ifdef	CONFIG_PM
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+#endif
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+};
+
+static int __devinit
+ehci_hcd_hlwd_probe(struct of_device *op, const struct of_device_id *match)
+{
+	struct device_node *dn = op->node;
+	struct usb_hcd *hcd;
+	struct ehci_hcd	*ehci = NULL;
+	struct resource res;
+	int irq;
+	int error = -ENODEV;
+
+	if (usb_disabled())
+		goto out;
+
+	dev_dbg(&op->dev, "initializing " DRV_MODULE_NAME " USB Controller\n");
+
+	error = of_address_to_resource(dn, 0, &res);
+	if (error)
+		goto out;
+
+	hcd = usb_create_hcd(&ehci_hlwd_hc_driver, &op->dev, DRV_MODULE_NAME);
+	if (!hcd) {
+		error = -ENOMEM;
+		goto out;
+	}
+
+	hcd->rsrc_start = res.start;
+	hcd->rsrc_len = resource_size(&res);
+
+	irq = irq_of_parse_and_map(dn, 0);
+	if (irq == NO_IRQ) {
+		printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+		error = -EBUSY;
+		goto err_irq;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		printk(KERN_ERR __FILE__ ": ioremap failed\n");
+		error = -EBUSY;
+		goto err_ioremap;
+	}
+
+	/* this device requires MEM2 DMA buffers */
+	error = wii_set_mem2_dma_constraints(&op->dev);
+	if (error)
+		goto err_mem2_constraints;
+
+	ehci = hcd_to_ehci(hcd);
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs +
+			HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	error = usb_add_hcd(hcd, irq, 0);
+	if (error == 0)
+		return 0;
+
+err_mem2_constraints:
+	iounmap(hcd->regs);
+err_ioremap:
+	irq_dispose_mapping(irq);
+err_irq:
+	usb_put_hcd(hcd);
+out:
+	return error;
+}
+
+
+static int ehci_hcd_hlwd_remove(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+
+	dev_set_drvdata(&op->dev, NULL);
+
+	dev_dbg(&op->dev, "stopping " DRV_MODULE_NAME " USB Controller\n");
+
+	usb_remove_hcd(hcd);
+	wii_clear_mem2_dma_constraints(&op->dev);
+	iounmap(hcd->regs);
+	irq_dispose_mapping(hcd->irq);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+
+static int ehci_hcd_hlwd_shutdown(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+
+	if (hcd->driver->shutdown)
+		hcd->driver->shutdown(hcd);
+
+	return 0;
+}
+
+
+static struct of_device_id ehci_hcd_hlwd_match[] = {
+	{ .compatible = "nintendo,hollywood-usb-ehci", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ehci_hcd_hlwd_match);
+
+static struct of_platform_driver ehci_hcd_hlwd_driver = {
+	.name		= DRV_MODULE_NAME,
+	.match_table	= ehci_hcd_hlwd_match,
+	.probe		= ehci_hcd_hlwd_probe,
+	.remove		= ehci_hcd_hlwd_remove,
+	.shutdown	= ehci_hcd_hlwd_shutdown,
+	.driver		= {
+		.name	= DRV_MODULE_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2d85e21..8fb519b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -599,6 +599,27 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
 #define ehci_big_endian_mmio(e)		0
 #endif
 
+#ifdef CONFIG_USB_EHCI_HCD_HLWD
+
+/*
+ * The Nintendo Wii video game console has no PCI hardware.
+ * The USB controllers are part of the "Hollywood" chipset and are
+ * accessed via the platform internal I/O accessors.
+ */
+static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
+				      __u32 __iomem *regs)
+{
+	return in_be32(regs);
+}
+
+static inline void ehci_writel(const struct ehci_hcd *ehci,
+			       const unsigned int val, __u32 __iomem *regs)
+{
+	out_be32(regs, val);
+}
+
+#else
+
 /*
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
@@ -632,6 +653,8 @@ static inline void ehci_writel(const struct ehci_hcd *ehci,
 #endif
 }
 
+#endif /* CONFIG_USB_EHCI_HCD_HLWD */
+
 /*
  * On certain ppc-44x SoC there is a HW issue, that could only worked around with
  * explicit suspend/operate of OHCI. This function hereby makes sense only on that arch.
-- 
1.6.3.3

^ permalink raw reply related

* RE: [PATCH 0/3] Rework MPC5121 DIU support (for 2.6.34)
From: sun york-R58495 @ 2010-02-28 14:32 UTC (permalink / raw)
  To: Anatolij Gustschin; +Cc: linux-fbdev, wd, dzu, jrigby, linuxppc-dev

I agree device tree is the right direction to go.=0A=
=0A=
Sent from my Android phone=0A=
----- Original Message -----=0A=
From:"Anatolij Gustschin" <agust@denx.de>=0A=
To:"linuxppc-dev@ozlabs.org" <linuxppc-dev@ozlabs.org>=0A=
Cc:"grant.likely@secretlab.ca" <grant.likely@secretlab.ca>, =
"linux-fbdev@vger.kernel.org" <linux-fbdev@vger.kernel.org>, =
"yorksun@freescale.com" <yorksun@freescale.com>, "dzu@denx.de" =
<dzu@denx.de>, "wd@denx.de" <wd@denx.de>, "jrigby@gmail.com" =
<jrigby@gmail.com>, "Anatolij Gustschin" <agust@denx.de>=0A=
Sent:02-27-2010 16:00=0A=
Subject:[PATCH 0/3] Rework MPC5121 DIU support (for 2.6.34)=0A=
=0A=
=0A=
This patch series rework DIU support patch submitted
previously with the patch series for updating MPC5121
support in mainline. It doesn't add new panel timing data
to the framebuffer driver anymore. Instead we now allow
encoding this data in the device tree. First two patches
add this support.

The third patch for DIU support is rebased, but still
depends on patches for adding MPC5121 USB support (because
it touches shared platform code).

It is intended for inclusion in 2.6.34, since without
DIU support patch framebuffer doesn't work on mpc5121.

Anatolij Gustschin (3):
  video: add support for getting video mode from device tree
  fbdev: fsl-diu-fb.c: allow setting panel video mode from DT
  powerpc/mpc5121: shared DIU framebuffer support

 arch/powerpc/platforms/512x/mpc5121_ads.c     |    7 +
 arch/powerpc/platforms/512x/mpc5121_generic.c |   13 ++
 arch/powerpc/platforms/512x/mpc512x.h         |    3 +
 arch/powerpc/platforms/512x/mpc512x_shared.c  |  282 =
+++++++++++++++++++++++++
 arch/powerpc/sysdev/fsl_soc.h                 |    1 +
 drivers/video/Kconfig                         |    6 +
 drivers/video/Makefile                        |    1 +
 drivers/video/fsl-diu-fb.c                    |   88 +++++---
 drivers/video/fsl-diu-fb.h                    |  223 =
-------------------
 drivers/video/ofmode.c                        |   95 +++++++++
 drivers/video/ofmode.h                        |    6 +
 include/linux/fsl-diu-fb.h                    |  223 =
+++++++++++++++++++
 12 files changed, 693 insertions(+), 255 deletions(-)
 delete mode 100644 drivers/video/fsl-diu-fb.h
 create mode 100644 drivers/video/ofmode.c
 create mode 100644 drivers/video/ofmode.h
 create mode 100644 include/linux/fsl-diu-fb.h

^ permalink raw reply

* Re: [RFC PATCH v2 4/9] add generic dmabounce support
From: Russell King - ARM Linux @ 2010-02-28 14:20 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1267366082-15248-5-git-send-email-albert_herranz@yahoo.es>

On Sun, Feb 28, 2010 at 03:07:57PM +0100, Albert Herranz wrote:
> This patch makes part of the ARM dmabounce code available to other
> architectures as a generic API.

There is already a generic dma bounce implementation - it's called
swiotlb - lib/swiotlb.c.  We should eventually switch the ARM
dmabounce stuff over to that instead of keeping dmabounce around.

The only problem I forsee is that on ARM, we have devices which can
only address the least significant N bits of RAM, but there may be
an offset on the base address of RAM on the bus which isn't included
in these N bits.

Even more fun is where we have a DMA controller which can address
N bits of RAM, except for bit M which must be zero... (where N > M).

^ permalink raw reply

* Re: [PATCH 1/3] video: add support for getting video mode from device tree
From: Grant Likely @ 2010-02-28 14:47 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: linux-fbdev, wd, dzu, jrigby, devicetree-discuss, linuxppc-dev,
	Anatolij Gustschin, yorksun
In-Reply-To: <4B8A2CD7.7070305@firmworks.com>

On Sun, Feb 28, 2010 at 1:44 AM, Mitch Bradley <wmb@firmworks.com> wrote:
> Grant Likely Wrote:
>> On Sat, Feb 27, 2010 at 2:58 PM, Anatolij Gustschin <agust@denx.de> wrot=
e:
>> Also, since you're now in the realm of describing a video display,
>> which is separate from the display controller, you should consider
>> describing the display in a separate device tree node. =A0Maybe
>> something like this...
>>
>> video {
>> =A0 =A0 =A0 =A0compatible =3D "fsl,mpc5121-diu";
>> =A0 =A0 =A0 =A0display {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0compatible =3D "<vendor>,<model>";
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0edid =3D [edid-data];
>> =A0 =A0 =A0 =A0};
>> };
>>
>
>
> As it turns out, I'm doing exactly that - exporting verbatim EDID data as
> the value of the "edid" property - for the display node on the Via versio=
n
> of the OLPC machine. =A0The kernel driver uses it instead of trying to ob=
tain
> the EDID data from the monitor, because the builtin OLPC display cannot
> supply EDID data through the usual hardware interfaces.

Cool.  That sounds sane then.  How do you go about generating the EDID
data?  Is there a tool that can do that?  Or did you hand craft it?

Cheers,
g.

^ permalink raw reply

* Re: [RFC PATCH v2 4/9] add generic dmabounce support
From: Albert Herranz @ 2010-02-28 16:37 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20100228142046.GA16745@n2100.arm.linux.org.uk>

Russell King - ARM Linux wrote:
> On Sun, Feb 28, 2010 at 03:07:57PM +0100, Albert Herranz wrote:
>> This patch makes part of the ARM dmabounce code available to other
>> architectures as a generic API.
> 
> There is already a generic dma bounce implementation - it's called
> swiotlb - lib/swiotlb.c.  We should eventually switch the ARM
> dmabounce stuff over to that instead of keeping dmabounce around.
> 
> The only problem I forsee is that on ARM, we have devices which can
> only address the least significant N bits of RAM, but there may be
> an offset on the base address of RAM on the bus which isn't included
> in these N bits.
> 
> Even more fun is where we have a DMA controller which can address
> N bits of RAM, except for bit M which must be zero... (where N > M).
> 

In the Wii we have several limitations:
- it is a NOT_COHERENT_CACHE platform
- write accesses to coherent memory from the main processor must be done always in 32-bit chunks
- some devices can only reliably perform DMA to/from a specific region of memory (the second block of RAM, 64MB at 0x10000000, called MEM2)

So if swiotlb is the way to go I can try to adapt it to take into account these cases:
- it should allocate the io_tlb_start and io_tlb_overflow_buffer areas from MEM2 (add allocation/freeing hooks for these areas?)
- it should copy data from coherent memory in 32-bit chunks (add copy to/from coherent hooks?)
- it should decide to bounce buffers sitting in MEM1 (add a dma_needs_bounce() hook?)

Thanks,
Albert

^ permalink raw reply

* [PATCH] fix PHY polling system blocking
From: Stefani Seibold @ 2010-02-28 22:39 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, Thomas Gleixner

This patch fix the PHY poller, which can block the whole system. On a
Freescale PPC 834x this result in a delay of 450 us due the slow
communication with the PHY chip.

For PHY chips without interrupts, the status of the ethernet will be
polled every 2 sec. The poll function will read some register of the MII
PHY. The time between the sending the MII_READ_COMMAND and receiving the
result is more the 100 us on a PPC 834x.
   
The patch modifies the poller a lit bit. Only a link status state change
will result in a successive detection of the connection type. The poll
cycle on the other hand will be increased to every seconds.

Together this patch will prevent a blocking of nearly 400 us every two
seconds of the whole system on a PPC 834x.

The patch is against kernel 2.6.33. Please merge it.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 phy.c        |    5 ++---
 phy_device.c |   12 +++++++++---
 2 files changed, 11 insertions(+), 6 deletions(-)

diff -u -N -r -p linux-2.6.33.orig/drivers/net/phy/phy.c linux-2.6.33/drivers/net//phy/phy.c
--- linux-2.6.33.orig/drivers/net/phy/phy.c	2010-02-24 19:52:17.000000000 +0100
+++ linux-2.6.33/drivers/net//phy/phy.c	2010-02-28 22:53:14.725464101 +0100
@@ -871,9 +871,8 @@ void phy_state_machine(struct work_struc
 		case PHY_RUNNING:
 			/* Only register a CHANGE if we are
 			 * polling */
-			if (PHY_POLL == phydev->irq)
-				phydev->state = PHY_CHANGELINK;
-			break;
+			if (PHY_POLL != phydev->irq)
+				break;
 		case PHY_CHANGELINK:
 			err = phy_read_status(phydev);
 
diff -u -N -r -p linux-2.6.33.orig/drivers/net/phy/phy_device.c linux-2.6.33/drivers/net//phy/phy_device.c
--- linux-2.6.33.orig/drivers/net/phy/phy_device.c	2010-02-24 19:52:17.000000000 +0100
+++ linux-2.6.33/drivers/net//phy/phy_device.c	2010-02-28 22:53:14.726464145 +0100
@@ -161,7 +161,7 @@ struct phy_device* phy_device_create(str
 	dev->speed = 0;
 	dev->duplex = -1;
 	dev->pause = dev->asym_pause = 0;
-	dev->link = 1;
+	dev->link = 0;
 	dev->interface = PHY_INTERFACE_MODE_GMII;
 
 	dev->autoneg = AUTONEG_ENABLE;
@@ -694,10 +694,16 @@ int genphy_update_link(struct phy_device
 	if (status < 0)
 		return status;
 
-	if ((status & BMSR_LSTATUS) == 0)
+	if ((status & BMSR_LSTATUS) == 0) {
+		if (phydev->link==0)
+			return 1;
 		phydev->link = 0;
-	else
+	}
+	else {
+		if (phydev->link==1)
+			return 1;
 		phydev->link = 1;
+	}
 
 	return 0;
 }

^ permalink raw reply

* Re: [PATCH 1/3] video: add support for getting video mode from device tree
From: Benjamin Herrenschmidt @ 2010-03-01  3:45 UTC (permalink / raw)
  To: Mitch Bradley
  Cc: linux-fbdev, wd, dzu, jrigby, devicetree-discuss, linuxppc-dev,
	Anatolij Gustschin, yorksun
In-Reply-To: <4B8A2CD7.7070305@firmworks.com>

At some stage, Grant wrote:

> > First off, I did a tiny amount of research, and I didn't find any
> > existing OpenFirmware bindings for describing video displays.
> > Otherwise, I'd suggest considering that.

There's a binding for framebuffers but it sucks big time :-) It doesn't
provide a reliable way for the OS to get to the physical address of the
fb, doesn't define outputs and mode setting, doesn't really deal with
>8bpp, etc....

On Sat, 2010-02-27 at 22:44 -1000, Mitch Bradley wrote:

> As it turns out, I'm doing exactly that - exporting verbatim EDID
> data 
> as the value of the "edid" property - for the display node on the Via 
> version of the OLPC machine.  The kernel driver uses it instead of 
> trying to obtain the EDID data from the monitor, because the builtin 
> OLPC display cannot supply EDID data through the usual hardware
> interfaces.

This is actually a common practice (though EDID is most often in
uppercase) on Apple hardware too. It has issues though in the sense that
it doesn't carry proper connector information and falls over in many
multi-head cases.

I think passing the EDID data, when available, is thus the right thing
to do indeed, however that doesn't solve two problems:

 - Where to put that property ? This is a complicated problem and we
might argue on a binding for weeks because video cards typically support
multiple outputs, etc. etc... I think the best for now is to stick as
closely as possible to the existing OF fb binding, and have "display"
nodes for each output, which can eventually contain an EDID. We might
also want to add a string that indicate the connector type. Specific
drivers might want to define additional properties here where it makes
sense such as binding of those outputs to CRTCs or such, up to you.

 - We -also- want a way to specify the "default" mode as set by the
firmware, at least on some devices. The EDID gives capabilities, and
often for LCDs also the "preferred" mode which is almost always the
"default" mode ... but could be different. In order to avoid "flicking",
the driver might wants to know what is the currently programmed mode.
For that, having split out properties makes sense, though I would like
to either prefix them all with "mode," or stick them in a sub-node of
the display@.

Cheers,
Ben.

^ permalink raw reply

* Re: [async_tx-next PATCH v2 2/2] fsldma: Fix cookie issues
From: Dan Williams @ 2010-03-01  5:14 UTC (permalink / raw)
  To: Steven J. Magnani; +Cc: Zhang Wei, Ira W. Snyder, linux-kernel, linuxppc-dev
In-Reply-To: <1267126777-21520-1-git-send-email-steve@digidescorp.com>

On Thu, Feb 25, 2010 at 12:39 PM, Steven J. Magnani
<steve@digidescorp.com> wrote:
> fsl_dma_update_completed_cookie() appears to calculate the last completed
> cookie incorrectly in the corner case where DMA on cookie 1 is in progres=
s
> just following a cookie wrap.
>
> Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
> ---
> diff -uprN a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
> --- a/drivers/dma/fsldma.c =A0 =A0 =A02010-02-22 11:16:36.000000000 -0600
> +++ b/drivers/dma/fsldma.c =A0 =A0 =A02010-02-22 11:08:41.000000000 -0600
> @@ -819,8 +819,11 @@ static void fsl_dma_update_completed_coo
> =A0 =A0 =A0 =A0desc =3D to_fsl_desc(chan->ld_running.prev);
> =A0 =A0 =A0 =A0if (dma_is_idle(chan))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cookie =3D desc->async_tx.cookie;
> - =A0 =A0 =A0 else
> + =A0 =A0 =A0 else {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cookie =3D desc->async_tx.cookie - 1;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (unlikely(cookie < DMA_MIN_COOKIE))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 cookie =3D DMA_MAX_COOKIE;
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0chan->completed_cookie =3D cookie;
>
> diff -uprN a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> --- a/include/linux/dmaengine.h 2010-02-22 11:18:11.000000000 -0600
> +++ b/include/linux/dmaengine.h 2010-02-22 11:18:30.000000000 -0600
> @@ -31,6 +31,8 @@
> =A0* if dma_cookie_t is >0 it's a DMA request cookie, <0 it's an error co=
de
> =A0*/
> =A0typedef s32 dma_cookie_t;
> +#define DMA_MIN_COOKIE 1
> +#define DMA_MAX_COOKIE ((1 << 31) - 1)
>

This patch introduces a new warning::

drivers/dma/fsldma.c:825: warning: integer overflow in expression

I'll fix this up to use INT_MAX instead.

--
Dan

powerpc-linux-gnu-gcc --version
powerpc-linux-gnu-gcc (Sourcery G++ Lite 4.2-50) 4.2.1

^ permalink raw reply

* Re: [PATCH] powerpc: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
From: Mel Gorman @ 2010-03-01 12:06 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: cl, linuxppc-dev
In-Reply-To: <20100223015551.GG31681@kryten>

On Tue, Feb 23, 2010 at 12:55:51PM +1100, Anton Blanchard wrote:
>  
> Hi Mel,
> 

I'm back but a bit vague. Am on painkillers for the bashing I gave
myself down the hills.

> > You're pretty much on the button here. Only one thread at a time enters
> > zone_reclaim. The others back off and try the next zone in the zonelist
> > instead. I'm not sure what the original intention was but most likely it
> > was to prevent too many parallel reclaimers in the same zone potentially
> > dumping out way more data than necessary.
> > 
> > > I'm not sure if there is an easy way to fix this without penalising other
> > > workloads though.
> > > 
> > 
> > You could experiment with waiting on the bit if the GFP flags allowi it? The
> > expectation would be that the reclaim operation does not take long. Wait
> > on the bit, if you are making the forward progress, recheck the
> > watermarks before continueing.
> 
> Thanks to you and Christoph for some suggestions to try. Attached is a
> chart showing the results of the following tests:
> 
> 
> baseline.txt
> The current ppc64 default of zone_reclaim_mode = 0. As expected we see
> no change in remote node memory usage even after 10 iterations.
> 
> zone_reclaim_mode.txt
> Now we set zone_reclaim_mode = 1. On each iteration we continue to improve,
> but even after 10 runs of stream we have > 10% remote node memory usage.
> 

Ok, so how reasonable would it be to expect that the rate of "improvement"
to be related to the ratio between "available free node memory at start -
how many pages the benchmark requires" and the number of pages zone_reclaim
reclaims on the local node?

The exact rate of improvement is complicated by multiple threads so it
won't be exact.

> reclaim_4096_pages.txt
> Instead of reclaiming 32 pages at a time, we try for a much larger batch
> of 4096. The slope is much steeper but it still takes around 6 iterations
> to get almost all local node memory.
> 
> wait_on_busy_flag.txt
> Here we busy wait if the ZONE_RECLAIM_LOCKED flag is set. As you suggest
> we would need to check the GFP flags etc, but so far it looks the most
> promising. We only get a few percent of remote node memory on the first
> iteration and get all local node by the second.
> 

If the above expectation is reasonable, a better alternative may be to adapt
the number of pages reclaimed to the number of callers to
__zone_reclaim() and allow parallel reclaimers.

e.g. 
	1 thread	 128
	2 threads	  64
	3 threads	  32
	4 threads	  16
etc

The exact starting batch count needs more careful thinking than what I'm
giving it currently and maybe the decay ratio too to work out what the
worst-case scenario for dumping node-local memory is but you get the idea.

The downside is that this requires a per-zone counter to count the
number of parallel reclaimers.

> 
> Perhaps a combination of larger batch size and waiting on the busy
> flag is the way to go?
> 

I think a static increase on the batch size runs three risks. The first of
parallel reclaimers dumping too much of local memory although it could be
mitigated by checking the watermarks after waiting on the bit lock. The
second is that the thread doing the reclaiming is penalised with higher
reclaim costs while other CPUs remain idle. The third is that there
could be latency snags with a thread spinning that would previously have
gone off-node.

Not sure what the impact of the third risk but it might be noticeable on
latency-sensitive machines where the off-node cost is not significant
enough to justify a delay.

Christoph, how feasible would it be to allow parallel reclaimers in
__zone_reclaim() that back off at a rate depending on the number of
reclaimers?

> --- mm/vmscan.c~	2010-02-21 23:47:14.000000000 -0600
> +++ mm/vmscan.c	2010-02-22 03:22:01.000000000 -0600
> @@ -2534,7 +2534,7 @@
>  		.may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP),
>  		.may_swap = 1,
>  		.nr_to_reclaim = max_t(unsigned long, nr_pages,
> -				       SWAP_CLUSTER_MAX),
> +				       4096),
>  		.gfp_mask = gfp_mask,
>  		.swappiness = vm_swappiness,
>  		.order = order,

> --- mm/vmscan.c~	2010-02-21 23:47:14.000000000 -0600
> +++ mm/vmscan.c	2010-02-21 23:47:31.000000000 -0600
> @@ -2634,8 +2634,8 @@
>  	if (node_state(node_id, N_CPU) && node_id != numa_node_id())
>  		return ZONE_RECLAIM_NOSCAN;
>  
> -	if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
> -		return ZONE_RECLAIM_NOSCAN;
> +	while (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
> +		cpu_relax();
>  
>  	ret = __zone_reclaim(zone, gfp_mask, order);
>  	zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);


-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* [RFC: PATCH 04/13] powerpc/476: add machine check handler for 47x core
From: Dave Kleikamp @ 2010-03-01 12:13 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: Torez Smith
In-Reply-To: <20100301191255.20987.84668.sendpatchset@norville.austin.ibm.com>

powerpc/476: add machine check handler for 47x core

From: Dave Kleikamp <shaggy@linux.vnet.ibm.com>

The 47x core's MCSR varies from 44x, so it needs it's own machine check
handler.

Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
---

 arch/powerpc/include/asm/cputable.h  |    1 +
 arch/powerpc/include/asm/reg_booke.h |    2 +-
 arch/powerpc/kernel/cputable.c       |    1 +
 arch/powerpc/kernel/traps.c          |   38 ++++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 1 deletions(-)


diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 75b774e..9fff628 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -72,6 +72,7 @@ extern int machine_check_4xx(struct pt_regs *regs);
 extern int machine_check_440A(struct pt_regs *regs);
 extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
+extern int machine_check_47x(struct pt_regs *regs);
 
 /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
 struct cpu_spec {
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index ee61a9d..a9245b9 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -194,7 +194,7 @@
 #ifdef CONFIG_PPC_47x
 #define PPC47x_MCSR_GPR	0x01000000 /* GPR parity error */
 #define PPC47x_MCSR_FPR	0x00800000 /* FPR parity error */
-#define PPC47x_MCSR_IPR	0x00400000 /* Imprecise Machine Check Exception */
+#define PPC47x_MCSR_IMP	0x00400000 /* Imprecise Machine Check Exception */
 #endif
 
 #ifdef CONFIG_E500
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 338ac47..7b2a67c 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1712,6 +1712,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 			MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 128,
+		.machine_check		= machine_check_47x,
 		.platform		= "ppc470",
 	},
 	{	/* default match */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d069ff8..66617b6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs)
 	}
 	return 0;
 }
+
+int machine_check_47x(struct pt_regs *regs)
+{
+	unsigned long reason = get_mc_reason(regs);
+
+	printk("Machine check in kernel mode.\n");
+	if (reason & ESR_IMCP){
+		printk("Instruction Synchronous Machine Check exception\n");
+		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+	}
+	else {
+		u32 mcsr = mfspr(SPRN_MCSR);
+		if (mcsr & MCSR_IB)
+			printk("Instruction Read PLB Error\n");
+		if (mcsr & MCSR_DRB)
+			printk("Data Read PLB Error\n");
+		if (mcsr & MCSR_DWB)
+			printk("Data Write PLB Error\n");
+		if (mcsr & MCSR_TLBP)
+			printk("TLB Parity Error\n");
+		if (mcsr & MCSR_ICP){
+			flush_instruction_cache();
+			printk("I-Cache Parity Error\n");
+		}
+		if (mcsr & MCSR_DCSP)
+			printk("D-Cache Search Parity Error\n");
+		if (mcsr & PPC47x_MCSR_GPR)
+			printk("GPR Parity Error\n");
+		if (mcsr & PPC47x_MCSR_FPR)
+			printk("FPR Parity Error\n");
+		if (mcsr & PPC47x_MCSR_IMP)
+			printk("Machine Check exception is imprecise\n");
+
+		/* Clear MCSR */
+		mtspr(SPRN_MCSR, mcsr);
+	}
+	return 0;
+}
 #elif defined(CONFIG_E500)
 int machine_check_e500(struct pt_regs *regs)
 {

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply related

* [PATCH v2 0/3] powerpc: bug fixes in pseries_mach_cpu_die()
From: Vaidyanathan Srinivasan @ 2010-03-01 12:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Anton Blanchard; +Cc: linuxppc-dev, Gautham R Shenoy

Hi Ben,

The following set of patches fixes kernel stack reset issue and also
potential race conditions.

This fix should be applied in 2.6.33 stable tree onwards.

Problem description:

(1) Repeated offline/online operation on pseries with extended cede
processor feature will run over the kernel stack and crash since the
stack was not reset on resume from cede processor.

(2) The 'if' conditions and code has been slightly rearranged to avoid
any possible race conditions where preferred_offline_state can change
while the cpu is still executing the condition checks in
pseries_mach_cpu_die().  The new code has the CPU_STATE_OFFLINE as
default and also improved readability.  Thanks to Anton Blanchard for
pointing this out.

(3) There were too many noisy KERN_INFO printks on offline/online
operation.  Removed the printk's for now.  Other debug methods or
traceevents can be introduced at a later point.

The patch has been tested on large POWER machine with both
cede_offline=off case and the default cede_offline=on case.

Please apply in powerpc.git tree and push upstream.

Previous version of the patch can be found at:

[PATCH] powerpc: reset kernel stack on cpu online from cede state
http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-February/080515.html

Thanks,
Vaidy

---

Vaidyanathan Srinivasan (3):
      powerpc: reset kernel stack on cpu online from cede state
      powerpc: move checks in pseries_mach_cpu_die()
      powerpc: reduce printk from pseries_mach_cpu_die()


 arch/powerpc/kernel/head_64.S                   |   11 ++++++
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |   42 ++++++++---------------
 arch/powerpc/platforms/pseries/offline_states.h |    2 +
 3 files changed, 27 insertions(+), 28 deletions(-)

^ permalink raw reply

* [PATCH v2 1/3] powerpc: reset kernel stack on cpu online from cede state
From: Vaidyanathan Srinivasan @ 2010-03-01 12:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Anton Blanchard; +Cc: linuxppc-dev, Gautham R Shenoy
In-Reply-To: <20100301123519.26066.8639.stgit@drishya.in.ibm.com>

	Cpu hotplug (offline) without dlpar operation will place cpu
	in cede state and the extended_cede_processor() function will
	return when resumed.

	Kernel stack pointer needs to be reset before
	start_secondary() is called to continue the online operation.

	Added new function start_secondary_resume() to do the above
	steps.

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
---
 arch/powerpc/kernel/head_64.S                   |   11 +++++++++++
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |    9 ++++-----
 arch/powerpc/platforms/pseries/offline_states.h |    2 +-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 9258074..567cd57 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -615,6 +615,17 @@ _GLOBAL(start_secondary_prolog)
 	std	r3,0(r1)		/* Zero the stack frame pointer	*/
 	bl	.start_secondary
 	b	.
+/*
+ * Reset stack pointer and call start_secondary
+ * to continue with online operation when woken up
+ * from cede in cpu offline.
+ */
+_GLOBAL(start_secondary_resume)
+	ld	r1,PACAKSAVE(r13)	/* Reload kernel stack pointer */
+	li	r3,0
+	std	r3,0(r1)		/* Zero the stack frame pointer	*/
+	bl	.start_secondary
+	b	.
 #endif
 
 /*
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 6ea4698..9be7af4 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -146,12 +146,11 @@ static void pseries_mach_cpu_die(void)
 		unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
 
 		/*
-		 * NOTE: Calling start_secondary() here for now to
-		 * start new context.
-		 * However, need to do it cleanly by resetting the
-		 * stack pointer.
+		 * Call to start_secondary_resume() will not return.
+		 * Kernel stack will be reset and start_secondary()
+		 * will be called to continue the online operation.
 		 */
-		start_secondary();
+		start_secondary_resume();
 
 	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
 
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 22574e0..da07256 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -14,5 +14,5 @@ extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
 extern enum cpu_state_vals get_preferred_offline_state(int cpu);
 extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
 extern void set_default_offline_state(int cpu);
-extern int start_secondary(void);
+extern void start_secondary_resume(void);
 #endif

^ permalink raw reply related

* [PATCH v2 2/3] powerpc: move checks in pseries_mach_cpu_die()
From: Vaidyanathan Srinivasan @ 2010-03-01 12:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Anton Blanchard; +Cc: linuxppc-dev, Gautham R Shenoy
In-Reply-To: <20100301123519.26066.8639.stgit@drishya.in.ibm.com>

	Rearrange condition checks for better code readability and
	prevention of possible race conditions when
	preferred_offline_state can potentially change during the
	execution of pseries_mach_cpu_die().  The patch will make
	pseries_mach_cpu_die() put cpu in one of the consistent states
	and not hit the run over BUG()

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c |   30 +++++++++++++-------------
 1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 9be7af4..39ecb40 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -140,25 +140,25 @@ static void pseries_mach_cpu_die(void)
 		if (!get_lppaca()->shared_proc)
 			get_lppaca()->donate_dedicated_cpu = 0;
 		get_lppaca()->idle = 0;
-	}
 
-	if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
-		unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+		if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+			unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
 
-		/*
-		 * Call to start_secondary_resume() will not return.
-		 * Kernel stack will be reset and start_secondary()
-		 * will be called to continue the online operation.
-		 */
-		start_secondary_resume();
+			/*
+			 * Call to start_secondary_resume() will not return.
+			 * Kernel stack will be reset and start_secondary()
+			 * will be called to continue the online operation.
+			 */
+			start_secondary_resume();
+		}
+	}
 
-	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+	/* Requested state is CPU_STATE_OFFLINE at this point */
+	WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
 
-		set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
-		unregister_slb_shadow(hard_smp_processor_id(),
-					__pa(get_slb_shadow()));
-		rtas_stop_self();
-	}
+	set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+	unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+	rtas_stop_self();
 
 	/* Should never get here... */
 	BUG();

^ permalink raw reply related

* [PATCH v2 3/3] powerpc: reduce printk from pseries_mach_cpu_die()
From: Vaidyanathan Srinivasan @ 2010-03-01 12:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Anton Blanchard; +Cc: linuxppc-dev, Gautham R Shenoy
In-Reply-To: <20100301123519.26066.8639.stgit@drishya.in.ibm.com>

	Remove debug printks in pseries_mach_cpu_die().  These are
	noisy at runtime.  Traceevents can be added to instrument this
	section of code.

	The following KERN_INFO printks are removed:

	cpu 62 (hwid 62) returned from cede.
	Decrementer value = b2802fff Timebase value = 2fa8f95035f4a
	cpu 62 (hwid 62) got prodded to go online
	cpu 58 (hwid 58) ceding for offline with hint 2

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Cc: Gautham R Shenoy <ego@in.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c |   11 -----------
 1 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 39ecb40..b842378 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -122,21 +122,10 @@ static void pseries_mach_cpu_die(void)
 		if (!get_lppaca()->shared_proc)
 			get_lppaca()->donate_dedicated_cpu = 1;
 
-		printk(KERN_INFO
-			"cpu %u (hwid %u) ceding for offline with hint %d\n",
-			cpu, hwcpu, cede_latency_hint);
 		while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
 			extended_cede_processor(cede_latency_hint);
-			printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
-				cpu, hwcpu);
-			printk(KERN_INFO
-			"Decrementer value = %x Timebase value = %llx\n",
-			get_dec(), get_tb());
 		}
 
-		printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
-			cpu, hwcpu);
-
 		if (!get_lppaca()->shared_proc)
 			get_lppaca()->donate_dedicated_cpu = 0;
 		get_lppaca()->idle = 0;

^ permalink raw reply related

* Re: Gianfar driver failing on MPC8641D based board
From: Martyn Welch @ 2010-03-01 13:07 UTC (permalink / raw)
  To: linuxppc-dev list
  Cc: Paul Gortmaker, davem, Sandeep Gopalpet, linux-kernel, netdev
In-Reply-To: <20100226213825.GA32363@oksana.dev.rtsoft.ru>

Anton Vorontsov wrote:
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index 8bd3c9f..cccb409 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  	}
>  
>  	/* setup the TxBD length and buffer pointer for the first BD */
> -	tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
>  	txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
>  			skb_headlen(skb), DMA_TO_DEVICE);
>  
> @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  	txbdp_start->lstatus = lstatus;
>  
> +	eieio(); /* force lstatus write before tx_skbuff */
> +
> +	tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
> +
>  	/* Update the current skb pointer to the next entry we will use
>  	 * (wrapping if necessary) */
>  	tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
>   
I can confirm 10/10 successful boots on p2020ds and mpc8641_hpcn.

Martyn


-- 
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply

* Re: [PATCH v3 06/11] dma: Add MPC512x DMA driver
From: Anatolij Gustschin @ 2010-03-01 13:46 UTC (permalink / raw)
  To: Dan Williams; +Cc: wd, dzu, linuxppc-dev, Piotr Ziecik
In-Reply-To: <1265377377-29327-7-git-send-email-agust@denx.de>

Hi Dan,

any chance this patch could be merged for 2.6.34 ?

Thanks,
Anatolij

On Fri,  5 Feb 2010 14:42:52 +0100
Anatolij Gustschin <agust@denx.de> wrote:

> From: Piotr Ziecik <kosmo@semihalf.com>
> 
> Adds initial version of MPC512x DMA driver.
> Only memory to memory transfers are currenly supported.
> 
> Signed-off-by: Piotr Ziecik <kosmo@semihalf.com>
> Signed-off-by: Wolfgang Denk <wd@denx.de>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: John Rigby <jcrigby@gmail.com>
> ---
> No changes since v2
> 
> Changes since v1:
>  - move content of the mpc512x.h into the drivers .c file as
>    it is only used by this DMA driver
>  - use __devinit/__devexit/__devexit_p as requested
>  - add unregistration of the dma device
>  - remove meaningless comment
> 
> Changes since patch version submitted in May 2009:
>  - don't use wildcards in compatible property, use "fsl,mpc5121-dma"
>  - don't add "fsl,mpc5121-dma" compatible to of_bus_ids[] as the
>    dma device is part of IMMR
> 
>  drivers/dma/Kconfig       |    7 +
>  drivers/dma/Makefile      |    1 +
>  drivers/dma/mpc512x_dma.c |  800 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 808 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/dma/mpc512x_dma.c

^ permalink raw reply

* [PATCH] powerpc: Renaming following split of GE Fanuc joint venture
From: Martyn Welch @ 2010-03-01 14:41 UTC (permalink / raw)
  To: kumar.gala; +Cc: linuxppc-dev

This patch renames GE Fanuc boards following the split-up of the GE Fanuc joint venture. These boards are now made by GE Intelligent platorms.

Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com>
---

 arch/powerpc/boot/dts/gef_ppc9a.dts      |    4 ++--
 arch/powerpc/boot/dts/gef_sbc310.dts     |    4 ++--
 arch/powerpc/boot/dts/gef_sbc610.dts     |    4 ++--
 arch/powerpc/platforms/86xx/Kconfig      |   12 ++++++------
 arch/powerpc/platforms/86xx/gef_gpio.c   |   10 +++++-----
 arch/powerpc/platforms/86xx/gef_pic.c    |    6 +++---
 arch/powerpc/platforms/86xx/gef_ppc9a.c  |   12 ++++++------
 arch/powerpc/platforms/86xx/gef_sbc310.c |   12 ++++++------
 arch/powerpc/platforms/86xx/gef_sbc610.c |   12 ++++++------
 9 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
index 977f260..83f4b79 100644
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc PPC9A Device Tree Source
+ * GE PPC9A Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index 8e4efff..fc3a331 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc SBC310 Device Tree Source
+ * GE SBC310 Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index bb70600..c0671cc 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -1,7 +1,7 @@
 /*
- * GE Fanuc SBC610 Device Tree Source
+ * GE SBC610 Device Tree Source
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 2bbfd53..fbe9f36 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -33,32 +33,32 @@ config MPC8610_HPCD
 	  This option enables support for the MPC8610 HPCD board.
 
 config GEF_PPC9A
-	bool "GE Fanuc PPC9A"
+	bool "GE PPC9A"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
-	  This option enables support for GE Fanuc's PPC9A.
+	  This option enables support for the GE PPC9A.
 
 config GEF_SBC310
-	bool "GE Fanuc SBC310"
+	bool "GE SBC310"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
-	  This option enables support for GE Fanuc's SBC310.
+	  This option enables support for the GE SBC310.
 
 config GEF_SBC610
-	bool "GE Fanuc SBC610"
+	bool "GE SBC610"
 	select DEFAULT_UIMAGE
 	select MMIO_NVRAM
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	select HAS_RAPIDIO
 	help
-	  This option enables support for GE Fanuc's SBC610.
+	  This option enables support for the GE SBC610.
 
 endif
 
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c
index b2ea887..11f7b2b 100644
--- a/arch/powerpc/platforms/86xx/gef_gpio.c
+++ b/arch/powerpc/platforms/86xx/gef_gpio.c
@@ -1,9 +1,9 @@
 /*
- * Driver for GE Fanuc's FPGA based GPIO pins
+ * Driver for GE FPGA based GPIO
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
@@ -164,6 +164,6 @@ static int __init gef_gpio_init(void)
 };
 arch_initcall(gef_gpio_init);
 
-MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
 MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0110a87..c92d5fb 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -1,9 +1,9 @@
 /*
- * Interrupt handling for GE Fanuc's FPGA based PIC
+ * Interrupt handling for GE FPGA based PIC
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index a792e5d..60ce07e 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc PPC9A board support
+ * GE PPC9A board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_ppc9a_setup_arch(void)
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -151,7 +151,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 
 	seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
 		('A' + gef_ppc9a_get_board_rev()));
@@ -235,7 +235,7 @@ static int __init declare_of_platform_devices(void)
 machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
 
 define_machine(gef_ppc9a) {
-	.name			= "GE Fanuc PPC9A",
+	.name			= "GE PPC9A",
 	.probe			= gef_ppc9a_probe,
 	.setup_arch		= gef_ppc9a_setup_arch,
 	.init_IRQ		= gef_ppc9a_init_irq,
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index 6a1a613..3ecee25 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc SBC310 board support
+ * GE SBC310 board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_sbc310_setup_arch(void)
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -142,7 +142,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m)
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 
 	seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id());
 	seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(),
@@ -223,7 +223,7 @@ static int __init declare_of_platform_devices(void)
 machine_device_initcall(gef_sbc310, declare_of_platform_devices);
 
 define_machine(gef_sbc310) {
-	.name			= "GE Fanuc SBC310",
+	.name			= "GE SBC310",
 	.probe			= gef_sbc310_probe,
 	.setup_arch		= gef_sbc310_setup_arch,
 	.init_IRQ		= gef_sbc310_init_irq,
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index e10688a..5090d60 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -1,9 +1,9 @@
 /*
- * GE Fanuc SBC610 board support
+ * GE SBC610 board support
  *
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
  *
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -82,7 +82,7 @@ static void __init gef_sbc610_setup_arch(void)
 	}
 #endif
 
-	printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n");
+	printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n");
 
 #ifdef CONFIG_SMP
 	mpc86xx_smp_init();
@@ -133,7 +133,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m)
 {
 	uint svid = mfspr(SPRN_SVR);
 
-	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 
 	seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
 		('A' + gef_sbc610_get_board_rev() - 1));
@@ -212,7 +212,7 @@ static int __init declare_of_platform_devices(void)
 machine_device_initcall(gef_sbc610, declare_of_platform_devices);
 
 define_machine(gef_sbc610) {
-	.name			= "GE Fanuc SBC610",
+	.name			= "GE SBC610",
 	.probe			= gef_sbc610_probe,
 	.setup_arch		= gef_sbc610_setup_arch,
 	.init_IRQ		= gef_sbc610_init_irq,


--
Martyn Welch (Principal Software Engineer)   |   Registered in England and
GE Intelligent Platforms                     |   Wales (3828642) at 100
T +44(0)127322748                            |   Barbirolli Square, Manchester,
E martyn.welch@ge.com                        |   M2 3AB  VAT:GB 927559189

^ permalink raw reply related

* Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
From: Alan Stern @ 2010-03-01 14:49 UTC (permalink / raw)
  To: Albert Herranz; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1267366082-15248-9-git-send-email-albert_herranz@yahoo.es>

On Sun, 28 Feb 2010, Albert Herranz wrote:

> The HCD_NO_COHERENT_MEM USB host controller driver flag can be enabled
> to instruct the USB stack to avoid allocating coherent memory for USB
> buffers.
> 
> This flag is useful to overcome some esoteric memory access restrictions
> found in some platforms.
> For example, the Nintendo Wii video game console is a NOT_COHERENT_CACHE
> platform that is unable to safely perform non-32 bit uncached writes
> to RAM because the byte enables are not connected to the bus.
> Thus, in that platform, "coherent" DMA buffers cannot be directly used
> by the kernel code unless it guarantees that all write accesses
> to said buffers are done in 32 bit chunks (which is not the case in the
> USB subsystem).
> 
> To avoid this unwanted behaviour HCD_NO_COHERENT_MEM can be enabled at
> the HCD controller, causing USB buffer allocations to be satisfied from
> normal kernel memory. In this case, the USB stack will make sure that
> the buffers get properly mapped/unmapped for DMA transfers using the DMA
> streaming mapping API.
> 
> Note that other parts of the USB stack may also use coherent memory,
> like for example the hardware descriptors used in the EHCI controllers.
> This needs to be checked and addressed separately. In the EHCI example,
> hardware descriptors are accessed in 32-bit (or 64-bit) chunks, causing
> no problems in the described scenario.

> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -1260,6 +1260,34 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
>  	*dma_handle = 0;
>  }
>  
> +static int urb_needs_setup_dma_map(struct usb_hcd *hcd, struct urb *urb)
> +{
> +	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
> +		urb->setup_dma == ~(dma_addr_t)0);
> +}
> +
> +static int urb_needs_setup_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
> +{
> +	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
> +		urb->setup_dma && urb->setup_dma != ~(dma_addr_t)0);
> +}
> +
> +static int urb_needs_transfer_dma_map(struct usb_hcd *hcd, struct urb *urb)
> +{
> +	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
> +		urb->transfer_dma == ~(dma_addr_t)0);
> +}
> +
> +static int urb_needs_transfer_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
> +{
> +	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
> +		urb->transfer_dma && urb->transfer_dma != ~(dma_addr_t)0);
> +}
> +

These functions would be a lot easier to understand if they were 
expanded into multiple test and return statements, rather than 
squeezing all the Boolean manipulations into single expressions.  (Not 
to mention the fact that other developement is going to make them even 
more complicated than they are now...)

Also, I can't help thinking that the corresponding *_map() and 
*_unmap() routines are so similar, it ought to be possible to combine 
them.  The only difference is a check for a NULL DMA address, and it's 
not clear to me why it is present.  It's also not clear why the test 
for a DMA address of all ones is present.  Maybe they both can be 
removed.

Alan Stern

^ permalink raw reply

* [PATCH] powerpc/booke: Fix breakpoint/watchpoint one-shot behavior
From: Dave Kleikamp @ 2010-03-01 14:57 UTC (permalink / raw)
  To: linuxppc-dev list
In-Reply-To: <1266954197.11207.20.camel@norville.austin.ibm.com>

Another fix for the extended ptrace patches in the -next tree.

The handling of breakpoints and watchpoints is inconsistent.  When a
breakpoint or watchpoint is hit, the interrupt handler is clearing the
proper bits in the dbcr* registers, but leaving the dac* and iac* registers
alone.  The ptrace code to delete the break/watchpoints checks the dac* and
iac* registers for zero to determine if they are enabled.  Instead, they
should check the dbcr* bits.

Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
---

 arch/powerpc/kernel/ptrace.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)


diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 0efa2e3..ed2cfe1 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -940,7 +940,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 {
 	switch (slot) {
 	case 1:
-		if (child->thread.iac1 == 0)
+		if ((child->thread.dbcr0 & DBCR0_IAC1) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
@@ -952,7 +952,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 		child->thread.dbcr0 &= ~DBCR0_IAC1;
 		break;
 	case 2:
-		if (child->thread.iac2 == 0)
+		if ((child->thread.dbcr0 & DBCR0_IAC2) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC12MODE)
@@ -963,7 +963,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 		break;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case 3:
-		if (child->thread.iac3 == 0)
+		if ((child->thread.dbcr0 & DBCR0_IAC3) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
@@ -975,7 +975,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 		child->thread.dbcr0 &= ~DBCR0_IAC3;
 		break;
 	case 4:
-		if (child->thread.iac4 == 0)
+		if ((child->thread.dbcr0 & DBCR0_IAC4) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC34MODE)
@@ -1054,7 +1054,7 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
 static int del_dac(struct task_struct *child, int slot)
 {
 	if (slot == 1) {
-		if (child->thread.dac1 == 0)
+		if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
 			return -ENOENT;
 
 		child->thread.dac1 = 0;
@@ -1070,7 +1070,7 @@ static int del_dac(struct task_struct *child, int slot)
 		child->thread.dvc1 = 0;
 #endif
 	} else if (slot == 2) {
-		if (child->thread.dac2 == 0)
+		if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
 			return -ENOENT;
 
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE

^ permalink raw reply related

* Re: [PATCH] powerpc: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
From: Christoph Lameter @ 2010-03-01 15:19 UTC (permalink / raw)
  To: Mel Gorman; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <20100301120632.GB3852@csn.ul.ie>

On Mon, 1 Mar 2010, Mel Gorman wrote:

> Christoph, how feasible would it be to allow parallel reclaimers in
> __zone_reclaim() that back off at a rate depending on the number of
> reclaimers?

Not too hard. Zone locking is there but there may be a lot of bouncing
cachelines if you run it concurrently.

^ permalink raw reply

* [Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
From: Albrecht Dreß @ 2010-03-01 18:11 UTC (permalink / raw)
  To: Linux PPC Development, Likely, Grant

On the MPC5200B, select the baud rate prescaler as /4 by default to make ve=
ry
high baud rates (e.g. 3 MBaud) accessible and to achieve a higher precision
for high baud rates in general. For baud rates below ~500 Baud, the code wi=
ll
automatically fall back to the /32 prescaler.  The original MPC5200 does on=
ly
have a /32 prescaler which is detected only once and stored in a global.  A
new chip-dependent method is used to set the divisor.

Tested on a custom 5200B based board, with up to 3 MBaud.

Signed-off-by: Albrecht Dre=DF <albrecht.dress@arcor.de>

---

--- linux-2.6.33/drivers/serial/mpc52xx_uart.c.orig	2010-02-24 19:52:17.000=
000000 +0100
+++ linux-2.6.33/drivers/serial/mpc52xx_uart.c	2010-02-26 21:12:51.00000000=
0 +0100
@@ -144,9 +144,17 @@ struct psc_ops {
 	unsigned char	(*read_char)(struct uart_port *port);
 	void		(*cw_disable_ints)(struct uart_port *port);
 	void		(*cw_restore_ints)(struct uart_port *port);
+	void		(*set_divisor)(struct uart_port *port,
+				       unsigned int divisor);
 	unsigned long	(*getuartclk)(void *p);
 };
=20
+/* We need to distinguish between the MPC5200 which has only a /32 prescal=
er,
+ * and the MPC5200B which has a /32 and a /4 prescaler.  The global is fin=
e,
+ * as the chip can be only either a 5200B or not. */
+static int is_mpc5200b =3D -1;
+
+
 #ifdef CONFIG_PPC_MPC52xx
 #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
 static void mpc52xx_psc_fifo_init(struct uart_port *port)
@@ -154,9 +162,6 @@ static void mpc52xx_psc_fifo_init(struct
 	struct mpc52xx_psc __iomem *psc =3D PSC(port);
 	struct mpc52xx_psc_fifo __iomem *fifo =3D FIFO_52xx(port);
=20
-	/* /32 prescaler */
-	out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
-
 	out_8(&fifo->rfcntl, 0x00);
 	out_be16(&fifo->rfalarm, 0x1ff);
 	out_8(&fifo->tfcntl, 0x07);
@@ -245,15 +250,40 @@ static void mpc52xx_psc_cw_restore_ints(
 	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
 }
=20
+static void mpc52xx_psc_set_divisor(struct uart_port *port,
+				    unsigned int divisor)
+{
+	struct mpc52xx_psc __iomem *psc =3D PSC(port);
+
+	/* prescaler */
+	if (is_mpc5200b !=3D 1)
+		out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */
+	else if (divisor > 0xffff) {
+		out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */
+		divisor =3D (divisor + 4) / 8;
+	} else
+		out_be16(&psc->mpc52xx_psc_clock_select, 0xff00); /* /4 */
+
+	/* ctr */
+	divisor &=3D 0xffff;
+	out_8(&psc->ctur, divisor >> 8);
+	out_8(&psc->ctlr, divisor & 0xff);
+}
+
 /* Search for bus-frequency property in this node or a parent */
 static unsigned long mpc52xx_getuartclk(void *p)
 {
 	/*
-	 * 5200 UARTs have a / 32 prescaler
-	 * but the generic serial code assumes 16
-	 * so return ipb freq / 2
+	 * The 5200 has only /32 prescalers.
+	 * 5200B UARTs have a /4 or a /32 prescaler.  For higher accuracy, we
+	 * do all calculations using the /4 prescaler for this chip.
+	 * The generic serial code assumes /16 so return ipb freq / 2 (5200)
+	 * or ipb freq * 4 (5200B).
 	 */
-	return mpc5xxx_get_bus_frequency(p) / 2;
+	if (is_mpc5200b =3D=3D 1)
+		return mpc5xxx_get_bus_frequency(p) * 4;
+	else
+		return mpc5xxx_get_bus_frequency(p) / 2;
 }
=20
 static struct psc_ops mpc52xx_psc_ops =3D {
@@ -272,6 +302,7 @@ static struct psc_ops mpc52xx_psc_ops =3D=20
 	.read_char =3D mpc52xx_psc_read_char,
 	.cw_disable_ints =3D mpc52xx_psc_cw_disable_ints,
 	.cw_restore_ints =3D mpc52xx_psc_cw_restore_ints,
+	.set_divisor =3D mpc52xx_psc_set_divisor,
 	.getuartclk =3D mpc52xx_getuartclk,
 };
=20
@@ -388,6 +419,16 @@ static void mpc512x_psc_cw_restore_ints(
 	out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
 }
=20
+static void mpc512x_psc_set_divisor(struct uart_port *port,
+				    unsigned int divisor)
+{
+	struct mpc52xx_psc __iomem *psc =3D PSC(port);
+
+	divisor &=3D 0xffff;
+	out_8(&psc->ctur, divisor >> 8);
+	out_8(&psc->ctlr, divisor & 0xff);
+}
+
 static unsigned long mpc512x_getuartclk(void *p)
 {
 	return mpc5xxx_get_bus_frequency(p);
@@ -409,6 +450,7 @@ static struct psc_ops mpc512x_psc_ops =3D=20
 	.read_char =3D mpc512x_psc_read_char,
 	.cw_disable_ints =3D mpc512x_psc_cw_disable_ints,
 	.cw_restore_ints =3D mpc512x_psc_cw_restore_ints,
+	.set_divisor =3D mpc512x_psc_set_divisor,
 	.getuartclk =3D mpc512x_getuartclk,
 };
 #endif
@@ -564,7 +606,6 @@ mpc52xx_uart_set_termios(struct uart_por
 	struct mpc52xx_psc __iomem *psc =3D PSC(port);
 	unsigned long flags;
 	unsigned char mr1, mr2;
-	unsigned short ctr;
 	unsigned int j, baud, quot;
=20
 	/* Prepare what we're gonna write */
@@ -604,7 +645,6 @@ mpc52xx_uart_set_termios(struct uart_por
=20
 	baud =3D uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
 	quot =3D uart_get_divisor(port, baud);
-	ctr =3D quot & 0xffff;
=20
 	/* Get the lock */
 	spin_lock_irqsave(&port->lock, flags);
@@ -635,8 +675,7 @@ mpc52xx_uart_set_termios(struct uart_por
 	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
 	out_8(&psc->mode, mr1);
 	out_8(&psc->mode, mr2);
-	out_8(&psc->ctur, ctr >> 8);
-	out_8(&psc->ctlr, ctr & 0xff);
+	psc_ops->set_divisor(port, quot);
=20
 	if (UART_ENABLE_MS(port, new->c_cflag))
 		mpc52xx_uart_enable_ms(port);
@@ -1113,6 +1152,19 @@ mpc52xx_uart_of_probe(struct of_device *
=20
 	dev_dbg(&op->dev, "mpc52xx_uart_probe(op=3D%p, match=3D%p)\n", op, match)=
;
=20
+	/* Check only once if we are running on a mpc5200b or not */
+	if (is_mpc5200b =3D=3D -1) {
+		struct device_node *np;
+
+		np =3D of_find_compatible_node(NULL, NULL, "fsl,mpc5200b-immr");
+		if (np) {
+			is_mpc5200b =3D 1;
+			dev_dbg(&op->dev, "mpc5200b: using /4 prescaler\n");
+			of_node_put(np);
+		} else
+			is_mpc5200b =3D 0;
+	}
+
 	/* Check validity & presence */
 	for (idx =3D 0; idx < MPC52xx_PSC_MAXNUM; idx++)
 		if (mpc52xx_uart_nodes[idx] =3D=3D op->node)

^ permalink raw reply

* Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
From: Albert Herranz @ 2010-03-01 18:38 UTC (permalink / raw)
  To: Alan Stern; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1003010943480.1645-100000@iolanthe.rowland.org>

Alan Stern wrote:
>> --- a/drivers/usb/core/hcd.c
>> +++ b/drivers/usb/core/hcd.c
>> @@ -1260,6 +1260,34 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
>>  	*dma_handle = 0;
>>  }
>>  
>> +static int urb_needs_setup_dma_map(struct usb_hcd *hcd, struct urb *urb)
>> +{
>> +	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
>> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
>> +		urb->setup_dma == ~(dma_addr_t)0);
>> +}
>> +
>> +static int urb_needs_setup_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
>> +{
>> +	return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) ||
>> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
>> +		urb->setup_dma && urb->setup_dma != ~(dma_addr_t)0);
>> +}
>> +
>> +static int urb_needs_transfer_dma_map(struct usb_hcd *hcd, struct urb *urb)
>> +{
>> +	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
>> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
>> +		urb->transfer_dma == ~(dma_addr_t)0);
>> +}
>> +
>> +static int urb_needs_transfer_dma_unmap(struct usb_hcd *hcd, struct urb *urb)
>> +{
>> +	return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) ||
>> +	       ((hcd->driver->flags & HCD_NO_COHERENT_MEM) &&
>> +		urb->transfer_dma && urb->transfer_dma != ~(dma_addr_t)0);
>> +}
>> +
> 
> These functions would be a lot easier to understand if they were 
> expanded into multiple test and return statements, rather than 
> squeezing all the Boolean manipulations into single expressions.  (Not 
> to mention the fact that other developement is going to make them even 
> more complicated than they are now...)
> 

Yes, agreed. I'll enhance that, thanks.

> Also, I can't help thinking that the corresponding *_map() and 
> *_unmap() routines are so similar, it ought to be possible to combine 
> them.  The only difference is a check for a NULL DMA address, and it's 
> not clear to me why it is present.  It's also not clear why the test 
> for a DMA address of all ones is present.  Maybe they both can be 
> removed.
> 

I think too that I can simplify that logic.
I added those checks in a defensive way seeking robustness while I familiarize with the USB stack innards. So far, those cases are just avoiding mappings when urb_needs_transfer_dma_map()/urb_needs_transfer_dma_unmap() are called with urb->transfer_buffer == 0 and urb->transfer_dma == 0.

I guess that those cases are related to scatterlist-based urb requests.
What should be the correct way to check if a urb has already been scatter/gather-mapped?

The final logic would be something like:
- map if URB_NO_TRANSFER_DMA_MAP is cleared
- otherwise (URB_TRANSFER_NO_DMA_MAP is set so) map if HCD_NO_COHERENT_MEM is set _and_ it's not a scatter/gather request (as that should have been mapped already by usb_buffer_map_sg())

Am I on the right path?

> Alan Stern
> 

Thanks,
Albert

^ permalink raw reply

* JFFS2 warnings
From: Ron Madrid @ 2010-03-01 18:43 UTC (permalink / raw)
  To: linuxppc-dev

I'm getting a bunch of these after I 'reboot' or 'poweroff'
several times.

Empty flash at 0x0056205c ends at 0x00562800
Empty flash at 0x00565334 ends at 0x00565800
Empty flash at 0x00576104 ends at 0x00576800

JFFS2 notice: (848) check_node_data: wrong data CRC
in data node at 0x00577034: read 0xe6adad18, calculated
0x202a305c.
JFFS2 notice: (848) check_node_data: wrong data CRC
in data node at 0x00575768: read 0xe6adad18, calculated
0xfc64f8a3.

I'm not too sure why I'm getting these, but recently
they seem to have caused a few problems with parts of
my filesystem (i.e. programs not running correctly).

Can someone tell me what these are or what could be
causing them?

I'm using 2.6.33rc1 and this is on an mpc8313 based board.
Not sure what other info would be useful.

Thanks,

Ron

^ permalink raw reply

* [RFC: PATCH 00/13] powerpc/47x: Support for 476 core
From: Dave Kleikamp @ 2010-03-01 19:12 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: Torez Smith

These patches add support for the 476 core.  The goal is to have a single
binary that will run on both 44x and 47x, but we still have some details to
work out.  The biggest is that the L1 cache line size differs on the two
platforms, but it's currently a compile-time option.

The code was originally written by Ben Herrenschmidt and Torez Smith, but
I've been maintaining it.  I'll take responsibility for the content, but I
can't take all the credit.

The first patch is a generic bookE feature.  Patches 2-5 add base 47x
support.  Patches 6 & 7 add a platform to support the ISS simulator, and
patches 8-13 add workarounds for DD1 and DD1.1 hardware bugs.

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox