Skip to contentSkip to conversation

SuperH on-chip EHCI glue

PATCH In review Paul Mundt 3 participants 6 messages Nov 25, 2010 – Dec 1, 2010

Subsystems (4)
lore
Share & tools
lore

Paul Mundt

author
#0 lore raw

PATCH 1/1 SuperH on-chip EHCI glue

This is a simple patch series for adding EHCI glue for the SuperH on-chip controller. It's largely modelled after the ohci-sh driver with clock management added on top, which I plan to move out to be shared between the two like Octeon presently does in a future patch -- this just hasn't been done yet since I need to go through and audit all of the SH OHCI users first.

The changes themselves are sitting in a topic branch, and I've had Shimoda-san give them a cursory review without incident. If you don't have any issues with the series then you can feel free to pull the topic branch in to one of your trees as-is, or I can merge it via the SH tree (I don't have anything that depends on it, so I'm fine with whatever you prefer).

The topic branch itself is at:

master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git sh/ehci

and contains:

Paul Mundt (3):
usb: ohci-sh: Set IRQ as shared.
usb: ehci-hcd: Add support for SuperH EHCI.
sh: Add EHCI support for SH7786.

---

 arch/sh/kernel/cpu/sh4a/setup-sh7786.c |   35 +++++-
 drivers/usb/Kconfig                    |    1 +
 drivers/usb/host/ehci-hcd.c            |    5 +
 drivers/usb/host/ehci-sh.c             |  232 ++++++++++++++++++++++++++++++++
 drivers/usb/host/ohci-sh.c             |    2 +-
 5 files changed, 270 insertions(+), 5 deletions(-)
 create mode 100644 drivers/usb/host/ehci-sh.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c +31 -4
index c016c00..0170dbd 100644
@@ -522,10 +522,37 @@ static struct platform_device dma0_device = {
 	},
 };
 
+#define USB_EHCI_START 0xffe70000
+#define USB_OHCI_START 0xffe70400
+
+static struct resource usb_ehci_resources[] = {
+	[0] = {
+		.start	= USB_EHCI_START,
+		.end	= USB_EHCI_START + 0x3ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 77,
+		.end	= 77,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usb_ehci_device = {
+	.name		= "sh_ehci",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &usb_ehci_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(usb_ehci_resources),
+	.resource	= usb_ehci_resources,
+};
+
 static struct resource usb_ohci_resources[] = {
 	[0] = {
-		.start	= 0xffe70400,
-		.end	= 0xffe704ff,
+		.start	= USB_OHCI_START,
+		.end	= USB_OHCI_START + 0x3ff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -535,12 +562,11 @@ static struct resource usb_ohci_resources[] = {
 	},
 };
 
-static u64 usb_ohci_dma_mask = DMA_BIT_MASK(32);
 static struct platform_device usb_ohci_device = {
 	.name		= "sh_ohci",
 	.id		= -1,
 	.dev = {
-		.dma_mask		= &usb_ohci_dma_mask,
+		.dma_mask		= &usb_ohci_device.dev.coherent_dma_mask,
 		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(usb_ohci_resources),
@@ -570,6 +596,7 @@ static struct platform_device *sh7786_early_devices[] __initdata = {
 
 static struct platform_device *sh7786_devices[] __initdata = {
 	&dma0_device,
+	&usb_ehci_device,
 	&usb_ohci_device,
 };
 
drivers/usb/Kconfig +1 -0
index 67eb377..22a9173 100644
@@ -66,6 +66,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_AT91SAM9G45
 	default y if ARCH_MXC
 	default y if ARCH_OMAP3
+	default y if CPU_SUBTYPE_SH7786
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
drivers/usb/host/ehci-hcd.c +5 -0
index 502a7e6..02ffbea 100644
@@ -1166,6 +1166,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_mxc_driver
 #endif
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7786
+#include "ehci-sh.c"
+#define PLATFORM_DRIVER		ehci_hcd_sh_driver
+#endif
+
 #ifdef CONFIG_SOC_AU1200
 #include "ehci-au1xxx.c"
 #define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
drivers/usb/host/ehci-sh.c new file +232 -0

232 lines not on this page · raw message

drivers/usb/host/ohci-sh.c +1 -1
index 0b35d22..f47867f 100644
@@ -109,7 +109,7 @@ static int ohci_hcd_sh_probe(struct platform_device *pdev)
 	hcd->regs = (void __iomem *)res->start;
 	hcd->rsrc_start = res->start;
 	hcd->rsrc_len = resource_size(res);
-	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
 	if (ret != 0) {
 		err("Failed to add hcd");
 		usb_put_hcd(hcd);
maintainer
#1 lore raw
Quoted 13 lines · Paul Mundt

This is a simple patch series for adding EHCI glue for the SuperH on-chip controller. It's largely modelled after the ohci-sh driver with clock management added on top, which I plan to move out to be shared between the two like Octeon presently does in a future patch -- this just hasn't been done yet since I need to go through and audit all of the SH OHCI users first.

The changes themselves are sitting in a topic branch, and I've had Shimoda-san give them a cursory review without incident. If you don't have any issues with the series then you can feel free to pull the topic branch in to one of your trees as-is, or I can merge it via the SH tree (I don't have anything that depends on it, so I'm fine with whatever you prefer).

...

Quoted 38 lines
drivers/usb/host/ehci-sh.c new file +35 -0
 
+static const struct hc_driver ehci_sh_hc_driver = {
+	.description			= hcd_name,
+	.product_desc			= "SuperH EHCI",
+	.hcd_priv_size			= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq				= ehci_irq,
+	.flags				= HCD_USB2 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset				= ehci_sh_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,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number		= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data		= ehci_hub_status_data,

drivers/usb/host/ehci-sh.c line 94

Quoted 10 lines
drivers/usb/host/ehci-sh.c new file +10 -0
+	.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,
+};

You are missing the .endpoint_reset and .ehci_clear_tt_buffer_complete members. This is a little surprising -- it implies the driver was written by copying another one that didn't have these things, meaning it must have been pretty old.

Alan Stern

author
#2 lore raw
In reply to Paul Mundt
Quoted 10 lines · Alan Stern

drivers/usb/host/ehci-sh.c line 94

Quoted 3 lines · Paul Mundt
drivers/usb/host/ehci-sh.c new file +3 -0
+	.relinquish_port		= ehci_relinquish_port,
+	.port_handed_over		= ehci_port_handed_over,
+};

You are missing the .endpoint_reset and .ehci_clear_tt_buffer_complete members. This is a little surprising -- it implies the driver was written by copying another one that didn't have these things, meaning it must have been pretty old.

I based it on ehci-atmel, which had a similar need for the clock framework interfacing. I'll add in the two that you noticed, but if I'm behind on some API changes, is there something else I should be looking at?

maintainer
#3 lore raw
In reply to Paul Mundt
Quoted 11 lines · Paul Mundt
Quoted 10 lines · Alan Stern

drivers/usb/host/ehci-sh.c line 94

Quoted 3 lines · Paul Mundt
drivers/usb/host/ehci-sh.c new file +3 -0
+	.relinquish_port		= ehci_relinquish_port,
+	.port_handed_over		= ehci_port_handed_over,
+};

You are missing the .endpoint_reset and .ehci_clear_tt_buffer_complete members. This is a little surprising -- it implies the driver was written by copying another one that didn't have these things, meaning it must have been pretty old.

Quoted 4 lines

I based it on ehci-atmel, which had a similar need for the clock framework interfacing. I'll add in the two that you noticed, but if I'm behind on some API changes, is there something else I should be looking at?

Not that I know of.

A quick check shows that ehci-mxc.c and ehci-w90x900.c are also missing these methods. I'm sure that at one point all the existing drivers had them. Could you look into adding the missing methods to all the drivers that need them?

Alan Stern

#4 lore raw
In reply to Paul Mundt

On 11/25/2010 12:03 AM, Paul Mundt wrote:
[...]

drivers/usb/Kconfig config USB_ARCH_HAS_EHCI · line 71

Quoted 11 lines
drivers/usb/Kconfig +1 -0
index 67eb377..22a9173 100644
@@ -66,6 +66,7 @@ config USB_ARCH_HAS_EHCI
  	default y if ARCH_AT91SAM9G45
  	default y if ARCH_MXC
  	default y if ARCH_OMAP3
+	default y if CPU_SUBTYPE_SH7786
  	default PCI
 

How about moving that to your archecture Kconfig as:

' select USB_ARCH_HAS_EHCI'

We should be working towards reducing this per-chip churn in the Kconfig files if possible.

David Daney

author
#5 lore raw
In reply to Paul Mundt
Quoted 16 lines · David Daney

On 11/25/2010 12:03 AM, Paul Mundt wrote:
[...]

drivers/usb/Kconfig config USB_ARCH_HAS_EHCI · line 71

Quoted 11 lines
drivers/usb/Kconfig +1 -0
index 67eb377..22a9173 100644
@@ -66,6 +66,7 @@ config USB_ARCH_HAS_EHCI
 	default y if ARCH_AT91SAM9G45
 	default y if ARCH_MXC
 	default y if ARCH_OMAP3
+	default y if CPU_SUBTYPE_SH7786
 	default PCI
 

How about moving that to your archecture Kconfig as:

Quoted 5 lines

' select USB_ARCH_HAS_EHCI'

We should be working towards reducing this per-chip churn in the Kconfig files if possible.

Good idea, I didn't realize other architectures were doing this already. I've now ended up doing this for all of the SH subtypes with EHCI/OHCI support, which will follow in an updated patch.