soundwire: cadence: Remove ret variable from sdw_cdns_irq()
[linux-2.6-microblaze.git] / drivers / soundwire / bus.c
index 5d5b0bd..278a4fb 100644 (file)
@@ -394,13 +394,13 @@ sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
 }
 
 static int
-sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
 {
        struct sdw_msg msg;
        int ret;
 
        ret = sdw_fill_msg(&msg, slave, addr, count,
-                          slave->dev_num, SDW_MSG_FLAG_WRITE, val);
+                          slave->dev_num, SDW_MSG_FLAG_WRITE, (u8 *)val);
        if (ret < 0)
                return ret;
 
@@ -550,9 +550,9 @@ EXPORT_SYMBOL(sdw_nread);
  * @slave: SDW Slave
  * @addr: Register address
  * @count: length
- * @val: Buffer for values to be read
+ * @val: Buffer for values to be written
  */
-int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
 {
        int ret;
 
@@ -836,26 +836,6 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
        mutex_unlock(&bus->bus_lock);
 }
 
-static enum sdw_clk_stop_mode sdw_get_clk_stop_mode(struct sdw_slave *slave)
-{
-       enum sdw_clk_stop_mode mode;
-
-       /*
-        * Query for clock stop mode if Slave implements
-        * ops->get_clk_stop_mode, else read from property.
-        */
-       if (slave->ops && slave->ops->get_clk_stop_mode) {
-               mode = slave->ops->get_clk_stop_mode(slave);
-       } else {
-               if (slave->prop.clk_stop_mode1)
-                       mode = SDW_CLK_STOP_MODE1;
-               else
-                       mode = SDW_CLK_STOP_MODE0;
-       }
-
-       return mode;
-}
-
 static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
                                       enum sdw_clk_stop_mode mode,
                                       enum sdw_clk_stop_type type)
@@ -864,11 +844,8 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
 
        if (slave->ops && slave->ops->clk_stop) {
                ret = slave->ops->clk_stop(slave, mode, type);
-               if (ret < 0) {
-                       dev_err(&slave->dev,
-                               "Clk Stop type =%d failed: %d\n", type, ret);
+               if (ret < 0)
                        return ret;
-               }
        }
 
        return 0;
@@ -895,7 +872,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
        } else {
                ret = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
                if (ret < 0) {
-                       dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
+                       if (ret != -ENODATA)
+                               dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
                        return ret;
                }
                val = ret;
@@ -904,9 +882,8 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
 
        ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);
 
-       if (ret < 0)
-               dev_err(&slave->dev,
-                       "Clock Stop prepare failed for slave: %d", ret);
+       if (ret < 0 && ret != -ENODATA)
+               dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL write failed:%d\n", ret);
 
        return ret;
 }
@@ -919,12 +896,13 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
        do {
                val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT);
                if (val < 0) {
-                       dev_err(bus->dev, "SDW_SCP_STAT bread failed:%d\n", val);
+                       if (val != -ENODATA)
+                               dev_err(bus->dev, "SDW_SCP_STAT bread failed:%d\n", val);
                        return val;
                }
                val &= SDW_SCP_STAT_CLK_STP_NF;
                if (!val) {
-                       dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d",
+                       dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d\n",
                                dev_num);
                        return 0;
                }
@@ -933,7 +911,7 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
                retry--;
        } while (retry);
 
-       dev_err(bus->dev, "clock stop prep/de-prep failed slave:%d",
+       dev_err(bus->dev, "clock stop prep/de-prep failed slave:%d\n",
                dev_num);
 
        return -ETIMEDOUT;
@@ -948,7 +926,6 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
  */
 int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
 {
-       enum sdw_clk_stop_mode slave_mode;
        bool simple_clk_stop = true;
        struct sdw_slave *slave;
        bool is_slave = false;
@@ -958,6 +935,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
         * In order to save on transition time, prepare
         * each Slave and then wait for all Slave(s) to be
         * prepared for clock stop.
+        * If one of the Slave devices has lost sync and
+        * replies with Command Ignored/-ENODATA, we continue
+        * the loop
         */
        list_for_each_entry(slave, &bus->slaves, node) {
                if (!slave->dev_num)
@@ -970,36 +950,45 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
                /* Identify if Slave(s) are available on Bus */
                is_slave = true;
 
-               slave_mode = sdw_get_clk_stop_mode(slave);
-               slave->curr_clk_stop_mode = slave_mode;
-
-               ret = sdw_slave_clk_stop_callback(slave, slave_mode,
+               ret = sdw_slave_clk_stop_callback(slave,
+                                                 SDW_CLK_STOP_MODE0,
                                                  SDW_CLK_PRE_PREPARE);
-               if (ret < 0) {
-                       dev_err(&slave->dev,
-                               "pre-prepare failed:%d", ret);
-                       return ret;
-               }
-
-               ret = sdw_slave_clk_stop_prepare(slave,
-                                                slave_mode, true);
-               if (ret < 0) {
-                       dev_err(&slave->dev,
-                               "pre-prepare failed:%d", ret);
+               if (ret < 0 && ret != -ENODATA) {
+                       dev_err(&slave->dev, "clock stop pre-prepare cb failed:%d\n", ret);
                        return ret;
                }
 
-               if (slave_mode == SDW_CLK_STOP_MODE1)
+               /* Only prepare a Slave device if needed */
+               if (!slave->prop.simple_clk_stop_capable) {
                        simple_clk_stop = false;
+
+                       ret = sdw_slave_clk_stop_prepare(slave,
+                                                        SDW_CLK_STOP_MODE0,
+                                                        true);
+                       if (ret < 0 && ret != -ENODATA) {
+                               dev_err(&slave->dev, "clock stop prepare failed:%d\n", ret);
+                               return ret;
+                       }
+               }
        }
 
        /* Skip remaining clock stop preparation if no Slave is attached */
        if (!is_slave)
-               return ret;
+               return 0;
 
+       /*
+        * Don't wait for all Slaves to be ready if they follow the simple
+        * state machine
+        */
        if (!simple_clk_stop) {
                ret = sdw_bus_wait_for_clk_prep_deprep(bus,
                                                       SDW_BROADCAST_DEV_NUM);
+               /*
+                * if there are no Slave devices present and the reply is
+                * Command_Ignored/-ENODATA, we don't need to continue with the
+                * flow and can just return here. The error code is not modified
+                * and its handling left as an exercise for the caller.
+                */
                if (ret < 0)
                        return ret;
        }
@@ -1013,21 +1002,17 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
                    slave->status != SDW_SLAVE_ALERT)
                        continue;
 
-               slave_mode = slave->curr_clk_stop_mode;
-
-               if (slave_mode == SDW_CLK_STOP_MODE1) {
-                       ret = sdw_slave_clk_stop_callback(slave,
-                                                         slave_mode,
-                                                         SDW_CLK_POST_PREPARE);
+               ret = sdw_slave_clk_stop_callback(slave,
+                                                 SDW_CLK_STOP_MODE0,
+                                                 SDW_CLK_POST_PREPARE);
 
-                       if (ret < 0) {
-                               dev_err(&slave->dev,
-                                       "post-prepare failed:%d", ret);
-                       }
+               if (ret < 0 && ret != -ENODATA) {
+                       dev_err(&slave->dev, "clock stop post-prepare cb failed:%d\n", ret);
+                       return ret;
                }
        }
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(sdw_bus_prep_clk_stop);
 
@@ -1050,12 +1035,8 @@ int sdw_bus_clk_stop(struct sdw_bus *bus)
        ret = sdw_bwrite_no_pm(bus, SDW_BROADCAST_DEV_NUM,
                               SDW_SCP_CTRL, SDW_SCP_CTRL_CLK_STP_NOW);
        if (ret < 0) {
-               if (ret == -ENODATA)
-                       dev_dbg(bus->dev,
-                               "ClockStopNow Broadcast msg ignored %d", ret);
-               else
-                       dev_err(bus->dev,
-                               "ClockStopNow Broadcast msg failed %d", ret);
+               if (ret != -ENODATA)
+                       dev_err(bus->dev, "ClockStopNow Broadcast msg failed %d\n", ret);
                return ret;
        }
 
@@ -1074,7 +1055,6 @@ EXPORT_SYMBOL(sdw_bus_clk_stop);
  */
 int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
 {
-       enum sdw_clk_stop_mode mode;
        bool simple_clk_stop = true;
        struct sdw_slave *slave;
        bool is_slave = false;
@@ -1096,33 +1076,36 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
                /* Identify if Slave(s) are available on Bus */
                is_slave = true;
 
-               mode = slave->curr_clk_stop_mode;
-
-               if (mode == SDW_CLK_STOP_MODE1) {
-                       simple_clk_stop = false;
-                       continue;
-               }
-
-               ret = sdw_slave_clk_stop_callback(slave, mode,
+               ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
                                                  SDW_CLK_PRE_DEPREPARE);
                if (ret < 0)
-                       dev_warn(&slave->dev,
-                                "clk stop deprep failed:%d", ret);
+                       dev_warn(&slave->dev, "clock stop pre-deprepare cb failed:%d\n", ret);
 
-               ret = sdw_slave_clk_stop_prepare(slave, mode,
-                                                false);
+               /* Only de-prepare a Slave device if needed */
+               if (!slave->prop.simple_clk_stop_capable) {
+                       simple_clk_stop = false;
 
-               if (ret < 0)
-                       dev_warn(&slave->dev,
-                                "clk stop deprep failed:%d", ret);
+                       ret = sdw_slave_clk_stop_prepare(slave, SDW_CLK_STOP_MODE0,
+                                                        false);
+
+                       if (ret < 0)
+                               dev_warn(&slave->dev, "clock stop deprepare failed:%d\n", ret);
+               }
        }
 
        /* Skip remaining clock stop de-preparation if no Slave is attached */
        if (!is_slave)
                return 0;
 
-       if (!simple_clk_stop)
-               sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
+       /*
+        * Don't wait for all Slaves to be ready if they follow the simple
+        * state machine
+        */
+       if (!simple_clk_stop) {
+               ret = sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
+               if (ret < 0)
+                       dev_warn(&slave->dev, "clock stop deprepare wait failed:%d\n", ret);
+       }
 
        list_for_each_entry(slave, &bus->slaves, node) {
                if (!slave->dev_num)
@@ -1132,9 +1115,10 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
                    slave->status != SDW_SLAVE_ALERT)
                        continue;
 
-               mode = slave->curr_clk_stop_mode;
-               sdw_slave_clk_stop_callback(slave, mode,
-                                           SDW_CLK_POST_DEPREPARE);
+               ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
+                                                 SDW_CLK_POST_DEPREPARE);
+               if (ret < 0)
+                       dev_warn(&slave->dev, "clock stop post-deprepare cb failed:%d\n", ret);
        }
 
        return 0;