From ba1af96f79573e96b5929bfba481ecb95f28ff25 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 27 Apr 2015 16:50:04 +0200 Subject: [PATCH] sunxi: usb: Do not call phy_probe from hcd code The 2/3 usb-phys on the sunxi SoCs are really a single separate functional block, and are modelled as such in devicetree. So once we've moved all the sunxi usb code to the driver-model then phy_probe will be called once for the entire block from the driver-model enumeration code. Move to this now as this also avoids problems with phy_probe being called multiple times once we introduce ohci support. This also allows us to get rid of the sunxi_usb_phy_enabled_count variable as phy_probe now is guaranteed to be called only once. Since we're effectively rewriting the probe / remove functions, move them to the end of the file while we are at it, as that is the most logical place for them. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/usb_phy.c | 106 ++++++++++++---------- arch/arm/include/asm/arch-sunxi/usb_phy.h | 4 +- board/sunxi/board.c | 4 + drivers/usb/host/ehci-sunxi.c | 8 +- drivers/usb/musb-new/sunxi.c | 7 +- include/configs/sun4i.h | 2 + include/configs/sun5i.h | 2 + include/configs/sun6i.h | 2 + include/configs/sun7i.h | 2 + include/configs/sun8i.h | 2 + 10 files changed, 76 insertions(+), 63 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index c238d38a1a..1f85dec07e 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -54,7 +54,7 @@ static struct sunxi_usb_phy { .usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK, .id = 1, }, -#if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1) +#if CONFIG_SUNXI_USB_PHYS >= 3 { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .id = 2, @@ -62,8 +62,6 @@ static struct sunxi_usb_phy { #endif }; -static int sunxi_usb_phy_enabled_count; - static int get_vbus_gpio(int index) { switch (index) { @@ -167,57 +165,17 @@ void sunxi_usb_phy_enable_squelch_detect(int index, int enable) usb_phy_write(phy, 0x3c, enable ? 0 : 2, 2); } -int sunxi_usb_phy_probe(int index) -{ - struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; - int ret = 0; - - phy->gpio_vbus = get_vbus_gpio(index); - if (phy->gpio_vbus >= 0) { - ret |= gpio_request(phy->gpio_vbus, "usbc_vbus"); - ret |= gpio_direction_output(phy->gpio_vbus, 0); - } - - phy->gpio_vbus_det = get_vbus_detect_gpio(index); - if (phy->gpio_vbus_det >= 0) { - ret |= gpio_request(phy->gpio_vbus_det, "usbc_vbus_det"); - ret |= gpio_direction_input(phy->gpio_vbus_det); - } - - return ret; -} - -int sunxi_usb_phy_remove(int index) -{ - struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; - int ret = 0; - - if (phy->gpio_vbus >= 0) - ret |= gpio_free(phy->gpio_vbus); - - if (phy->gpio_vbus_det >= 0) - ret |= gpio_free(phy->gpio_vbus_det); - - return ret; -} - void sunxi_usb_phy_init(int index) { struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - /* enable common PHY only once */ - if (sunxi_usb_phy_enabled_count == 0) - setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); - setbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); sunxi_usb_phy_config(phy); if (phy->id != 0) sunxi_usb_phy_passby(index, SUNXI_USB_PASSBY_EN); - - sunxi_usb_phy_enabled_count++; } void sunxi_usb_phy_exit(int index) @@ -229,12 +187,6 @@ void sunxi_usb_phy_exit(int index) sunxi_usb_phy_passby(index, !SUNXI_USB_PASSBY_EN); clrbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); - - /* disable common PHY only once, for the last enabled phy */ - if (sunxi_usb_phy_enabled_count == 1) - clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); - - sunxi_usb_phy_enabled_count--; } void sunxi_usb_phy_power_on(int index) @@ -276,3 +228,59 @@ int sunxi_usb_phy_vbus_detect(int index) return err; } + +int sunxi_usb_phy_probe(void) +{ + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_usb_phy *phy; + int i, ret = 0; + + for (i = 0; i < CONFIG_SUNXI_USB_PHYS; i++) { + phy = &sunxi_usb_phy[i]; + + phy->gpio_vbus = get_vbus_gpio(i); + if (phy->gpio_vbus >= 0) { + ret = gpio_request(phy->gpio_vbus, "usb_vbus"); + if (ret) + return ret; + ret = gpio_direction_output(phy->gpio_vbus, 0); + if (ret) + return ret; + } + + phy->gpio_vbus_det = get_vbus_detect_gpio(i); + if (phy->gpio_vbus_det >= 0) { + ret = gpio_request(phy->gpio_vbus_det, "usb_vbus_det"); + if (ret) + return ret; + ret = gpio_direction_input(phy->gpio_vbus_det); + if (ret) + return ret; + } + } + + setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); + + return 0; +} + +int sunxi_usb_phy_remove(void) +{ + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_usb_phy *phy; + int i; + + clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); + + for (i = 0; i < CONFIG_SUNXI_USB_PHYS; i++) { + phy = &sunxi_usb_phy[i]; + + if (phy->gpio_vbus >= 0) + gpio_free(phy->gpio_vbus); + + if (phy->gpio_vbus_det >= 0) + gpio_free(phy->gpio_vbus_det); + } + + return 0; +} diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h index 14ed0814dd..b7b831e24a 100644 --- a/arch/arm/include/asm/arch-sunxi/usb_phy.h +++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h @@ -10,8 +10,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -int sunxi_usb_phy_probe(int index); -int sunxi_usb_phy_remove(int index); +int sunxi_usb_phy_probe(void); +int sunxi_usb_phy_remove(void); void sunxi_usb_phy_init(int index); void sunxi_usb_phy_exit(int index); void sunxi_usb_phy_power_on(int index); diff --git a/board/sunxi/board.c b/board/sunxi/board.c index be76e62d2a..d9f7691373 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -510,6 +510,10 @@ int misc_init_r(void) } } + ret = sunxi_usb_phy_probe(); + if (ret) + return ret; + #if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET) musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE); #endif diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index 9e74a0babf..0edb6438cb 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -20,11 +20,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int ahb_gate_offset, err; - - err = sunxi_usb_phy_probe(index + 1); - if (err) - return err; + int ahb_gate_offset; ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 : AHB_GATE_OFFSET_USB_EHCI0; @@ -66,5 +62,5 @@ int ehci_hcd_stop(int index) #endif clrbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset); - return sunxi_usb_phy_remove(index + 1); + return 0; } diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 4f08f9f906..e8a3a23aa4 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -250,15 +250,10 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); - err = sunxi_usb_phy_probe(0); - if (err) - return err; - if (is_host_enabled(musb)) { err = sunxi_usb_phy_vbus_detect(0); if (err) { eprintf("Error: A charger is plugged into the OTG\n"); - sunxi_usb_phy_remove(0); return -EIO; } } @@ -296,7 +291,7 @@ static int sunxi_musb_exit(struct musb *musb) sunxi_usb_phy_power_off(0); sunxi_usb_phy_exit(0); - return sunxi_usb_phy_remove(0); + return 0; } const struct musb_platform_ops sunxi_musb_ops = { diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h index 7cd5c69d3a..ea079eb5f7 100644 --- a/include/configs/sun4i.h +++ b/include/configs/sun4i.h @@ -17,6 +17,8 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif +#define CONFIG_SUNXI_USB_PHYS 3 + /* * Include common sunxi configuration where most the settings are */ diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h index e0470d4282..d257659903 100644 --- a/include/configs/sun5i.h +++ b/include/configs/sun5i.h @@ -17,6 +17,8 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif +#define CONFIG_SUNXI_USB_PHYS 2 + /* * Include common sunxi configuration where most the settings are */ diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h index 617c1cdfde..2c24bd2312 100644 --- a/include/configs/sun6i.h +++ b/include/configs/sun6i.h @@ -20,6 +20,8 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif +#define CONFIG_SUNXI_USB_PHYS 3 + /* * Include common sunxi configuration where most the settings are */ diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index 7fa7cec244..56101a9ffc 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -18,6 +18,8 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif +#define CONFIG_SUNXI_USB_PHYS 3 + #define CONFIG_ARMV7_PSCI 1 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE #define CONFIG_TIMER_CLK_FREQ 24000000 diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 79796d75d3..7111c635c1 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -18,6 +18,8 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif +#define CONFIG_SUNXI_USB_PHYS 2 + /* * Include common sunxi configuration where most the settings are */ -- 2.39.2