* [PATCH 1/6] usb: phy: export ulpi_viewport_access_ops
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2013-06-03 19:21 ` Stephen Warren
[not found] ` <1370287290-21579-2-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-06-03 19:21 ` [PATCH 2/6] usb: phy: add MODULE_LICENSE to phy-tegra-usb.c Stephen Warren
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
In order to build a ULPI PHY driver as a module, this symbol needs to
be exported.
Signed-off-by: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
[swarren, reworked Manjunath's patches to split them more logically]
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/phy/phy-ulpi-viewport.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/phy/phy-ulpi-viewport.c b/drivers/usb/phy/phy-ulpi-viewport.c
index c5ba7e5..4442425 100644
--- a/drivers/usb/phy/phy-ulpi-viewport.c
+++ b/drivers/usb/phy/phy-ulpi-viewport.c
@@ -13,6 +13,7 @@
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/usb.h>
#include <linux/io.h>
#include <linux/usb/otg.h>
@@ -78,3 +79,4 @@ struct usb_phy_io_ops ulpi_viewport_access_ops = {
.read = ulpi_viewport_read,
.write = ulpi_viewport_write,
};
+EXPORT_SYMBOL_GPL(ulpi_viewport_access_ops);
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/6] usb: phy: add MODULE_LICENSE to phy-tegra-usb.c
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-06-03 19:21 ` [PATCH 1/6] usb: phy: export ulpi_viewport_access_ops Stephen Warren
@ 2013-06-03 19:21 ` Stephen Warren
2013-06-03 19:21 ` [PATCH 3/6] USB: EHCI: expand struct ehci_driver_overrides Stephen Warren
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
When this file is built as a module, it needs a MODULE_LICENSE in order
to access many exported symbols.
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/phy/phy-tegra-usb.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index 5d9af11..f0727f2 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
@@ -869,3 +870,6 @@ struct usb_phy *tegra_usb_get_phy(struct device_node *dn)
return &tegra_phy->u_phy;
}
EXPORT_SYMBOL_GPL(tegra_usb_get_phy);
+
+MODULE_DESCRIPTION("Tegra USB PHY driver");
+MODULE_LICENSE("GPL v2");
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/6] USB: EHCI: expand struct ehci_driver_overrides
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-06-03 19:21 ` [PATCH 1/6] usb: phy: export ulpi_viewport_access_ops Stephen Warren
2013-06-03 19:21 ` [PATCH 2/6] usb: phy: add MODULE_LICENSE to phy-tegra-usb.c Stephen Warren
@ 2013-06-03 19:21 ` Stephen Warren
[not found] ` <1370287290-21579-4-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-06-03 19:21 ` [PATCH 4/6] USB: EHCI: export symbols for ehci-hcd sub-drivers Stephen Warren
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Some EHCI HCD drivers may need to override additional fields in struct
hc_driver, such as map_urb_for_dma, unmap_urb_for_dma, hub_control. Add
fields to struct ehci_driver_overrides to allow them to do so.
These new overrides will be used at least by the Tegra EHCI driver.
Signed-off-by: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
[swarren, reworked Manjunath's patches to split them more logically]
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/host/ehci-hcd.c | 6 ++++++
drivers/usb/host/ehci.h | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 246e124..da1c224 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1211,6 +1211,12 @@ void ehci_init_driver(struct hc_driver *drv,
drv->hcd_priv_size += over->extra_priv_size;
if (over->reset)
drv->reset = over->reset;
+ if (over->map_urb_for_dma)
+ drv->map_urb_for_dma = over->map_urb_for_dma;
+ if (over->unmap_urb_for_dma)
+ drv->unmap_urb_for_dma = over->unmap_urb_for_dma;
+ if (over->hub_control)
+ drv->hub_control = over->hub_control;
}
}
EXPORT_SYMBOL_GPL(ehci_init_driver);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 7c978b2..918008a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -795,6 +795,12 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
struct ehci_driver_overrides {
size_t extra_priv_size;
int (*reset)(struct usb_hcd *hcd);
+ int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags);
+ void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);
+ int (*hub_control)(struct usb_hcd *hcd,
+ u16 typeReq, u16 wValue, u16 wIndex,
+ char *buf, u16 wLength);
};
extern void ehci_init_driver(struct hc_driver *drv,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/6] USB: EHCI: export symbols for ehci-hcd sub-drivers
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
` (2 preceding siblings ...)
2013-06-03 19:21 ` [PATCH 3/6] USB: EHCI: expand struct ehci_driver_overrides Stephen Warren
@ 2013-06-03 19:21 ` Stephen Warren
[not found] ` <1370287290-21579-5-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-06-03 19:21 ` [PATCH 5/6] USB: EHCI: fix circular dependency in Tegra modules Stephen Warren
2013-06-03 19:21 ` [PATCH 6/6] USB: EHCI: make ehci-tegra a separate driver Stephen Warren
5 siblings, 1 reply; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
In order to split ehci-hcd.c into separate modules, various symbols must
be exported. Also, rename the symbols to add an ehci_ prefix, to avoid
any naming clashes.
Signed-off-by: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
[swarren, reworked Manjunath's patches to split them more logically]
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/host/ehci-hcd.c | 28 +++++++++++++++++-----------
drivers/usb/host/ehci-hub.c | 9 +++++----
drivers/usb/host/ehci-tegra.c | 14 +++++++-------
drivers/usb/host/ehci.h | 8 ++++++++
4 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index da1c224..75cf500 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -139,7 +139,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
/*-------------------------------------------------------------------------*/
/*
- * handshake - spin reading hc until handshake completes or fails
+ * ehci_handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
* @mask: bits to look at in result of read
* @done: value of those bits when handshake succeeds
@@ -155,8 +155,8 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
* before driver shutdown. But it also seems to be caused by bugs in cardbus
* bridge shutdown: shutting down the bridge before the devices using it.
*/
-static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
- u32 mask, u32 done, int usec)
+int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr,
+ u32 mask, u32 done, int usec)
{
u32 result;
@@ -172,6 +172,7 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
} while (usec > 0);
return -ETIMEDOUT;
}
+EXPORT_SYMBOL_GPL(ehci_handshake);
/* check TDI/ARC silicon is in host mode */
static int tdi_in_host_mode (struct ehci_hcd *ehci)
@@ -186,7 +187,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
* Force HC to halt state from unknown (EHCI spec section 2.3).
* Must be called with interrupts enabled and the lock not held.
*/
-static int ehci_halt (struct ehci_hcd *ehci)
+int ehci_halt(struct ehci_hcd *ehci)
{
u32 temp;
@@ -212,12 +213,13 @@ static int ehci_halt (struct ehci_hcd *ehci)
spin_unlock_irq(&ehci->lock);
synchronize_irq(ehci_to_hcd(ehci)->irq);
- return handshake(ehci, &ehci->regs->status,
+ return ehci_handshake(ehci, &ehci->regs->status,
STS_HALT, STS_HALT, 16 * 125);
}
+EXPORT_SYMBOL_GPL(ehci_halt);
/* put TDI/ARC silicon into EHCI mode */
-static void tdi_reset (struct ehci_hcd *ehci)
+void ehci_tdi_reset(struct ehci_hcd *ehci)
{
u32 tmp;
@@ -231,12 +233,13 @@ static void tdi_reset (struct ehci_hcd *ehci)
tmp |= USBMODE_BE;
ehci_writel(ehci, tmp, &ehci->regs->usbmode);
}
+EXPORT_SYMBOL_GPL(ehci_tdi_reset);
/*
* Reset a non-running (STS_HALT == 1) controller.
* Must be called with interrupts enabled and the lock not held.
*/
-static int ehci_reset (struct ehci_hcd *ehci)
+int ehci_reset(struct ehci_hcd *ehci)
{
int retval;
u32 command = ehci_readl(ehci, &ehci->regs->command);
@@ -251,7 +254,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
ehci_writel(ehci, command, &ehci->regs->command);
ehci->rh_state = EHCI_RH_HALTED;
ehci->next_statechange = jiffies;
- retval = handshake (ehci, &ehci->regs->command,
+ retval = ehci_handshake(ehci, &ehci->regs->command,
CMD_RESET, 0, 250 * 1000);
if (ehci->has_hostpc) {
@@ -263,7 +266,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
return retval;
if (ehci_is_TDI(ehci))
- tdi_reset (ehci);
+ ehci_tdi_reset(ehci);
if (ehci->debug)
dbgp_external_startup(ehci_to_hcd(ehci));
@@ -272,6 +275,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
ehci->resuming_ports = 0;
return retval;
}
+EXPORT_SYMBOL_GPL(ehci_reset);
/*
* Idle the controller (turn off the schedules).
@@ -286,7 +290,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
/* wait for any schedule enables/disables to take effect */
temp = (ehci->command << 10) & (STS_ASS | STS_PSS);
- handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, temp, 16 * 125);
+ ehci_handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, temp,
+ 16 * 125);
/* then disable anything that's still active */
spin_lock_irq(&ehci->lock);
@@ -295,7 +300,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
spin_unlock_irq(&ehci->lock);
/* hardware can take 16 microframes to turn off ... */
- handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, 0, 16 * 125);
+ ehci_handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, 0,
+ 16 * 125);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index b2f6450..3be5129 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -33,7 +33,7 @@
#ifdef CONFIG_PM
-static int ehci_hub_control(
+int ehci_hub_control(
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
@@ -712,7 +712,7 @@ ehci_hub_descriptor (
/*-------------------------------------------------------------------------*/
-static int ehci_hub_control (
+int ehci_hub_control(
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
@@ -892,7 +892,7 @@ static int ehci_hub_control (
PORT_SUSPEND | PORT_RESUME);
ehci_writel(ehci, temp, status_reg);
clear_bit(wIndex, &ehci->resuming_ports);
- retval = handshake(ehci, status_reg,
+ retval = ehci_handshake(ehci, status_reg,
PORT_RESUME, 0, 2000 /* 2msec */);
if (retval != 0) {
ehci_err(ehci,
@@ -918,7 +918,7 @@ static int ehci_hub_control (
/* REVISIT: some hardware needs 550+ usec to clear
* this bit; seems too long to spin routinely...
*/
- retval = handshake(ehci, status_reg,
+ retval = ehci_handshake(ehci, status_reg,
PORT_RESET, 0, 1000);
if (retval != 0) {
ehci_err (ehci, "port %d reset error %d\n",
@@ -1132,6 +1132,7 @@ error_exit:
spin_unlock_irqrestore (&ehci->lock, flags);
return retval;
}
+EXPORT_SYMBOL_GPL(ehci_hub_control);
static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
{
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 8390c87..29d4643 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -179,7 +179,7 @@ static int tegra_ehci_hub_control(
* If a transaction is in progress, there may be a delay in
* suspending the port. Poll until the port is suspended.
*/
- if (handshake(ehci, status_reg, PORT_SUSPEND,
+ if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
PORT_SUSPEND, 5000))
pr_err("%s: timeout waiting for SUSPEND\n", __func__);
@@ -227,9 +227,9 @@ static int tegra_ehci_hub_control(
spin_lock_irqsave(&ehci->lock, flags);
/* Poll until the controller clears RESUME and SUSPEND */
- if (handshake(ehci, status_reg, PORT_RESUME, 0, 2000))
+ if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 2000))
pr_err("%s: timeout waiting for RESUME\n", __func__);
- if (handshake(ehci, status_reg, PORT_SUSPEND, 0, 2000))
+ if (ehci_handshake(ehci, status_reg, PORT_SUSPEND, 0, 2000))
pr_err("%s: timeout waiting for SUSPEND\n", __func__);
ehci->reset_done[wIndex-1] = 0;
@@ -480,7 +480,7 @@ static int controller_resume(struct device *dev)
tegra_ehci_phy_restore_start(hcd->phy, tegra->port_speed);
/* Enable host mode */
- tdi_reset(ehci);
+ ehci_tdi_reset(ehci);
/* Enable Port Power */
val = readl(&hw->port_status[0]);
@@ -511,14 +511,14 @@ static int controller_resume(struct device *dev)
}
/* Poll until CCS is enabled */
- if (handshake(ehci, &hw->port_status[0], PORT_CONNECT,
+ if (ehci_handshake(ehci, &hw->port_status[0], PORT_CONNECT,
PORT_CONNECT, 2000)) {
pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__);
goto restart;
}
/* Poll until PE is enabled */
- if (handshake(ehci, &hw->port_status[0], PORT_PE,
+ if (ehci_handshake(ehci, &hw->port_status[0], PORT_PE,
PORT_PE, 2000)) {
pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__);
goto restart;
@@ -536,7 +536,7 @@ static int controller_resume(struct device *dev)
writel(val, &hw->port_status[0]);
/* Wait until port suspend completes */
- if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND,
+ if (ehci_handshake(ehci, &hw->port_status[0], PORT_SUSPEND,
PORT_SUSPEND, 1000)) {
pr_err("%s: timeout waiting for PORT_SUSPEND\n",
__func__);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 918008a..67606ec7 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -806,6 +806,14 @@ struct ehci_driver_overrides {
extern void ehci_init_driver(struct hc_driver *drv,
const struct ehci_driver_overrides *over);
extern int ehci_setup(struct usb_hcd *hcd);
+extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr,
+ u32 mask, u32 done, int usec);
+extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq,
+ u16 wValue, u16 wIndex, char *buf,
+ u16 wLength);
+extern int ehci_reset(struct ehci_hcd *ehci);
+extern int ehci_halt(struct ehci_hcd *ehci);
+extern void ehci_tdi_reset(struct ehci_hcd *ehci);
#ifdef CONFIG_PM
extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/6] USB: EHCI: fix circular dependency in Tegra modules
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
` (3 preceding siblings ...)
2013-06-03 19:21 ` [PATCH 4/6] USB: EHCI: export symbols for ehci-hcd sub-drivers Stephen Warren
@ 2013-06-03 19:21 ` Stephen Warren
2013-06-03 19:21 ` [PATCH 6/6] USB: EHCI: make ehci-tegra a separate driver Stephen Warren
5 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
The Tegra EHCI driver directly calls various functions in the Tegra USB
PHY driver. The reverse is also true; the PHY driver calls into the EHCI
driver. This is problematic when the two are built as modules.
The calls from the PHY to EHCI driver were originally added in commit
bbdabdb "usb: add APIs to access host registers from Tegra PHY", for the
following reasons:
1) The register being touched is an EHCI register, so logically only the
EHCI driver should touch it.
2) (1) implies that some locking may be needed to correctly implement the
r/m/w access to this shared register.
3) We were expecting to pass only the PHY register space to the Tegra PHY
driver, and hence it would not have access to touch the shared
registers.
To solve this, that commit added functions in the EHCI driver to touch the
shared register on behalf of the PHY driver.
In practice, we ended up not having any locking in the implementaiton of
those functions, and I've been led to believe this is safe. Equally, (3)
did not happen either. Hence, it is possible for the PHY driver to touch
the shared register directly.
Given that, this patch moves the code to touch the shared register back
into the PHY driver, to eliminate the module problems. If we actually
need locking or co-ordination in the future, I propose we put the lock
support into some pre-existing core module, or into a third separate
module, in order to avoid the circular dependencies.
I apologize for my contribution to code churn here.
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/host/ehci-tegra.c | 36 ----------------------------------
drivers/usb/phy/phy-tegra-usb.c | 39 ++++++++++++++++++++++++++++++++++---
include/linux/usb/tegra_usb_phy.h | 4 ----
3 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 29d4643..edf7d36 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -34,11 +34,6 @@
#define TEGRA_USB2_BASE 0xC5004000
#define TEGRA_USB3_BASE 0xC5008000
-/* PORTSC registers */
-#define TEGRA_USB_PORTSC1 0x184
-#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
-#define TEGRA_USB_PORTSC1_PHCD (1 << 23)
-
#define TEGRA_USB_DMA_ALIGN 32
struct tegra_ehci_hcd {
@@ -608,37 +603,6 @@ static const struct dev_pm_ops tegra_ehci_pm_ops = {
#endif
-/* Bits of PORTSC1, which will get cleared by writing 1 into them */
-#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
-
-void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val)
-{
- unsigned long val;
- struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
- void __iomem *base = hcd->regs;
-
- val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
- val &= ~TEGRA_USB_PORTSC1_PTS(3);
- val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3);
- writel(val, base + TEGRA_USB_PORTSC1);
-}
-EXPORT_SYMBOL_GPL(tegra_ehci_set_pts);
-
-void tegra_ehci_set_phcd(struct usb_phy *x, bool enable)
-{
- unsigned long val;
- struct usb_hcd *hcd = bus_to_hcd(x->otg->host);
- void __iomem *base = hcd->regs;
-
- val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
- if (enable)
- val |= TEGRA_USB_PORTSC1_PHCD;
- else
- val &= ~TEGRA_USB_PORTSC1_PHCD;
- writel(val, base + TEGRA_USB_PORTSC1);
-}
-EXPORT_SYMBOL_GPL(tegra_ehci_set_phcd);
-
static int tegra_ehci_probe(struct platform_device *pdev)
{
struct resource *res;
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index f0727f2..3446245 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -32,11 +32,20 @@
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h>
+#include <linux/usb/ehci_def.h>
#include <linux/usb/tegra_usb_phy.h>
#include <linux/module.h>
#define ULPI_VIEWPORT 0x170
+/* PORTSC registers */
+#define TEGRA_USB_PORTSC1 0x184
+#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
+#define TEGRA_USB_PORTSC1_PHCD (1 << 23)
+
+/* Bits of PORTSC1, which will get cleared by writing 1 into them */
+#define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
+
#define USB_SUSP_CTRL 0x400
#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
@@ -197,6 +206,30 @@ static struct tegra_utmip_config utmip_default[] = {
},
};
+static void set_pts(struct tegra_usb_phy *phy, u8 pts_val)
+{
+ void __iomem *base = phy->regs;
+ unsigned long val;
+
+ val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
+ val &= ~TEGRA_USB_PORTSC1_PTS(3);
+ val |= TEGRA_USB_PORTSC1_PTS(pts_val & 3);
+ writel(val, base + TEGRA_USB_PORTSC1);
+}
+
+static void set_phcd(struct tegra_usb_phy *phy, bool enable)
+{
+ void __iomem *base = phy->regs;
+ unsigned long val;
+
+ val = readl(base + TEGRA_USB_PORTSC1) & ~TEGRA_PORTSC1_RWC_BITS;
+ if (enable)
+ val |= TEGRA_USB_PORTSC1_PHCD;
+ else
+ val &= ~TEGRA_USB_PORTSC1_PHCD;
+ writel(val, base + TEGRA_USB_PORTSC1);
+}
+
static int utmip_pad_open(struct tegra_usb_phy *phy)
{
phy->pad_clk = devm_clk_get(phy->dev, "utmi-pads");
@@ -283,7 +316,7 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
val &= ~USB_SUSP_SET;
writel(val, base + USB_SUSP_CTRL);
} else
- tegra_ehci_set_phcd(&phy->u_phy, true);
+ set_phcd(phy, true);
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
@@ -305,7 +338,7 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
val &= ~USB_SUSP_CLR;
writel(val, base + USB_SUSP_CTRL);
} else
- tegra_ehci_set_phcd(&phy->u_phy, false);
+ set_phcd(phy, false);
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
USB_PHY_CLK_VALID))
@@ -428,7 +461,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
utmi_phy_clk_enable(phy);
if (!phy->is_legacy_phy)
- tegra_ehci_set_pts(&phy->u_phy, 0);
+ set_pts(phy, 0);
return 0;
}
diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h
index 0cd15d2..d2ca919 100644
--- a/include/linux/usb/tegra_usb_phy.h
+++ b/include/linux/usb/tegra_usb_phy.h
@@ -76,8 +76,4 @@ void tegra_ehci_phy_restore_start(struct usb_phy *phy,
void tegra_ehci_phy_restore_end(struct usb_phy *phy);
-void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val);
-
-void tegra_ehci_set_phcd(struct usb_phy *x, bool enable);
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/6] USB: EHCI: make ehci-tegra a separate driver
[not found] ` <1370287290-21579-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
` (4 preceding siblings ...)
2013-06-03 19:21 ` [PATCH 5/6] USB: EHCI: fix circular dependency in Tegra modules Stephen Warren
@ 2013-06-03 19:21 ` Stephen Warren
5 siblings, 0 replies; 10+ messages in thread
From: Stephen Warren @ 2013-06-03 19:21 UTC (permalink / raw)
To: Felipe Balbi
Cc: Greg Kroah-Hartman, Alan Stern, Manjunath Goudar, Arnd Bergmann,
Venu Byravarasu, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren
From: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Separate the Tegra on-chip host controller driver from
ehci-hcd host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.
Signed-off-by: Manjunath Goudar <manjunath.goudar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
[swarren, reworked Manjunath's patches to split them more logically,
minor re-order of added lines to better match layout of other split-up
HCD drivers and existing code, add MODULE_DEVICE_TABLE, fix
MODULE_LICENSE.]
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/usb/host/Kconfig | 2 +-
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ehci-hcd.c | 5 --
drivers/usb/host/ehci-tegra.c | 125 ++++++++++++++++++++---------------------
4 files changed, 63 insertions(+), 70 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index fcb20fd..6c9347c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -200,7 +200,7 @@ config USB_EHCI_MSM
has an external PHY.
config USB_EHCI_TEGRA
- boolean "NVIDIA Tegra HCD support"
+ tristate "NVIDIA Tegra HCD support"
depends on ARCH_TEGRA
select USB_EHCI_ROOT_HUB_TT
select USB_PHY
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index dbc785d..c170383 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o
obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
+obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 75cf500..2eab6f0 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1278,11 +1278,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_hcd_msp_driver
#endif
-#ifdef CONFIG_USB_EHCI_TEGRA
-#include "ehci-tegra.c"
-#define PLATFORM_DRIVER tegra_ehci_driver
-#endif
-
#ifdef CONFIG_SPARC_LEON
#include "ehci-grlib.c"
#define PLATFORM_DRIVER ehci_grlib_driver
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index edf7d36..d12bc83 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -17,25 +17,38 @@
*/
#include <linux/clk.h>
+#include <linux/clk/tegra.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/tegra_usb.h>
-#include <linux/irq.h>
-#include <linux/usb/otg.h>
#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_usb.h>
#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#include <linux/usb/ehci_def.h>
#include <linux/usb/tegra_usb_phy.h>
-#include <linux/clk/tegra.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ehci.h"
#define TEGRA_USB_BASE 0xC5000000
#define TEGRA_USB2_BASE 0xC5004000
#define TEGRA_USB3_BASE 0xC5008000
+#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
+
#define TEGRA_USB_DMA_ALIGN 32
+#define DRIVER_DESC "Tegra EHCI driver"
+#define DRV_NAME "tegra-ehci"
+
struct tegra_ehci_hcd {
struct ehci_hcd *ehci;
struct tegra_usb_phy *phy;
@@ -47,6 +60,8 @@ struct tegra_ehci_hcd {
enum tegra_usb_phy_port_speed port_speed;
};
+static struct hc_driver __read_mostly tegra_ehci_hc_driver;
+
static void tegra_ehci_power_up(struct usb_hcd *hcd)
{
struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
@@ -264,31 +279,6 @@ static void tegra_ehci_restart(struct usb_hcd *hcd)
up_write(&ehci_cf_port_reset_rwsem);
}
-static void tegra_ehci_shutdown(struct usb_hcd *hcd)
-{
- struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
-
- /* ehci_shutdown touches the USB controller registers, make sure
- * controller has clocks to it */
- if (!tegra->host_resumed)
- tegra_ehci_power_up(hcd);
-
- ehci_shutdown(hcd);
-}
-
-static int tegra_ehci_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-
- /* EHCI registers start at offset 0x100 */
- ehci->caps = hcd->regs + 0x100;
-
- /* switch to host mode */
- hcd->has_tt = 1;
-
- return ehci_setup(hcd);
-}
-
struct dma_aligned_buffer {
void *kmalloc_ptr;
void *old_xfer_buffer;
@@ -368,38 +358,6 @@ static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
free_dma_aligned_buffer(urb);
}
-static const struct hc_driver tegra_ehci_hc_driver = {
- .description = hcd_name,
- .product_desc = "Tegra EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
- .flags = HCD_USB2 | HCD_MEMORY,
-
- /* standard ehci functions */
- .irq = ehci_irq,
- .start = ehci_run,
- .stop = ehci_stop,
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
- .get_frame_number = ehci_get_frame,
- .hub_status_data = ehci_hub_status_data,
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-
- /* modified ehci functions for tegra */
- .reset = tegra_ehci_setup,
- .shutdown = tegra_ehci_shutdown,
- .map_urb_for_dma = tegra_ehci_map_urb_for_dma,
- .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
- .hub_control = tegra_ehci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
-#endif
-};
-
static int setup_vbus_gpio(struct platform_device *pdev,
struct tegra_ehci_platform_data *pdata)
{
@@ -672,6 +630,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
err = -ENOMEM;
goto cleanup_clk;
}
+ tegra->ehci = hcd_to_ehci(hcd);
+
+ hcd->has_tt = 1;
hcd->phy = u_phy;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -688,6 +649,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
err = -ENOMEM;
goto cleanup_hcd_create;
}
+ tegra->ehci->caps = hcd->regs + 0x100;
err = usb_phy_init(hcd->phy);
if (err) {
@@ -711,7 +673,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
}
tegra->host_resumed = 1;
- tegra->ehci = hcd_to_ehci(hcd);
irq = platform_get_irq(pdev, 0);
if (!irq) {
@@ -785,6 +746,12 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
+ /*
+ * ehci_shutdown touches the USB controller registers, make sure
+ * controller has clocks to it
+ */
+ if (!tegra->host_resumed)
+ tegra_ehci_power_up(hcd);
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
}
@@ -799,10 +766,40 @@ static struct platform_driver tegra_ehci_driver = {
.remove = tegra_ehci_remove,
.shutdown = tegra_ehci_hcd_shutdown,
.driver = {
- .name = "tegra-ehci",
+ .name = DRV_NAME,
.of_match_table = tegra_ehci_of_match,
#ifdef CONFIG_PM
.pm = &tegra_ehci_pm_ops,
#endif
}
};
+
+static struct ehci_driver_overrides tegra_overrides __initdata = {
+ .extra_priv_size = sizeof(struct tegra_ehci_hcd),
+ .map_urb_for_dma = tegra_ehci_map_urb_for_dma,
+ .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
+ .hub_control = tegra_ehci_hub_control,
+};
+
+static int __init ehci_tegra_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info(DRV_NAME ": " DRIVER_DESC "\n");
+
+ ehci_init_driver(&tegra_ehci_hc_driver, &tegra_overrides);
+ return platform_driver_register(&tegra_ehci_driver);
+}
+module_init(ehci_tegra_init);
+
+static void __exit ehci_tegra_cleanup(void)
+{
+ platform_driver_unregister(&tegra_ehci_driver);
+}
+module_exit(ehci_tegra_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_ehci_of_match);
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread