Skip to content

Commit baa181f

Browse files
committed
soundwire: bus: add CLOCK_STOP_MODE1 support back
CLOCK_STOP_MODE1 is used when the Peripheral might have entered a deeper power-saving mode that does not retain state while the Clock is stopped. It is useful when the device is more power consumption sensitive. Add it back to allow the Peripheral use CLOCK_STOP_MODE1. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent 5f4a36a commit baa181f

2 files changed

Lines changed: 30 additions & 20 deletions

File tree

  • drivers/soundwire
  • include/linux/soundwire

drivers/soundwire/bus.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -956,8 +956,22 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
956956
mutex_unlock(&bus->bus_lock);
957957
}
958958

959+
static enum sdw_clk_stop_mode sdw_get_clk_stop_mode(struct sdw_slave *slave)
960+
{
961+
struct device *dev = &slave->dev;
962+
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
963+
964+
/*
965+
* Query for clock stop mode if Slave implements
966+
* ops->get_clk_stop_mode, else read from property.
967+
*/
968+
if (drv->ops && drv->ops->get_clk_stop_mode)
969+
return drv->ops->get_clk_stop_mode(slave);
970+
else
971+
return slave->prop.clk_stop_mode1 ? SDW_CLK_STOP_MODE1 : SDW_CLK_STOP_MODE0;
972+
}
973+
959974
static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
960-
enum sdw_clk_stop_mode mode,
961975
enum sdw_clk_stop_type type)
962976
{
963977
int ret = 0;
@@ -969,7 +983,7 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
969983
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
970984

971985
if (drv->ops && drv->ops->clk_stop)
972-
ret = drv->ops->clk_stop(slave, mode, type);
986+
ret = drv->ops->clk_stop(slave, slave->clk_stop_mode, type);
973987
}
974988

975989
mutex_unlock(&slave->sdw_dev_lock);
@@ -978,7 +992,6 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
978992
}
979993

980994
static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
981-
enum sdw_clk_stop_mode mode,
982995
bool prepare)
983996
{
984997
bool wake_en;
@@ -990,7 +1003,7 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
9901003
if (prepare) {
9911004
val = SDW_SCP_SYSTEMCTRL_CLK_STP_PREP;
9921005

993-
if (mode == SDW_CLK_STOP_MODE1)
1006+
if (slave->clk_stop_mode == SDW_CLK_STOP_MODE1)
9941007
val |= SDW_SCP_SYSTEMCTRL_CLK_STP_MODE1;
9951008

9961009
if (wake_en)
@@ -1078,9 +1091,9 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
10781091
/* Identify if Slave(s) are available on Bus */
10791092
is_slave = true;
10801093

1081-
ret = sdw_slave_clk_stop_callback(slave,
1082-
SDW_CLK_STOP_MODE0,
1083-
SDW_CLK_PRE_PREPARE);
1094+
slave->clk_stop_mode = sdw_get_clk_stop_mode(slave);
1095+
1096+
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_PRE_PREPARE);
10841097
if (ret < 0 && ret != -ENODATA) {
10851098
dev_err(&slave->dev, "clock stop pre-prepare cb failed:%d\n", ret);
10861099
return ret;
@@ -1090,9 +1103,7 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
10901103
if (!slave->prop.simple_clk_stop_capable) {
10911104
simple_clk_stop = false;
10921105

1093-
ret = sdw_slave_clk_stop_prepare(slave,
1094-
SDW_CLK_STOP_MODE0,
1095-
true);
1106+
ret = sdw_slave_clk_stop_prepare(slave, true);
10961107
if (ret < 0 && ret != -ENODATA) {
10971108
dev_err(&slave->dev, "clock stop prepare failed:%d\n", ret);
10981109
return ret;
@@ -1130,9 +1141,7 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
11301141
slave->status != SDW_SLAVE_ALERT)
11311142
continue;
11321143

1133-
ret = sdw_slave_clk_stop_callback(slave,
1134-
SDW_CLK_STOP_MODE0,
1135-
SDW_CLK_POST_PREPARE);
1144+
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_POST_PREPARE);
11361145

11371146
if (ret < 0 && ret != -ENODATA) {
11381147
dev_err(&slave->dev, "clock stop post-prepare cb failed:%d\n", ret);
@@ -1204,18 +1213,16 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
12041213
/* Identify if Slave(s) are available on Bus */
12051214
is_slave = true;
12061215

1207-
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
1208-
SDW_CLK_PRE_DEPREPARE);
1216+
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_PRE_DEPREPARE);
12091217
if (ret < 0)
12101218
dev_warn(&slave->dev, "clock stop pre-deprepare cb failed:%d\n", ret);
12111219

1220+
12121221
/* Only de-prepare a Slave device if needed */
12131222
if (!slave->prop.simple_clk_stop_capable) {
12141223
simple_clk_stop = false;
12151224

1216-
ret = sdw_slave_clk_stop_prepare(slave, SDW_CLK_STOP_MODE0,
1217-
false);
1218-
1225+
ret = sdw_slave_clk_stop_prepare(slave, false);
12191226
if (ret < 0)
12201227
dev_warn(&slave->dev, "clock stop deprepare failed:%d\n", ret);
12211228
}
@@ -1243,8 +1250,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
12431250
slave->status != SDW_SLAVE_ALERT)
12441251
continue;
12451252

1246-
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_STOP_MODE0,
1247-
SDW_CLK_POST_DEPREPARE);
1253+
ret = sdw_slave_clk_stop_callback(slave, SDW_CLK_POST_DEPREPARE);
12481254
if (ret < 0)
12491255
dev_warn(&slave->dev, "clock stop post-deprepare cb failed:%d\n", ret);
12501256
}

include/linux/soundwire/sdw.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ struct sdw_bus_params {
611611
* @update_status: Update Slave status
612612
* @bus_config: Update the bus config for Slave
613613
* @port_prep: Prepare the port with parameters
614+
* @get_clk_stop_mode: Get the clock stop mode of the Slave
614615
* @clk_stop: handle imp-def sequences before and after prepare and de-prepare
615616
*/
616617
struct sdw_slave_ops {
@@ -624,6 +625,7 @@ struct sdw_slave_ops {
624625
int (*port_prep)(struct sdw_slave *slave,
625626
struct sdw_prepare_ch *prepare_ch,
626627
enum sdw_port_prep_ops pre_ops);
628+
int (*get_clk_stop_mode)(struct sdw_slave *slave);
627629
int (*clk_stop)(struct sdw_slave *slave,
628630
enum sdw_clk_stop_mode mode,
629631
enum sdw_clk_stop_type type);
@@ -642,6 +644,7 @@ struct sdw_slave_ops {
642644
* @node: node for bus list
643645
* @port_ready: Port ready completion flag for each Slave port
644646
* @m_port_map: static Master port map for each Slave port
647+
* @clk_stop_mode: The clock stop mode of the Slave
645648
* @dev_num: Current Device Number, values can be 0 or dev_num_sticky
646649
* @dev_num_sticky: one-time static Device Number assigned by Bus
647650
* @probed: boolean tracking driver state
@@ -676,6 +679,7 @@ struct sdw_slave {
676679
struct list_head node;
677680
struct completion port_ready[SDW_MAX_PORTS];
678681
unsigned int m_port_map[SDW_MAX_PORTS];
682+
enum sdw_clk_stop_mode clk_stop_mode;
679683
u16 dev_num;
680684
u16 dev_num_sticky;
681685
bool probed;

0 commit comments

Comments
 (0)