summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-06-13 11:24:11 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-17 13:54:48 -0700
commit91a687d8fe39bf100286138f0ed1ef1e7b32cfb8 (patch)
tree74c93c11d714195a1775cd83e957d88a098abdac /drivers/usb/host
parenta4faa54e3aa2b4a8cdc65e36ac70fd17d3f86629 (diff)
downloadop-kernel-dev-91a687d8fe39bf100286138f0ed1ef1e7b32cfb8.zip
op-kernel-dev-91a687d8fe39bf100286138f0ed1ef1e7b32cfb8.tar.gz
USB: EHCI: tegra: fix circular module dependencies
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@nvidia.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Arnd Bergmann <arnd@arndb.de> Tested-by: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-tegra.c36
1 files changed, 0 insertions, 36 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index dde5189..8063429 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 {
@@ -380,37 +375,6 @@ static int setup_vbus_gpio(struct platform_device *pdev,
return err;
}
-/* 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;
OpenPOWER on IntegriCloud