diff options
author | Hans de Goede <hdegoede@redhat.com> | 2015-04-27 16:57:54 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2015-05-04 16:51:55 +0200 |
commit | fd01ae1384a67c354eb53fc8a4c1e0d519014ae8 (patch) | |
tree | ab54002dae09ebac95f6ba20f0ea5db0766b8bd1 /arch/arm/cpu/armv7/sunxi/usb_phy.c | |
parent | e13afeef6f5d3c9c4fc130b21ee7c885f96d55f2 (diff) |
sunxi: usb: Protect phy-init and phy-power-on against multiple calls
Once we add support for the ohci controller the phy-init and phy-power-on
functions may be called twice (once by the ehci code and once by the ohci
code) protect them against this.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
Diffstat (limited to 'arch/arm/cpu/armv7/sunxi/usb_phy.c')
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/usb_phy.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index 1f85dec07e..410669e548 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -45,6 +45,8 @@ static struct sunxi_usb_phy { int gpio_vbus; int gpio_vbus_det; int id; + int init_count; + int power_on_count; } sunxi_usb_phy[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, @@ -170,6 +172,10 @@ 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; + phy->init_count++; + if (phy->init_count != 1) + return; + setbits_le32(&ccm->usb_clk_cfg, phy->usb_rst_mask); sunxi_usb_phy_config(phy); @@ -183,6 +189,10 @@ void sunxi_usb_phy_exit(int index) struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + phy->init_count--; + if (phy->init_count != 0) + return; + if (phy->id != 0) sunxi_usb_phy_passby(index, !SUNXI_USB_PASSBY_EN); @@ -193,6 +203,10 @@ void sunxi_usb_phy_power_on(int index) { struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; + phy->power_on_count++; + if (phy->power_on_count != 1) + return; + if (phy->gpio_vbus >= 0) gpio_set_value(phy->gpio_vbus, 1); } @@ -201,6 +215,10 @@ void sunxi_usb_phy_power_off(int index) { struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; + phy->power_on_count--; + if (phy->power_on_count != 0) + return; + if (phy->gpio_vbus >= 0) gpio_set_value(phy->gpio_vbus, 0); } |