]> rtime.felk.cvut.cz Git - vajnamar/linux-xlnx.git/commitdiff
phy: zynqmp: Move assert/de-assert to a separate functions
authorAnurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Tue, 18 Apr 2017 15:51:12 +0000 (21:21 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 19 Apr 2017 09:31:11 +0000 (11:31 +0200)
Currently assert/de-assert are controlled through reset-controller
framework. Since these functions are non-blocking calls, changed the
code to wait until the assert/de-assert is done by the reset framework.
Waiting is done by reading the status from the reset-controller
framework.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/phy/phy-zynqmp.c

index aebcb32e7950ae88f308a72d00ff460dddb83130..7db1d8cf966e24d04f204bfc3c1f40c0690476fa 100644 (file)
@@ -46,6 +46,7 @@
 #define RST_ULPI_LOW                   0x02
 
 #define RST_ULPI_TIMEOUT               10
+#define RST_TIMEOUT                    1000
 
 #define ICM_CFG0                       0x10010
 #define ICM_CFG1                       0x10014
@@ -534,92 +535,155 @@ static int xpsgtr_configure_lane(struct xpsgtr_phy *gtr_phy)
        return 0;
 }
 
+/**
+ * xpsgtr_reset_assert - asserts reset using reset framework
+ * @gtr_phy: pointer to reset_control
+ *
+ * Return: 0 on success or error on failure
+ */
+static int xpsgtr_reset_assert(struct reset_control *rstc)
+{
+       unsigned long loop_time = msecs_to_jiffies(RST_TIMEOUT);
+       unsigned long timeout;
+
+       reset_control_assert(rstc);
+
+       /* wait until reset is asserted or timeout */
+       timeout = jiffies + loop_time;
+
+       while (!time_after_eq(jiffies, timeout)) {
+               if (reset_control_status(rstc) > 0)
+                       return 0;
+
+               cpu_relax();
+       }
+
+       return -ETIMEDOUT;
+}
+
+/**
+ * xpsgtr_reset_release - de-asserts reset using reset framework
+ * @gtr_phy: pointer to reset_control
+ *
+ * Return: 0 on success or error on failure
+ */
+static int xpsgtr_reset_release(struct reset_control *rstc)
+{
+       unsigned long loop_time = msecs_to_jiffies(RST_TIMEOUT);
+       unsigned long timeout;
+
+       reset_control_deassert(rstc);
+
+       /* wait until reset is de-asserted or timeout */
+       timeout = jiffies + loop_time;
+       while (!time_after_eq(jiffies, timeout)) {
+               if (!reset_control_status(rstc))
+                       return 0;
+
+               cpu_relax();
+       }
+
+       return -ETIMEDOUT;
+}
+
 /**
  * xpsgtr_controller_reset - puts controller in reset
  * @gtr_phy: pointer to lane
+ *
+ * Return: 0 on success or error on failure
  */
-static void xpsgtr_controller_reset(struct xpsgtr_phy *gtr_phy)
+static int xpsgtr_controller_reset(struct xpsgtr_phy *gtr_phy)
 {
        struct xpsgtr_dev *gtr_dev = gtr_phy->data;
+       int ret;
 
        switch (gtr_phy->type) {
        case XPSGTR_TYPE_USB0:
-               reset_control_assert(gtr_dev->usb0_crst);
-               reset_control_assert(gtr_dev->usb0_hibrst);
-               reset_control_assert(gtr_dev->usb0_apbrst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb0_crst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb0_hibrst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb0_apbrst);
                break;
        case XPSGTR_TYPE_USB1:
-               reset_control_assert(gtr_dev->usb1_crst);
-               reset_control_assert(gtr_dev->usb1_hibrst);
-               reset_control_assert(gtr_dev->usb1_apbrst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb1_crst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb1_hibrst);
+               ret = xpsgtr_reset_assert(gtr_dev->usb1_apbrst);
                break;
        case XPSGTR_TYPE_SATA_0:
        case XPSGTR_TYPE_SATA_1:
-               reset_control_assert(gtr_dev->sata_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->sata_rst);
                break;
        case XPSGTR_TYPE_DP_0:
        case XPSGTR_TYPE_DP_1:
-               reset_control_assert(gtr_dev->dp_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->dp_rst);
                break;
        case XPSGTR_TYPE_SGMII0:
-               reset_control_assert(gtr_dev->gem0_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->gem0_rst);
                break;
        case XPSGTR_TYPE_SGMII1:
-               reset_control_assert(gtr_dev->gem1_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->gem1_rst);
                break;
        case XPSGTR_TYPE_SGMII2:
-               reset_control_assert(gtr_dev->gem2_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->gem2_rst);
                break;
        case XPSGTR_TYPE_SGMII3:
-               reset_control_assert(gtr_dev->gem3_rst);
+               ret = xpsgtr_reset_assert(gtr_dev->gem3_rst);
                break;
        default:
+               ret = -EINVAL;
                break;
        }
+
+       return ret;
 }
 
 /**
  * xpsgtr_controller_release_reset - releases controller from reset
  * @gtr_phy: pointer to lane
+ *
+ * Return: 0 on success or error on failure
  */
-static void xpsgtr_controller_release_reset(struct xpsgtr_phy *gtr_phy)
+static int xpsgtr_controller_release_reset(struct xpsgtr_phy *gtr_phy)
 {
        struct xpsgtr_dev *gtr_dev = gtr_phy->data;
+       int ret;
 
        switch (gtr_phy->type) {
        case XPSGTR_TYPE_USB0:
-               reset_control_deassert(gtr_dev->usb0_crst);
-               reset_control_deassert(gtr_dev->usb0_hibrst);
-               reset_control_deassert(gtr_dev->usb0_apbrst);
+               ret = xpsgtr_reset_release(gtr_dev->usb0_crst);
+               ret = xpsgtr_reset_release(gtr_dev->usb0_hibrst);
+               ret = xpsgtr_reset_release(gtr_dev->usb0_apbrst);
                break;
        case XPSGTR_TYPE_USB1:
-               reset_control_deassert(gtr_dev->usb1_crst);
-               reset_control_deassert(gtr_dev->usb1_hibrst);
-               reset_control_deassert(gtr_dev->usb1_apbrst);
+               ret = xpsgtr_reset_release(gtr_dev->usb1_crst);
+               ret = xpsgtr_reset_release(gtr_dev->usb1_hibrst);
+               ret = xpsgtr_reset_release(gtr_dev->usb1_apbrst);
                break;
        case XPSGTR_TYPE_SATA_0:
        case XPSGTR_TYPE_SATA_1:
-               reset_control_deassert(gtr_dev->sata_rst);
+               ret = xpsgtr_reset_release(gtr_dev->sata_rst);
                break;
        case XPSGTR_TYPE_DP_0:
        case XPSGTR_TYPE_DP_1:
-               reset_control_deassert(gtr_dev->dp_rst);
+               ret = xpsgtr_reset_release(gtr_dev->dp_rst);
                break;
        case XPSGTR_TYPE_SGMII0:
-               reset_control_deassert(gtr_dev->gem0_rst);
+               ret = xpsgtr_reset_release(gtr_dev->gem0_rst);
                break;
        case XPSGTR_TYPE_SGMII1:
-               reset_control_deassert(gtr_dev->gem1_rst);
+               ret = xpsgtr_reset_release(gtr_dev->gem1_rst);
                break;
        case XPSGTR_TYPE_SGMII2:
-               reset_control_deassert(gtr_dev->gem2_rst);
+               ret = xpsgtr_reset_release(gtr_dev->gem2_rst);
                break;
        case XPSGTR_TYPE_SGMII3:
-               reset_control_deassert(gtr_dev->gem3_rst);
+               ret = xpsgtr_reset_release(gtr_dev->gem3_rst);
                break;
        default:
+               ret = -EINVAL;
                break;
        }
+
+       return ret;
 }
 
 int xpsgtr_wait_pll_lock(struct phy *phy)
@@ -850,7 +914,11 @@ static int xpsgtr_phy_init(struct phy *phy)
        mutex_lock(&gtr_dev->gtr_mutex);
 
        /* Put controller in reset */
-       xpsgtr_controller_reset(gtr_phy);
+       ret = xpsgtr_controller_reset(gtr_phy);
+       if (ret != 0) {
+               dev_err(gtr_dev->dev, "Failed to assert reset\n");
+               goto out;
+       }
 
        /*
         * There is a functional issue in the GT. The TX termination resistance
@@ -941,7 +1009,11 @@ static int xpsgtr_phy_init(struct phy *phy)
                xpsgtr_misc_sgmii(gtr_phy);
 
        /* Bring controller out of reset */
-       xpsgtr_controller_release_reset(gtr_phy);
+       ret = xpsgtr_controller_release_reset(gtr_phy);
+       if (ret != 0) {
+               dev_err(gtr_dev->dev, "Failed to release reset\n");
+               goto out;
+       }
 
        /* Wait till pll is locked for all protocols except DP. For DP
         * pll locking function will be called from driver.