Re: [PATCH 2/2] net: stmmac: add fixed_phy and phy_addr support using DT file
Le 22/01/2015 18:41, Ming Lei a écrit : From: Byungho An bh74...@samsung.com This patch adds codes for DT file support, fixed_phy and phy_addr can be set in DT file. Signed-off-by: Byungho An bh74...@samsung.com (bypass check for fixed phy) Signed-off-by: Ming Leiming@canonical.com --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |5 - .../net/ethernet/stmicro/stmmac/stmmac_platform.c |7 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8c6b7c16..ddb4351 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -847,8 +847,11 @@ static int stmmac_init_phy(struct net_device *dev) * 0 rather than 0x. Catch this here and treat 0 as a non-existent * device as well. * Note: phydev-phy_id is the result of reading the UID PHY registers. + * But phy_id returned from fixed phy is always zero, so bypass the + * check for fixed phy. */ -if (phydev-phy_id == 0) { + if (phydev-phy_id == 0 (!priv-plat-phy_bus_name || + strcmp(priv-plat-phy_bus_name,fixed))) { phy_disconnect(phydev); return -ENODEV; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 879e29f..4f11491 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -128,6 +128,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, struct device_node *np = pdev-dev.of_node; struct stmmac_dma_cfg *dma_cfg; const struct of_device_id *device; + u32 phy_addr; if (!np) return -ENODEV; @@ -217,6 +218,12 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, plat-pmt = 1; } + if (of_find_property(np, fixed_phy, NULL)) { + plat-phy_bus_name = fixed; + of_property_read_u32(np, phy_addr, phy_addr); + plat-phy_addr = phy_addr; +} Humm, same here, it would look like you could use the existing Device Tree helpers for parsing and registering a fixed PHY here, provided that you use the proper binding though. BTW, Ming Lei's email is bouncing, do we have an updated email he could be contacted with? + if (of_device_is_compatible(np, snps,dwmac-3.610) || of_device_is_compatible(np, snps,dwmac-3.710)) { plat-enh_desc = 1; -- Florian -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: EXYNOS: add fixed phy support for EXYNOS5440
Le 22/01/2015 18:41, Ming Lei a écrit : From: Byungho An bh74...@samsung.com This patch adds fixed phy codes for Exynos5440. This patch can support fixed_phy. Signed-off-by: Byungho An bh74...@samsung.com Signed-off-by: Ike Panhc ike@canonical.com Signed-off-by: Ming Lei ming@canoncial.com --- arch/arm/mach-exynos/exynos.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 78eca99b..dfd5699 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -20,6 +20,8 @@ #include linux/platform_device.h #include linux/pm_domain.h #include linux/irqchip.h +#include linux/phy.h +#include linux/phy_fixed.h #include asm/cacheflush.h #include asm/hardware/cache-l2x0.h @@ -202,8 +204,21 @@ static void __init exynos_init_irq(void) exynos_map_pmu(); } +static struct fixed_phy_status fixed_phy_status __initdata = { + .link = 1, + .speed = 1000, + .duplex = 1, +}; + static void __init exynos_dt_machine_init(void) { + struct device_node *gmac_np; + unsigned int tmp; + + /* add fixed phy in need */ + gmac_np = of_find_compatible_node(NULL, NULL, snps,dwmac-3.70a); +if (of_find_property(gmac_np, fixed_phy, NULL)) + tmp = fixed_phy_add(PHY_POLL, 1, fixed_phy_status); Is there a particular reason you are doing this and not using of_phy_is_fixed_link() and of_phy_register_fixed_link()? See the gianfar and bcmsysport for examples on how to use it in a driver along with the relevant Device Tree binding in Documentation/devicetree/bindings/net/fixed-link.txt for examples. /* * This is called from smp_prepare_cpus if we've built for SMP, but * we still need to set it up for PM and firmware ops if not. -- Florian -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: sxgbe: Added tail point update
2014-05-07 1:14 GMT-07:00 Byungho An bh74...@samsung.com: This patch adds tail point update function for rx path after rx_refill function. It indicates tail point for rx dma. Signed-off-by: Byungho An bh74...@samsung.com --- drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c | 14 +- drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h |4 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c |5 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c index 49240c9..249b0e0 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c @@ -112,7 +112,7 @@ static void sxgbe_dma_channel_init(void __iomem *ioaddr, int cha_num, dma_addr = dma_rx + ((r_rsize - 1) * SXGBE_DESC_SIZE_BYTES); writel(lower_32_bits(dma_addr), - ioaddr + SXGBE_DMA_CHA_RXDESC_LADD_REG(cha_num)); + ioaddr + SXGBE_DMA_CHA_RXDESC_TAILPTR_REG(cha_num)); /* program the ring sizes */ writel(t_rsize - 1, ioaddr + SXGBE_DMA_CHA_TXDESC_RINGLEN_REG(cha_num)); writel(r_rsize - 1, ioaddr + SXGBE_DMA_CHA_RXDESC_RINGLEN_REG(cha_num)); @@ -370,6 +370,17 @@ static void sxgbe_enable_tso(void __iomem *ioaddr, u8 chan_num) writel(ctrl, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(chan_num)); } +static void sxgbe_dma_update_rxdesc_tail_ptr(void __iomem *ioaddr, u8 chan_num, + dma_addr_t dma_rx_phy, int cur_rx, + int rxsize) I think that at some point you should revisit your abstraction, all the patches that I see do take a void __iomem * argument as the first function argument, you should probably use your driver private context here. The day you support a different version of the hardware, there might be other differences that need to be taken care of. +{ + u32 reg_val; + + reg_val = (dma_rx_phy 0x) + ((cur_rx % rxsize) * + SXGBE_DESC_SIZE_BYTES); + writel(reg_val, ioaddr + SXGBE_DMA_CHA_RXDESC_TAILPTR_REG(chan_num)); +} + static const struct sxgbe_dma_ops sxgbe_dma_ops = { .init = sxgbe_dma_init, .cha_init = sxgbe_dma_channel_init, @@ -386,6 +397,7 @@ static const struct sxgbe_dma_ops sxgbe_dma_ops = { .rx_dma_int_status = sxgbe_rx_dma_int_status, .rx_watchdog= sxgbe_dma_rx_watchdog, .enable_tso = sxgbe_enable_tso, + .update_rxdesc_tail_ptr = sxgbe_dma_update_rxdesc_tail_ptr, }; const struct sxgbe_dma_ops *sxgbe_get_dma_ops(void) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h index 843fa9b..a06e01e 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h @@ -43,6 +43,10 @@ struct sxgbe_dma_ops { void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt); /* Enable TSO for each DMA channel */ void (*enable_tso)(void __iomem *ioaddr, u8 chan_num); + void (*update_rxdesc_tail_ptr)(void __iomem *ioaddr, u8 chan_num, + dma_addr_t dma_rx, int r_rentry, + int r_rsize); + }; const struct sxgbe_dma_ops *sxgbe_get_dma_ops(void); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 93bf151..7dc3449 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -1521,6 +1521,7 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) skb_put(skb, frame_len); skb-ip_summed = checksum; + skb-protocol = eth_type_trans(skb, priv-dev); if (checksum == CHECKSUM_NONE) netif_receive_skb(skb); else @@ -1530,6 +1531,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) } sxgbe_rx_refill(priv); + priv-hw-dma-update_rxdesc_tail_ptr(priv-ioaddr, qnum, + priv-rxq[qnum]-dma_rx_phy, + priv-rxq[qnum]-cur_rx, + priv-dma_rx_size); return count; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- Florian -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at
Re: [PATCH V5 1/8] sxgbe: Add device-tree binding support document
2014-03-18 11:19 GMT-07:00 Byungho An bh74...@samsung.com: From: Siva Reddy siva.kal...@samsung.com This patch adds binding document for SXGBE ethernet driver via device-tree. Signed-off-by: Siva Reddy Kallam siva.kal...@samsung.com Signed-off-by: Byungho An bh74...@samsung.com --- .../devicetree/bindings/net/samsung-sxgbe.txt | 52 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/samsung-sxgbe.txt diff --git a/Documentation/devicetree/bindings/net/samsung-sxgbe.txt b/Documentation/devicetree/bindings/net/samsung-sxgbe.txt new file mode 100644 index 000..340eff6 --- /dev/null +++ b/Documentation/devicetree/bindings/net/samsung-sxgbe.txt @@ -0,0 +1,52 @@ +* Samsung 10G Ethernet driver (SXGBE) + +Required properties: +- compatible: Should be samsung,sxgbe-v2.0a +- reg: Address and length of the register set for the device +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupts: Should contain the SXGBE interrupts + These interrupts are ordered by fixed and follows variable + trasmit DMA interrupts, receive DMA interrupts and lpi interrupt. + index 0 - this is fixed common interrupt of SXGBE and it is always + available. + index 1 to 25 - 8 variable trasmit interrupts, variable 16 receive interrupts + and 1 optional lpi interrupt. +- phy-mode: String, operation mode of the PHY interface. You should reference Documentation/devicetree/bindings/net/ethernet.txt which is more thorough about what this is about. + Supported values are: xaui, gmii. xaui is not documented in Documentation/devicetree/bindings/net/ethernet.txt, nor is it supported in include/linux/phy.h and drivers/of/of_net.c, that should be part of the patchset. +- samsung,pbl: Integer, Programmable Burst Length. + Supported values are 1, 2, 4, 8, 16, or 32. +- samsung,burst-map: Integer, Program the possible bursts supported by sxgbe + This is an interger and represents allowable DMA bursts when fixed burst. + Allowable range is 0x00-0x3F. This field is valid only when fixed burst is + enabled, otherwise ignored. +- samsung,adv-addr-mode: Boolean, Program the DMA to use Enhanced address mode. +- samsung,force-thresh-dma-mode: Boolean, Force DMA to use the threshold mode + for both tx and rx +- samsung,force-sf-dma-mode: Boolean, Force DMA to use the Store and Forward + mode for both tx and rx. This flag is ignored if force-thresh-dma-mode is set. +- samsung,phy-addr: Integer, Address of the PHY attached with SXGBE. Please don't use a custom property for that, use a phy-handle which points to an ePAPR compliant Ethernet PHY device tree node as described in Documentation/devicetree/bindings/net/phy.txt. + +Optional properties: +- mac-address: 6 bytes, mac address Did you intend to use 'local-mac-address'. 'mac-address' is described by ePAPR as: Specifies the MAC address that was last used by the boot program. This property should be used in cases where the MAC address assigned to the device by the boot program is different from the local-mac-address property. This property shall be used only if the value differs from local-mac-address property value. Does your bootloader really do something which falls into that description? If not, use 'local-mac-address'. + +Example: + + aliases { + ethernet0 = sxgbe0; + }; + + sxgbe0: ethernet@1a04 { + compatible = samsung,sxgbe-v2.0a; + reg = 0 0x1a04 0 0x1; + interrupt-parent = gic; + interrupts = 0 209 4, 0 185 4, 0 186 4, 0 187 4, +0 188 4, 0 189 4, 0 190 4, 0 191 4, +0 192 4, 0 193 4, 0 194 4, 0 195 4, +0 196 4, 0 197 4, 0 198 4, 0 199 4, +0 200 4, 0 201 4, 0 202 4, 0 203 4, +0 204 4, 0 205 4, 0 206 4, 0 207 4, +0 208 4, 0 210 4; + mac-address = []; /* Filled in by U-Boot */ The preferred way to format this is: mac-address = [ 00 00 00 00 00 00 ]; even better is something directly usable in case people copy/paste this example such as 00 11 22 33 44 55. + phy-mode = xaui; Your example is lacking a corresponding Ethernet PHY address/node. -- Florian -- To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V5 2/8] net: sxgbe: add basic framework for Samsung 10Gb ethernet driver
2014-03-18 11:19 GMT-07:00 Byungho An bh74...@samsung.com: From: Siva Reddy siva.kal...@samsung.com This patch adds support for Samsung 10Gb ethernet driver(sxgbe). - sxgbe core initialization - Tx and Rx support - MDIO support - ISRs for Tx and Rx - ifconfig support to driver Too many files to review at once, the diffstat was around 5000+ lines! You should split this into logical parts, or just submit the basic bits for now and add the features later. [snip] + ret = register_netdev(ndev); + if (ret) { + pr_err(%s: ERROR %i registering the device\n, __func__, ret); + goto error_netdev_register; + } + + priv-sxgbe_clk = clk_get(priv-device, SXGBE_RESOURCE_NAME); + if (IS_ERR(priv-sxgbe_clk)) { + netdev_warn(ndev, %s: warning: cannot get CSR clock\n, + __func__); + goto error_clk_get; + } This is racy, after register_netdev() is called, the network stack is free to use the interface, which means that as much as possible needs to be initialized before you call it, including clocks, and MDIO. + + /* If a specific clk_csr value is passed from the platform +* this means that the CSR Clock Range selection cannot be +* changed at run-time and it is fixed. Viceversa the driver'll try to +* set the MDC clock dynamically according to the csr actual +* clock input. +*/ + if (!priv-plat-clk_csr) + sxgbe_clk_csr_set(priv); + else + priv-clk_csr = priv-plat-clk_csr; + + /* MDIO bus Registration */ + ret = sxgbe_mdio_register(ndev); + if (ret 0) { + netdev_dbg(ndev, %s: MDIO bus (id: %d) registration failed\n, + __func__, priv-plat-bus_id); + goto error_mdio_register; + } Don't do this, register your MDIO bus before calling register_netdev(). + + sxgbe_check_ether_addr(priv); + + return priv; + +error_mdio_register: + clk_put(priv-sxgbe_clk); +error_clk_get: + unregister_netdev(ndev); +error_netdev_register: + netif_napi_del(priv-napi); +error_free_netdev: + free_netdev(ndev); + + return NULL; +} + +/** + * sxgbe_dvr_remove + * @ndev: net device pointer + * Description: this function resets the TX/RX processes, disables the MAC RX/TX + * changes the link status, releases the DMA descriptor rings. + */ +int sxgbe_dvr_remove(struct net_device *ndev) +{ + struct sxgbe_priv_data *priv = netdev_priv(ndev); + + netdev_info(ndev, %s: removing driver\n, __func__); + + priv-hw-dma-stop_rx(priv-ioaddr, SXGBE_RX_QUEUES); + priv-hw-dma-stop_tx(priv-ioaddr, SXGBE_TX_QUEUES); + + priv-hw-mac-enable_tx(priv-ioaddr, false); + priv-hw-mac-enable_rx(priv-ioaddr, false); + + netif_napi_del(priv-napi); + + sxgbe_mdio_unregister(ndev); + + netif_carrier_off(ndev); This is not required, both the PHY library and the network stack will do that for you. [snip] + /* register with kernel subsystem */ + err = mdiobus_register(mdio_bus); + if (err != 0) { + netdev_err(ndev, mdiobus register failed\n); + goto mdiobus_err; + } + + for (phy_addr = 0; phy_addr PHY_MAX_ADDR; phy_addr++) { + struct phy_device *phy = mdio_bus-phy_map[phy_addr]; + if (phy) { + char irq_num[4]; + char *irq_str; + /* If an IRQ was provided to be assigned after +* the bus probe, do it here. +*/ + if ((mdio_data-irqs == NULL) + (mdio_data-probed_phy_irq 0)) { + irqlist[phy_addr] = mdio_data-probed_phy_irq; + phy-irq = mdio_data-probed_phy_irq; + } + + /* If we're going to bind the MAC to this PHY bus, +* and no PHY number was provided to the MAC, +* use the one probed here. +*/ + if (priv-plat-phy_addr == -1) + priv-plat-phy_addr = phy_addr; + + act = (priv-plat-phy_addr == phy_addr); + switch (phy-irq) { + case PHY_POLL: + irq_str = POLL; + break; + case PHY_IGNORE_INTERRUPT: + irq_str = IGNORE; + break; + default: + sprintf(irq_num, %d, phy-irq); + irq_str = irq_num; + break; +
[PATCH 15/32 v3] USB: ohci: merge ohci_finish_controller_resume with ohci_resume
Merge ohci_finish_controller_resume with ohci_resume as suggested by Alan Stern. Since ohci_finish_controller_resume no longer exists, update the various OHCI drivers to call ohci_resume() instead. Some drivers used to set themselves the bit HCD_FLAG_HW_ACCESSIBLE, which is now handled by ohci_resume(). Acked-by: Jingoo Han jg1@samsung.com Acked-by: Nicolas Ferre nicolas.fe...@atmel.com Signed-off-by: Florian Fainelli flor...@openwrt.org --- Changes in v3: - rebased against greg's latest usb-next Changes in v2: - added Nicolas and Jingoo's Acked-by drivers/usb/host/ohci-at91.c |2 +- drivers/usb/host/ohci-ep93xx.c |2 +- drivers/usb/host/ohci-exynos.c |5 + drivers/usb/host/ohci-hcd.c | 41 +++-- drivers/usb/host/ohci-hub.c | 42 -- drivers/usb/host/ohci-omap.c |2 +- drivers/usb/host/ohci-platform.c |2 +- drivers/usb/host/ohci-pxa27x.c |2 +- drivers/usb/host/ohci-s3c2410.c |3 +-- drivers/usb/host/ohci-spear.c|2 +- drivers/usb/host/ohci-tmio.c |2 +- 11 files changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0bf72f9..908d84a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) if (!clocked) at91_start_clock(); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #else diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dbfbd1d..a982f04 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ep93xx_start_hc(pdev-dev); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #endif diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 20a5008..929a494 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -252,10 +252,7 @@ static int exynos_ohci_resume(struct device *dev) if (pdata pdata-phy_init) pdata-phy_init(pdev, S5P_USB_PHY_HOST); - /* Mark hardware accessible again as we are out of D3 state by now */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); - - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 31a4616..8e17f17 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1007,13 +1007,50 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + boolneed_reinit = false; + set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* Make sure resume from hibernation re-enumerates everything */ if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); + ohci_usb_reset(ohci); + + /* See if the controller is already running or has been reset */ + ohci-hc_control = ohci_readl(ohci, ohci-regs-control); + if (ohci-hc_control (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci-hc_control OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(ohci-lock); + ohci_rh_resume(ohci); + ohci_rh_suspend(ohci, 0); + spin_unlock_irq(ohci-lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, powerup ports\n); + for (port = 0; port ohci-num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + ohci-regs-roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, ohci-regs-intrenable); + ohci_readl(ohci, ohci-regs-intrenable); + msleep(20); + } + + usb_hcd_resume_root_hub(hcd); - ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f3619e..db09dae 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } -/* Carry out the final steps of resuming the controller device
[PATCH 15/32 v2] USB: ohci: merge ohci_finish_controller_resume with ohci_resume
Merge ohci_finish_controller_resume with ohci_resume as suggested by Alan Stern. Since ohci_finish_controller_resume no longer exists, update the various OHCI drivers to call ohci_resume() instead. Some drivers used to set themselves the bit HCD_FLAG_HW_ACCESSIBLE, which is now handled by ohci_resume(). Acked-by: Jingoo Han jg1@samsung.com Acked-by: Nicolas Ferre nicolas.fe...@atmel.com Signed-off-by: Florian Fainelli flor...@openwrt.org --- Changes since v1: - added Nicolas and Jingoo's Acked-by drivers/usb/host/ohci-at91.c |2 +- drivers/usb/host/ohci-ep93xx.c |2 +- drivers/usb/host/ohci-exynos.c |5 + drivers/usb/host/ohci-hcd.c | 41 +++-- drivers/usb/host/ohci-hub.c | 42 -- drivers/usb/host/ohci-omap.c |2 +- drivers/usb/host/ohci-platform.c |2 +- drivers/usb/host/ohci-pxa27x.c |2 +- drivers/usb/host/ohci-s3c2410.c |3 +-- drivers/usb/host/ohci-spear.c|2 +- drivers/usb/host/ohci-tmio.c |2 +- 11 files changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0bf72f9..908d84a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) if (!clocked) at91_start_clock(); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #else diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dbfbd1d..a982f04 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ep93xx_start_hc(pdev-dev); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #endif diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index fc3091b..53c5a989 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -252,10 +252,7 @@ static int exynos_ohci_resume(struct device *dev) if (pdata pdata-phy_init) pdata-phy_init(pdev, S5P_USB_PHY_HOST); - /* Mark hardware accessible again as we are out of D3 state by now */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); - - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index acf8c83..d97dc48 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1005,13 +1005,50 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + boolneed_reinit = false; + set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* Make sure resume from hibernation re-enumerates everything */ if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); + ohci_usb_reset(ohci); + + /* See if the controller is already running or has been reset */ + ohci-hc_control = ohci_readl(ohci, ohci-regs-control); + if (ohci-hc_control (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci-hc_control OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(ohci-lock); + ohci_rh_resume(ohci); + ohci_rh_suspend(ohci, 0); + spin_unlock_irq(ohci-lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, powerup ports\n); + for (port = 0; port ohci-num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + ohci-regs-roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, ohci-regs-intrenable); + ohci_readl(ohci, ohci-regs-intrenable); + msleep(20); + } + + usb_hcd_resume_root_hub(hcd); - ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f3619e..db09dae 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } -/* Carry out the final steps of resuming the controller device */ -static void __maybe_unused
[PATCH 14/24] USB: ohci: merge ohci_finish_controller_resume with ohci_resume
Merge ohci_finish_controller_resume with ohci_resume as suggested by Alan Stern. Since ohci_finish_controller_resume no longer exists, update the various OHCI drivers to call ohci_resume() instead. Some drivers used to set themselves the bit HCD_FLAG_HW_ACCESSIBLE, which is now handled by ohci_resume(). Signed-off-by: Florian Fainelli flor...@openwrt.org --- drivers/usb/host/ohci-at91.c |2 +- drivers/usb/host/ohci-ep93xx.c |2 +- drivers/usb/host/ohci-exynos.c |5 + drivers/usb/host/ohci-hcd.c | 41 +++-- drivers/usb/host/ohci-hub.c | 42 -- drivers/usb/host/ohci-omap.c |2 +- drivers/usb/host/ohci-platform.c |2 +- drivers/usb/host/ohci-pxa27x.c |2 +- drivers/usb/host/ohci-s3c2410.c |3 +-- drivers/usb/host/ohci-spear.c|2 +- drivers/usb/host/ohci-tmio.c |2 +- 11 files changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0bf72f9..908d84a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) if (!clocked) at91_start_clock(); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #else diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dbfbd1d..a982f04 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ep93xx_start_hc(pdev-dev); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #endif diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index fc3091b..53c5a989 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -252,10 +252,7 @@ static int exynos_ohci_resume(struct device *dev) if (pdata pdata-phy_init) pdata-phy_init(pdev, S5P_USB_PHY_HOST); - /* Mark hardware accessible again as we are out of D3 state by now */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); - - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5d30992..568bdb3 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1003,13 +1003,50 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + boolneed_reinit = false; + set_bit(HCD_FLAG_HW_ACCESSIBLE, hcd-flags); /* Make sure resume from hibernation re-enumerates everything */ if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); + ohci_usb_reset(ohci); + + /* See if the controller is already running or has been reset */ + ohci-hc_control = ohci_readl(ohci, ohci-regs-control); + if (ohci-hc_control (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci-hc_control OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(ohci-lock); + ohci_rh_resume(ohci); + ohci_rh_suspend(ohci, 0); + spin_unlock_irq(ohci-lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, powerup ports\n); + for (port = 0; port ohci-num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + ohci-regs-roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, ohci-regs-intrenable); + ohci_readl(ohci, ohci-regs-intrenable); + msleep(20); + } + + usb_hcd_resume_root_hub(hcd); - ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f3619e..db09dae 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } -/* Carry out the final steps of resuming the controller device */ -static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int port; - bool