diff options
author | Krishna Yarlagadda <kyarlagadda@nvidia.com> | 2013-05-02 17:30:46 +0530 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2013-06-11 17:31:59 -0700 |
commit | 02be51ade99e6792682b387fd18fbad43bee9ebf (patch) | |
tree | b5fcd535beaef6dbd4724d990aa6adcaa42e41c1 /drivers | |
parent | fd8b151aba563df1be5d57cae204bfee2ed5f4cb (diff) |
USB: xhci: Dynamic host load support
Load xhci dynamically when otg cable is connected
Bug 1242148
Change-Id: If6b9b3ad198e3d1aef7636e9a7752be7a4ccc1c7
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Reviewed-on: http://git-master/r/234146
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/xhci-tegra.c | 24 | ||||
-rw-r--r-- | drivers/usb/otg/tegra-otg.c | 25 |
2 files changed, 26 insertions, 23 deletions
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 29e96ea15d84..490de9ef6ede 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -314,15 +314,7 @@ static void update_speed(struct tegra_xhci_hcd *tegra, u8 port) pmc_data.port_speed = USB_PMC_PORT_SPEED_UNKNOWN; } -static void setup_wake_detect(bool setup_wake) -{ - if (setup_wake) - pmc_data.pmc_ops->setup_pmc_wake_detect(&pmc_data); - else - pmc_data.pmc_ops->disable_pmc_bus_ctrl(&pmc_data); -} - -static void pmc_init(struct tegra_xhci_hcd *tegra, bool setup_wake) +static void pmc_init(struct tegra_xhci_hcd *tegra) { u32 portmap = tegra->bdata->portmap; @@ -332,7 +324,6 @@ static void pmc_init(struct tegra_xhci_hcd *tegra, bool setup_wake) pmc_data.phy_type = TEGRA_USB_PHY_INTF_UTMI; update_speed(tegra, PMC_PORT_UTMIP_P0); tegra_usb_pmc_init(&pmc_data); - setup_wake_detect(setup_wake); } if (portmap & TEGRA_XUSB_USB2_P1) { /* XUSB_USB2_P1 is PMC UTMI_P2 */ @@ -340,14 +331,12 @@ static void pmc_init(struct tegra_xhci_hcd *tegra, bool setup_wake) pmc_data.phy_type = TEGRA_USB_PHY_INTF_UTMI; update_speed(tegra, PMC_PORT_UTMIP_P2); tegra_usb_pmc_init(&pmc_data); - setup_wake_detect(setup_wake); } if (portmap & TEGRA_XUSB_HSIC_P0) { pmc_data.instance = PMC_PORT_UHSIC_P0; pmc_data.phy_type = TEGRA_USB_PHY_INTF_HSIC; update_speed(tegra, PMC_PORT_UHSIC_P0); tegra_usb_pmc_init(&pmc_data); - setup_wake_detect(setup_wake); } } @@ -1659,7 +1648,8 @@ static int tegra_xhci_host_elpg_entry(struct tegra_xhci_hcd *tegra) /* STEP 1.1: Do a context save of XUSB and IPFS registers */ tegra_xhci_save_xusb_ctx(tegra); - pmc_init(tegra, 1); + pmc_init(tegra); + pmc_data.pmc_ops->setup_pmc_wake_detect(&pmc_data); tegra_xhci_hs_wake_on_interrupts(tegra, true); xhci_dbg(xhci, "%s: PMC_UTMIP_UHSIC_SLEEP_CFG_0 = %x\n", __func__, @@ -1884,7 +1874,7 @@ static void tegra_xhci_war_for_tctrl_rctrl(struct tegra_xhci_hcd *tegra) * XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_0::PD_TRK = 1 */ reg = readl(tegra->padctl_base + USB2_BIAS_PAD_CTL_0_0); - reg |= (1 << 12) | (1 << 13); + reg |= (1 << 13); writel(reg, tegra->padctl_base + USB2_BIAS_PAD_CTL_0_0); /* Program these values into PMC regiseter and program the @@ -2020,7 +2010,8 @@ tegra_xhci_host_partition_elpg_exit(struct tegra_xhci_hcd *tegra) goto out; } - pmc_init(tegra, 0); + pmc_init(tegra); + pmc_data.pmc_ops->disable_pmc_bus_ctrl(&pmc_data); tegra->hc_in_elpg = false; ret = xhci_resume(tegra->xhci, 0); @@ -2950,6 +2941,8 @@ static int tegra_xhci_probe(struct platform_device *pdev) tegra_xhci_debug_read_pads(tegra); utmi_phy_pad_enable(); utmi_phy_iddq_override(false); + pmc_init(tegra); + pmc_data.pmc_ops->powerup_pmc_wake_detect(&pmc_data); return 0; @@ -2986,6 +2979,7 @@ static int tegra_xhci_remove(struct platform_device *pdev) xhci = tegra->xhci; hcd = xhci_to_hcd(xhci); + tegra_xhci_release_port_ownership(tegra, true); devm_free_irq(&pdev->dev, tegra->usb3_irq, tegra); devm_free_irq(&pdev->dev, tegra->padctl_irq, tegra); devm_free_irq(&pdev->dev, tegra->smi_irq, tegra); diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c index 23fb48f213fb..8a20c58b91e7 100644 --- a/drivers/usb/otg/tegra-otg.c +++ b/drivers/usb/otg/tegra-otg.c @@ -26,6 +26,7 @@ #include <linux/usb/gadget.h> #include <linux/platform_device.h> #include <linux/platform_data/tegra_usb.h> +#include <mach/xusb.h> #include <linux/clk.h> #include <linux/io.h> #include <linux/delay.h> @@ -218,29 +219,37 @@ static unsigned long enable_interrupt(struct tegra_otg_data *tegra, bool en) static void tegra_start_host(struct tegra_otg_data *tegra) { struct tegra_usb_otg_data *pdata = tegra->pdata; - struct platform_device *pdev, *ehci_device = pdata->ehci_device; + struct platform_device *pdev, *host_device; int val; DBG("%s(%d) Begin\n", __func__, __LINE__); if (tegra->pdev) return; + if (pdata->is_xhci) + host_device = pdata->xhci_device; + else + host_device = pdata->ehci_device; /* prepare device structure for registering host*/ - pdev = platform_device_alloc(ehci_device->name, ehci_device->id); + pdev = platform_device_alloc(host_device->name, host_device->id); if (!pdev) return ; - val = platform_device_add_resources(pdev, ehci_device->resource, - ehci_device->num_resources); + val = platform_device_add_resources(pdev, host_device->resource, + host_device->num_resources); if (val) goto error; - pdev->dev.dma_mask = ehci_device->dev.dma_mask; - pdev->dev.coherent_dma_mask = ehci_device->dev.coherent_dma_mask; + pdev->dev.dma_mask = host_device->dev.dma_mask; + pdev->dev.coherent_dma_mask = host_device->dev.coherent_dma_mask; - val = platform_device_add_data(pdev, pdata->ehci_pdata, - sizeof(struct tegra_usb_platform_data)); + if (pdata->is_xhci) + val = platform_device_add_data(pdev, pdata->xhci_pdata, + sizeof(struct tegra_xusb_platform_data)); + else + val = platform_device_add_data(pdev, pdata->ehci_pdata, + sizeof(struct tegra_usb_platform_data)); if (val) goto error; |