From 0a78303054f9fd89d382cc14f0b8dff69ac937cb Mon Sep 17 00:00:00 2001 From: Venkat Moganty Date: Thu, 8 Jul 2010 10:29:21 +0530 Subject: [tegra-usb] Fix USB-OTG for CONFIG_USB_SUSPEND When CONFIG_USB_SUSPEND is enabled, after auto suspend by the usb core driver, USB devices(mouse,keyboard etc.) are not recognised. After auto suspend device state goes to suspend and not resuming to the address. This is fixed by changing the device state to address state on USB cable insertion. Bug 674938 Bug 698734 Change-Id: I837562fd1eb020f400824f2d475289df5fbc1f83 Reviewed-on: http://git-master/r/3494 Reviewed-by: Gary King Tested-by: Hanumanth Venkateswa Moganty --- drivers/usb/host/ehci-tegra.c | 24 +++++++++++++++++++++--- drivers/usb/otg/tegra-otg.c | 1 - 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index a5a32021f2a6..21d18bebb562 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -35,6 +35,7 @@ #include "nvrm_power.h" #include "nvrm_hardware_access.h" #include "nvddk_usbphy.h" +#include "../core/usb.h" #define TEGRA_USB_ID_INT_ENABLE (1 << 0) #define TEGRA_USB_ID_INT_STATUS (1 << 1) @@ -58,7 +59,7 @@ static void tegra_ehci_busy_hint_work(struct work_struct* work) struct tegra_hcd_platform_data *pdata = container_of(work, struct tegra_hcd_platform_data, work); NvDdkUsbPhyIoctl_UsbBusyHintsOnOffInputArgs busyhint; - busyhint.OnOff = NV_TRUE; + busyhint.OnOff = true; /* USB transfers will be done with in 1 sec, this need to be * * fine tuned (if required). with safe limit set to 2 sec */ @@ -76,7 +77,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd) pdata = hcd->self.controller->platform_data; - NV_ASSERT_SUCCESS(NvDdkUsbPhyPowerUp(pdata->hUsbPhy, NV_TRUE, 0)); + NV_ASSERT_SUCCESS(NvDdkUsbPhyPowerUp(pdata->hUsbPhy, true, 0)); ehci->host_resumed = 1; } @@ -87,7 +88,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd) pdata = hcd->self.controller->platform_data; - NV_ASSERT_SUCCESS(NvDdkUsbPhyPowerDown(pdata->hUsbPhy, NV_TRUE, 0)); + NV_ASSERT_SUCCESS(NvDdkUsbPhyPowerDown(pdata->hUsbPhy, true, 0)); ehci->host_resumed = 0; } @@ -142,6 +143,7 @@ static int tegra_ehci_hub_control ( && ehci->host_reinited) { /* indicate hcd flags, that hardware is not accessable now */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + ehci_halt(ehci); tegra_ehci_power_down(hcd); ehci->transceiver->state = OTG_STATE_UNDEFINED; ehci->host_reinited = 0; @@ -215,6 +217,7 @@ static void tegra_ehci_irq_work(struct work_struct* irq_work) struct usb_hcd *hcd = ehci_to_hcd(ehci); struct tegra_hcd_platform_data *pdata; u32 status; + bool kick_rhub = false; pdata = hcd->self.controller->platform_data; @@ -224,6 +227,8 @@ static void tegra_ehci_irq_work(struct work_struct* irq_work) if (!ehci->host_reinited) { ehci->host_reinited = 1; tegra_ehci_power_up(hcd); + if (hcd->state == HC_STATE_SUSPENDED) + kick_rhub = true; tegra_ehci_restart(hcd); } } @@ -238,9 +243,18 @@ static void tegra_ehci_irq_work(struct work_struct* irq_work) tegra_ehci_power_down(hcd); } else { tegra_ehci_power_up(hcd); + if (hcd->state == HC_STATE_SUSPENDED) + kick_rhub = true; } } } + + if (kick_rhub && hcd->rh_registered) { + hcd->poll_rh = 0; + usb_set_device_state (hcd->self.root_hub, USB_STATE_ADDRESS); + hcd->state = HC_STATE_RUNNING; + usb_kick_khubd (hcd->self.root_hub); + } } @@ -260,6 +274,8 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) if (ehci->transceiver->state == OTG_STATE_A_HOST) { if (!ehci->host_reinited) { schedule_work(&ehci->irq_work); + spin_unlock (&ehci->lock); + return IRQ_HANDLED; } } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { if (!ehci->host_reinited) { @@ -281,6 +297,8 @@ static irqreturn_t tegra_ehci_irq (struct usb_hcd *hcd) /* Check if there is any ID pin interrupt */ if (status & TEGRA_USB_ID_INT_STATUS) { schedule_work(&ehci->irq_work); + spin_unlock (&ehci->lock); + return IRQ_HANDLED; } } } diff --git a/drivers/usb/otg/tegra-otg.c b/drivers/usb/otg/tegra-otg.c index 8bf00010edcc..42b292c90fd5 100644 --- a/drivers/usb/otg/tegra-otg.c +++ b/drivers/usb/otg/tegra-otg.c @@ -81,7 +81,6 @@ static irqreturn_t tegra_otg_irq(int irq, void *data) tegra_otg->otg.state = OTG_STATE_A_SUSPEND; } else { tegra_otg->otg.state = OTG_STATE_A_HOST; - hcd->state = HC_STATE_RUNNING; /* set HCD flags to start host ISR */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); } -- cgit v1.2.3