This patch (as1623) removes the ehci_port_power() routine and all the places that call it. There's no reason for ehci-hcd to change the port power settings; the hub driver takes care of all that stuff. There is one exception: When the controller is resumed from hibernation or following a loss of power, the ports that are supposed to be handed over to a companion controller must be powered on first. Otherwise the handover won't work. This process is not visible to the hub driver, so it has to be handled in ehci-hcd. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> --- arch/arm/mach-cns3xxx/cns3420vb.c | 1 - arch/mips/ath79/dev-usb.c | 2 -- arch/mips/loongson1/common/platform.c | 1 - drivers/usb/chipidea/host.c | 18 +----------------- drivers/usb/host/ehci-atmel.c | 9 +-------- drivers/usb/host/ehci-fsl.c | 1 - drivers/usb/host/ehci-grlib.c | 18 +----------------- drivers/usb/host/ehci-hcd.c | 21 --------------------- drivers/usb/host/ehci-hub.c | 13 +++++++++++++ drivers/usb/host/ehci-msm.c | 1 - drivers/usb/host/ehci-mxc.c | 8 +------- drivers/usb/host/ehci-octeon.c | 3 --- drivers/usb/host/ehci-omap.c | 3 --- drivers/usb/host/ehci-orion.c | 16 +--------------- drivers/usb/host/ehci-pci.c | 1 - drivers/usb/host/ehci-platform.c | 5 ----- drivers/usb/host/ehci-pmcmsp.c | 1 - drivers/usb/host/ehci-sh.c | 9 +-------- drivers/usb/host/ehci-spear.c | 9 +-------- drivers/usb/host/ehci-tegra.c | 8 +------- include/linux/usb/ehci_pdriver.h | 2 -- 21 files changed, 21 insertions(+), 129 deletions(-) Index: usb-3.7/drivers/usb/host/ehci-hcd.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-hcd.c +++ usb-3.7/drivers/usb/host/ehci-hcd.c @@ -371,24 +371,6 @@ static void ehci_shutdown(struct usb_hcd hrtimer_cancel(&ehci->hrtimer); } -static void ehci_port_power (struct ehci_hcd *ehci, int is_on) -{ - unsigned port; - - if (!HCS_PPC (ehci->hcs_params)) - return; - - ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down"); - for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) - (void) ehci_hub_control(ehci_to_hcd(ehci), - is_on ? SetPortFeature : ClearPortFeature, - USB_PORT_FEAT_POWER, - port--, NULL, 0); - /* Flush those writes */ - ehci_readl(ehci, &ehci->regs->command); - msleep(20); -} - /*-------------------------------------------------------------------------*/ /* @@ -1184,9 +1166,6 @@ static int __maybe_unused ehci_resume(st ehci->rh_state = EHCI_RH_SUSPENDED; spin_unlock_irq(&ehci->lock); - /* here we "know" root ports should always stay powered */ - ehci_port_power(ehci, 1); - return 1; } Index: usb-3.7/drivers/usb/host/ehci-hub.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-hub.c +++ usb-3.7/drivers/usb/host/ehci-hub.c @@ -56,6 +56,19 @@ static void ehci_handover_companion_port if (!ehci->owned_ports) return; + /* Make sure the ports are powered */ + port = HCS_N_PORTS(ehci->hcs_params); + while (port--) { + if (test_bit(port, &ehci->owned_ports)) { + reg = &ehci->regs->port_status[port]; + status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; + if (!(status & PORT_POWER)) { + status |= PORT_POWER; + ehci_writel(ehci, status, reg); + } + } + } + /* Give the connections some time to appear */ msleep(20); Index: usb-3.7/include/linux/usb/ehci_pdriver.h =================================================================== --- usb-3.7.orig/include/linux/usb/ehci_pdriver.h +++ usb-3.7/include/linux/usb/ehci_pdriver.h @@ -41,8 +41,6 @@ struct usb_ehci_pdata { unsigned has_synopsys_hc_bug:1; unsigned big_endian_desc:1; unsigned big_endian_mmio:1; - unsigned port_power_on:1; - unsigned port_power_off:1; unsigned no_io_watchdog:1; /* Turn on all power and clocks */ Index: usb-3.7/arch/arm/mach-cns3xxx/cns3420vb.c =================================================================== --- usb-3.7.orig/arch/arm/mach-cns3xxx/cns3420vb.c +++ usb-3.7/arch/arm/mach-cns3xxx/cns3420vb.c @@ -162,7 +162,6 @@ static void csn3xxx_usb_power_off(struct } static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { - .port_power_off = 1, .power_on = csn3xxx_usb_power_on, .power_off = csn3xxx_usb_power_off, }; Index: usb-3.7/arch/mips/ath79/dev-usb.c =================================================================== --- usb-3.7.orig/arch/mips/ath79/dev-usb.c +++ usb-3.7/arch/mips/ath79/dev-usb.c @@ -50,13 +50,11 @@ static u64 ath79_ehci_dmamask = DMA_BIT_ static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { .has_synopsys_hc_bug = 1, - .port_power_off = 1, }; static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { .caps_offset = 0x100, .has_tt = 1, - .port_power_off = 1, }; static struct platform_device ath79_ehci_device = { Index: usb-3.7/arch/mips/loongson1/common/platform.c =================================================================== --- usb-3.7.orig/arch/mips/loongson1/common/platform.c +++ usb-3.7/arch/mips/loongson1/common/platform.c @@ -109,7 +109,6 @@ static struct resource ls1x_ehci_resourc }; static struct usb_ehci_pdata ls1x_ehci_pdata = { - .port_power_off = 1, }; struct platform_device ls1x_ehci_device = { Index: usb-3.7/drivers/usb/host/ehci-atmel.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-atmel.c +++ usb-3.7/drivers/usb/host/ehci-atmel.c @@ -53,18 +53,11 @@ static void atmel_stop_ehci(struct platf static int ehci_atmel_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; /* registers start at offset 0x0 */ ehci->caps = hcd->regs; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; + return ehci_setup(hcd); } static const struct hc_driver ehci_atmel_hc_driver = { Index: usb-3.7/drivers/usb/host/ehci-fsl.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-fsl.c +++ usb-3.7/drivers/usb/host/ehci-fsl.c @@ -349,7 +349,6 @@ static int ehci_fsl_reinit(struct ehci_h { if (ehci_fsl_usb_setup(ehci)) return -EINVAL; - ehci_port_power(ehci, 0); return 0; } Index: usb-3.7/drivers/usb/host/ehci-grlib.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-grlib.c +++ usb-3.7/drivers/usb/host/ehci-grlib.c @@ -34,22 +34,6 @@ #define GRUSBHC_HCIVERSION 0x0100 /* Known value of cap. reg. HCIVERSION */ -/* called during probe() after chip reset completes */ -static int ehci_grlib_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 1); - - return retval; -} - - static const struct hc_driver ehci_grlib_hc_driver = { .description = hcd_name, .product_desc = "GRLIB GRUSBHC EHCI", @@ -64,7 +48,7 @@ static const struct hc_driver ehci_grlib /* * basic lifecycle operations */ - .reset = ehci_grlib_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, Index: usb-3.7/drivers/usb/host/ehci-msm.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-msm.c +++ usb-3.7/drivers/usb/host/ehci-msm.c @@ -53,7 +53,6 @@ static int ehci_msm_reset(struct usb_hcd /* Disable streaming mode and select host mode */ writel(0x13, USB_USBMODE); - ehci_port_power(ehci, 1); return 0; } Index: usb-3.7/drivers/usb/host/ehci-mxc.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-mxc.c +++ usb-3.7/drivers/usb/host/ehci-mxc.c @@ -40,16 +40,10 @@ struct ehci_mxc_priv { static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; hcd->has_tt = 1; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - return 0; + return ehci_setup(hcd); } static const struct hc_driver ehci_mxc_hc_driver = { Index: usb-3.7/drivers/usb/host/ehci-octeon.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-octeon.c +++ usb-3.7/drivers/usb/host/ehci-octeon.c @@ -159,9 +159,6 @@ static int ehci_octeon_drv_probe(struct platform_set_drvdata(pdev, hcd); - /* root ports should always stay powered */ - ehci_port_power(ehci, 1); - return 0; err3: ehci_octeon_stop(); Index: usb-3.7/drivers/usb/host/ehci-omap.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-omap.c +++ usb-3.7/drivers/usb/host/ehci-omap.c @@ -146,9 +146,6 @@ static int omap_ehci_init(struct usb_hcd gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); } - /* root ports should always stay powered */ - ehci_port_power(ehci, 1); - return rc; } Index: usb-3.7/drivers/usb/host/ehci-orion.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-orion.c +++ usb-3.7/drivers/usb/host/ehci-orion.c @@ -101,20 +101,6 @@ static void orion_usb_phy_v1_setup(struc wrl(USB_MODE, 0x13); } -static int ehci_orion_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; -} - static const struct hc_driver ehci_orion_hc_driver = { .description = hcd_name, .product_desc = "Marvell Orion EHCI", @@ -129,7 +115,7 @@ static const struct hc_driver ehci_orion /* * basic lifecycle operations */ - .reset = ehci_orion_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, Index: usb-3.7/drivers/usb/host/ehci-pci.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-pci.c +++ usb-3.7/drivers/usb/host/ehci-pci.c @@ -297,7 +297,6 @@ static int ehci_pci_setup(struct usb_hcd ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif - ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; Index: usb-3.7/drivers/usb/host/ehci-platform.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-platform.c +++ usb-3.7/drivers/usb/host/ehci-platform.c @@ -40,11 +40,6 @@ static int ehci_platform_reset(struct us if (pdata->no_io_watchdog) ehci->need_io_watchdog = 0; - if (pdata->port_power_on) - ehci_port_power(ehci, 1); - if (pdata->port_power_off) - ehci_port_power(ehci, 0); - return 0; } Index: usb-3.7/drivers/usb/host/ehci-pmcmsp.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-pmcmsp.c +++ usb-3.7/drivers/usb/host/ehci-pmcmsp.c @@ -90,7 +90,6 @@ static int ehci_msp_setup(struct usb_hcd return retval; usb_hcd_tdi_set_mode(ehci); - ehci_port_power(ehci, 0); return retval; } Index: usb-3.7/drivers/usb/host/ehci-sh.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-sh.c +++ usb-3.7/drivers/usb/host/ehci-sh.c @@ -21,17 +21,10 @@ struct ehci_sh_priv { static int ehci_sh_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; ehci->caps = hcd->regs; - ret = ehci_setup(hcd); - if (unlikely(ret)) - return ret; - - ehci_port_power(ehci, 0); - - return ret; + return ehci_setup(hcd); } static const struct hc_driver ehci_sh_hc_driver = { Index: usb-3.7/drivers/usb/host/ehci-spear.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-spear.c +++ usb-3.7/drivers/usb/host/ehci-spear.c @@ -37,18 +37,11 @@ static void spear_stop_ehci(struct spear static int ehci_spear_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval = 0; /* registers start at offset 0x0 */ ehci->caps = hcd->regs; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; + return ehci_setup(hcd); } static const struct hc_driver ehci_spear_hc_driver = { Index: usb-3.7/drivers/usb/host/ehci-tegra.c =================================================================== --- usb-3.7.orig/drivers/usb/host/ehci-tegra.c +++ usb-3.7/drivers/usb/host/ehci-tegra.c @@ -280,7 +280,6 @@ static void tegra_ehci_shutdown(struct u static int tegra_ehci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; @@ -288,12 +287,7 @@ static int tegra_ehci_setup(struct usb_h /* switch to host mode */ hcd->has_tt = 1; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 1); - return retval; + return ehci_setup(hcd); } struct dma_aligned_buffer { Index: usb-3.7/drivers/usb/chipidea/host.c =================================================================== --- usb-3.7.orig/drivers/usb/chipidea/host.c +++ usb-3.7/drivers/usb/chipidea/host.c @@ -31,22 +31,6 @@ #include "bits.h" #include "host.h" -static int ci_ehci_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; - - hcd->has_tt = 1; - - ret = ehci_setup(hcd); - if (ret) - return ret; - - ehci_port_power(ehci, 0); - - return ret; -} - static const struct hc_driver ci_ehci_hc_driver = { .description = "ehci_hcd", .product_desc = "ChipIdea HDRC EHCI", @@ -61,7 +45,7 @@ static const struct hc_driver ci_ehci_hc /* * basic lifecycle operations */ - .reset = ci_ehci_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html