diff mbox

[U-Boot,6/6] sunxi: usb: Protect phy-init and phy-power-on against multiple calls

Message ID 1430203271-3130-7-git-send-email-hdegoede@redhat.com
State Accepted
Delegated to: Hans de Goede
Headers show

Commit Message

Hans de Goede April 28, 2015, 6:41 a.m. UTC
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>
---
 arch/arm/cpu/armv7/sunxi/usb_phy.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Ian Campbell May 2, 2015, 1:45 p.m. UTC | #1
On Tue, 2015-04-28 at 08:41 +0200, Hans de Goede wrote:
> 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>
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c
index 1f85dec..410669e 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);
 }