diff options
author | Michael Grzeschik <m.grzeschik@pengutronix.de> | 2014-10-13 09:53:03 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-03 15:34:00 -0800 |
commit | 11a7e59405148c855e0a9d13588930ccec02c150 (patch) | |
tree | a8e21a87496d8ec3fee589dfea21766d2813d58f /drivers/usb/host/ehci-hcd.c | |
parent | e28e2f2f7c42e5b9dd4c965a0245267e44a8a7ae (diff) | |
download | linux-stable-11a7e59405148c855e0a9d13588930ccec02c150.tar.gz linux-stable-11a7e59405148c855e0a9d13588930ccec02c150.tar.bz2 linux-stable-11a7e59405148c855e0a9d13588930ccec02c150.zip |
usb: ehci: add ehci_port_power interface
The current EHCI implementation is prepared to toggle the
PORT_POWER bit to enable or disable a USB-Port. In some
cases this port power can not be just toggled by the PORT_POWER
bit, and the gpio-regulator is needed to be toggled too.
This patch defines a port power control interface ehci_port_power for
ehci core use, it toggles PORT_POWER bit as well as calls platform
defined .port_power if it is defined.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Acked-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 15feaf924b71..df75b8e7d157 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -311,6 +311,7 @@ static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable); #include "ehci-timer.c" #include "ehci-hub.c" @@ -329,9 +330,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) { int port = HCS_N_PORTS(ehci->hcs_params); - while (port--) + while (port--) { ehci_writel(ehci, PORT_RWC_BITS, &ehci->regs->port_status[port]); + spin_unlock_irq(&ehci->lock); + ehci_port_power(ehci, port, false); + spin_lock_irq(&ehci->lock); + } } /* @@ -1233,6 +1238,8 @@ 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->port_power) + drv->port_power = over->port_power; } } EXPORT_SYMBOL_GPL(ehci_init_driver); |