Pull soundwire updates from Vinod Koul: "This is a small update which features a bit of core changes and driver updates in Intel and cadence driver. Core: - sdw_transfer_defer() API change to drop an argument - Reset page address rework - Export sdw_nwrite_no_pm and sdw_nread_no_pm APIs Drivers: - Cadence and related intel driver updates for FIFO handling and low level msg transfers" * tag 'soundwire-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: soundwire: cadence: further simplify low-level xfer_msg_defer() callback soundwire: cadence: use directly bus sdw_defer structure soundwire: bus: remove sdw_defer argument in sdw_transfer_defer() soundwire: stream: use consistent pattern for freeing buffers soundwire: bus: Remove unused reset_page_addr() callback soundwire: bus: Don't zero page registers after every transaction soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe() soundwire: stream: Move remaining register accesses over to no_pm soundwire: debugfs: Switch to sdw_read_no_pm soundwire: Provide build stubs for common functions soundwire: bus: export sdw_nwrite_no_pm and sdw_nread_no_pm functions soundwire: cadence: remove unused sdw_cdns_master_ops declaration soundwire: enable optional clock registers for SoundWire 1.2 devices ASoC/soundwire: remove is_sdca boolean property soundwire: cadence: Drain the RX FIFO after an IO timeout soundwire: cadence: Remove wasted space in response_buf soundwire: cadence: Don't overflow the command FIFOs soundwire: intel: remove DAI startup/shutdown
Unified · Split
| @@ -225,9 +225,9 @@ static inline int do_transfer(struct sdw_bus *bus, struct sdw_msg *msg) · 224 unmodified lines | |||
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | static inline int do_transfer_defer(struct sdw_bus *bus, | 227 | static inline int do_transfer_defer(struct sdw_bus *bus, |
| 228 | struct sdw_msg *msg, | 228 | struct sdw_msg *msg) |
| 229 | struct sdw_defer *defer) | ||
| 230 | { | 229 | { |
| 230 | struct sdw_defer *defer = &bus->defer_msg; | ||
| 231 | int retry = bus->prop.err_threshold; | 231 | int retry = bus->prop.err_threshold; |
| 232 | enum sdw_command_response resp; | 232 | enum sdw_command_response resp; |
| 233 | int ret = 0, i; | 233 | int ret = 0, i; |
| @@ -237,24 +237,7 @@ static inline int do_transfer_defer(struct sdw_bus *bus, · 3 unmodified lines | |||
| 237 | init_completion(&defer->complete); | 237 | init_completion(&defer->complete); |
| 238 | 238 | ||
| 239 | for (i = 0; i <= retry; i++) { | 239 | for (i = 0; i <= retry; i++) { |
| 240 | resp = bus->ops->xfer_msg_defer(bus, msg, defer); | 240 | resp = bus->ops->xfer_msg_defer(bus); |
| 241 | ret = find_response_code(resp); | ||
| 242 | /* if cmd is ok or ignored return */ | ||
| 243 | if (ret == 0 || ret == -ENODATA) | ||
| 244 | return ret; | ||
| 245 | } | ||
| 246 | |||
| 247 | return ret; | ||
| 248 | } | ||
| 249 | |||
| 250 | static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num) | ||
| 251 | { | ||
| 252 | int retry = bus->prop.err_threshold; | ||
| 253 | enum sdw_command_response resp; | ||
| 254 | int ret = 0, i; | ||
| 255 | |||
| 256 | for (i = 0; i <= retry; i++) { | ||
| 257 | resp = bus->ops->reset_page_addr(bus, dev_num); | ||
| 258 | ret = find_response_code(resp); | 241 | ret = find_response_code(resp); |
| 259 | /* if cmd is ok or ignored return */ | 242 | /* if cmd is ok or ignored return */ |
| 260 | if (ret == 0 || ret == -ENODATA) | 243 | if (ret == 0 || ret == -ENODATA) |
| @@ -275,9 +258,6 @@ static int sdw_transfer_unlocked(struct sdw_bus *bus, struct sdw_msg *msg) · 14 unmodified lines | |||
| 275 | (msg->flags & SDW_MSG_FLAG_WRITE) ? "write" : "read", | 258 | (msg->flags & SDW_MSG_FLAG_WRITE) ? "write" : "read", |
| 276 | msg->addr, msg->len); | 259 | msg->addr, msg->len); |
| 277 | 260 | ||
| 278 | if (msg->page) | ||
| 279 | sdw_reset_page(bus, msg->dev_num); | ||
| 280 | |||
| 281 | return ret; | 261 | return ret; |
| 282 | } | 262 | } |
| 283 | 263 | ||
| @@ -335,26 +315,21 @@ EXPORT_SYMBOL(sdw_show_ping_status); · 51 unmodified lines | |||
| 335 | * sdw_transfer_defer() - Asynchronously transfer message to a SDW Slave device | 315 | * sdw_transfer_defer() - Asynchronously transfer message to a SDW Slave device |
| 336 | * @bus: SDW bus | 316 | * @bus: SDW bus |
| 337 | * @msg: SDW message to be xfered | 317 | * @msg: SDW message to be xfered |
| 338 | * @defer: Defer block for signal completion | ||
| 339 | * | 318 | * |
| 340 | * Caller needs to hold the msg_lock lock while calling this | 319 | * Caller needs to hold the msg_lock lock while calling this |
| 341 | */ | 320 | */ |
| 342 | int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg, | 321 | int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg) |
| 343 | struct sdw_defer *defer) | ||
| 344 | { | 322 | { |
| 345 | int ret; | 323 | int ret; |
| 346 | 324 | ||
| 347 | if (!bus->ops->xfer_msg_defer) | 325 | if (!bus->ops->xfer_msg_defer) |
| 348 | return -ENOTSUPP; | 326 | return -ENOTSUPP; |
| 349 | 327 | ||
| 350 | ret = do_transfer_defer(bus, msg, defer); | 328 | ret = do_transfer_defer(bus, msg); |
| 351 | if (ret != 0 && ret != -ENODATA) | 329 | if (ret != 0 && ret != -ENODATA) |
| 352 | dev_err(bus->dev, "Defer trf on Slave %d failed:%d\n", | 330 | dev_err(bus->dev, "Defer trf on Slave %d failed:%d\n", |
| 353 | msg->dev_num, ret); | 331 | msg->dev_num, ret); |
| 354 | 332 | ||
| 355 | if (msg->page) | ||
| 356 | sdw_reset_page(bus, msg->dev_num); | ||
| 357 | |||
| 358 | return ret; | 333 | return ret; |
| 359 | } | 334 | } |
| 360 | 335 | ||
| @@ -414,8 +389,7 @@ int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave, · 53 unmodified lines | |||
| 414 | * all clients need to use the pm versions | 389 | * all clients need to use the pm versions |
| 415 | */ | 390 | */ |
| 416 | 391 | ||
| 417 | static int | 392 | int sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val) |
| 418 | sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val) | ||
| 419 | { | 393 | { |
| 420 | struct sdw_msg msg; | 394 | struct sdw_msg msg; |
| 421 | int ret; | 395 | int ret; |
| @@ -430,9 +404,9 @@ sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val) · 8 unmodified lines | |||
| 430 | ret = 0; | 404 | ret = 0; |
| 431 | return ret; | 405 | return ret; |
| 432 | } | 406 | } |
| 407 | EXPORT_SYMBOL(sdw_nread_no_pm); | ||
| 433 | 408 | ||
| 434 | static int | 409 | int sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val) |
| 435 | sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val) | ||
| 436 | { | 410 | { |
| 437 | struct sdw_msg msg; | 411 | struct sdw_msg msg; |
| 438 | int ret; | 412 | int ret; |
| @@ -447,6 +421,7 @@ sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val) · 8 unmodified lines | |||
| 447 | ret = 0; | 421 | ret = 0; |
| 448 | return ret; | 422 | return ret; |
| 449 | } | 423 | } |
| 424 | EXPORT_SYMBOL(sdw_nwrite_no_pm); | ||
| 450 | 425 | ||
| 451 | int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value) | 426 | int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value) |
| 452 | { | 427 | { |
| @@ -1214,7 +1189,7 @@ int sdw_configure_dpn_intr(struct sdw_slave *slave, · 761 unmodified lines | |||
| 1214 | val &= ~SDW_DPN_INT_PORT_READY; | 1189 | val &= ~SDW_DPN_INT_PORT_READY; |
| 1215 | } | 1190 | } |
| 1216 | 1191 | ||
| 1217 | ret = sdw_update(slave, addr, (mask | SDW_DPN_INT_PORT_READY), val); | 1192 | ret = sdw_update_no_pm(slave, addr, (mask | SDW_DPN_INT_PORT_READY), val); |
| 1218 | if (ret < 0) | 1193 | if (ret < 0) |
| 1219 | dev_err(&slave->dev, | 1194 | dev_err(&slave->dev, |
| 1220 | "SDW_DPN_INTMASK write failed:%d\n", val); | 1195 | "SDW_DPN_INTMASK write failed:%d\n", val); |
| @@ -1233,10 +1208,11 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave) · 12 unmodified lines | |||
| 1233 | 1208 | ||
| 1234 | /* | 1209 | /* |
| 1235 | * frequency base and scale registers are required for SDCA | 1210 | * frequency base and scale registers are required for SDCA |
| 1236 | * devices. They may also be used for 1.2+/non-SDCA devices, | 1211 | * devices. They may also be used for 1.2+/non-SDCA devices. |
| 1237 | * but we will need a DisCo property to cover this case | 1212 | * Driver can set the property, we will need a DisCo property |
| 1213 | * to discover this case from platform firmware. | ||
| 1238 | */ | 1214 | */ |
| 1239 | if (!slave->id.class_id) | 1215 | if (!slave->id.class_id && !slave->prop.clock_reg_supported) |
| 1240 | return 0; | 1216 | return 0; |
| 1241 | 1217 | ||
| 1242 | if (!mclk_freq) { | 1218 | if (!mclk_freq) { |
| @@ -1587,7 +1563,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) · 344 unmodified lines | |||
| 1587 | goto io_err; | 1563 | goto io_err; |
| 1588 | } | 1564 | } |
| 1589 | 1565 | ||
| 1590 | if (slave->prop.is_sdca) { | 1566 | if (slave->id.class_id) { |
| 1591 | ret = sdw_read_no_pm(slave, SDW_DP0_INT); | 1567 | ret = sdw_read_no_pm(slave, SDW_DP0_INT); |
| 1592 | if (ret < 0) { | 1568 | if (ret < 0) { |
| 1593 | dev_err(&slave->dev, | 1569 | dev_err(&slave->dev, |
| @@ -1724,7 +1700,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) · 130 unmodified lines | |||
| 1724 | goto io_err; | 1700 | goto io_err; |
| 1725 | } | 1701 | } |
| 1726 | 1702 | ||
| 1727 | if (slave->prop.is_sdca) { | 1703 | if (slave->id.class_id) { |
| 1728 | ret = sdw_read_no_pm(slave, SDW_DP0_INT); | 1704 | ret = sdw_read_no_pm(slave, SDW_DP0_INT); |
| 1729 | if (ret < 0) { | 1705 | if (ret < 0) { |
| 1730 | dev_err(&slave->dev, | 1706 | dev_err(&slave->dev, |
| @@ -151,8 +151,7 @@ int sdw_configure_dpn_intr(struct sdw_slave *slave, int port, · 150 unmodified lines | |||
| 151 | bool enable, int mask); | 151 | bool enable, int mask); |
| 152 | 152 | ||
| 153 | int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg); | 153 | int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg); |
| 154 | int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg, | 154 | int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg); |
| 155 | struct sdw_defer *defer); | ||
| 156 | 155 | ||
| 157 | #define SDW_READ_INTR_CLEAR_RETRY 10 | 156 | #define SDW_READ_INTR_CLEAR_RETRY 10 |
| 158 | 157 | ||
| @@ -105,20 +105,19 @@ static int sdw_drv_probe(struct device *dev) · 104 unmodified lines | |||
| 105 | if (ret) | 105 | if (ret) |
| 106 | return ret; | 106 | return ret; |
| 107 | 107 | ||
| 108 | mutex_lock(&slave->sdw_dev_lock); | ||
| 109 | |||
| 110 | ret = drv->probe(slave, id); | 108 | ret = drv->probe(slave, id); |
| 111 | if (ret) { | 109 | if (ret) { |
| 112 | name = drv->name; | 110 | name = drv->name; |
| 113 | if (!name) | 111 | if (!name) |
| 114 | name = drv->driver.name; | 112 | name = drv->driver.name; |
| 115 | mutex_unlock(&slave->sdw_dev_lock); | ||
| 116 | 113 | ||
| 117 | dev_err(dev, "Probe of %s failed: %d\n", name, ret); | 114 | dev_err(dev, "Probe of %s failed: %d\n", name, ret); |
| 118 | dev_pm_domain_detach(dev, false); | 115 | dev_pm_domain_detach(dev, false); |
| 119 | return ret; | 116 | return ret; |
| 120 | } | 117 | } |
| 121 | 118 | ||
| 119 | mutex_lock(&slave->sdw_dev_lock); | ||
| 120 | |||
| 122 | /* device is probed so let's read the properties now */ | 121 | /* device is probed so let's read the properties now */ |
| 123 | if (drv->ops && drv->ops->read_prop) | 122 | if (drv->ops && drv->ops->read_prop) |
| 124 | drv->ops->read_prop(slave); | 123 | drv->ops->read_prop(slave); |
| @@ -167,14 +166,12 @@ static int sdw_drv_remove(struct device *dev) · 42 unmodified lines | |||
| 167 | int ret = 0; | 166 | int ret = 0; |
| 168 | 167 | ||
| 169 | mutex_lock(&slave->sdw_dev_lock); | 168 | mutex_lock(&slave->sdw_dev_lock); |
| 170 | |||
| 171 | slave->probed = false; | 169 | slave->probed = false; |
| 170 | mutex_unlock(&slave->sdw_dev_lock); | ||
| 172 | 171 | ||
| 173 | if (drv->remove) | 172 | if (drv->remove) |
| 174 | ret = drv->remove(slave); | 173 | ret = drv->remove(slave); |
| 175 | 174 | ||
| 176 | mutex_unlock(&slave->sdw_dev_lock); | ||
| 177 | |||
| 178 | dev_pm_domain_detach(dev, false); | 175 | dev_pm_domain_detach(dev, false); |
| 179 | 176 | ||
| 180 | return ret; | 177 | return ret; |
| @@ -127,7 +127,8 @@ MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask"); · 126 unmodified lines | |||
| 127 | 127 | ||
| 128 | #define CDNS_MCP_CMD_BASE 0x80 | 128 | #define CDNS_MCP_CMD_BASE 0x80 |
| 129 | #define CDNS_MCP_RESP_BASE 0x80 | 129 | #define CDNS_MCP_RESP_BASE 0x80 |
| 130 | #define CDNS_MCP_CMD_LEN 0x20 | 130 | /* FIFO can hold 8 commands */ |
| 131 | #define CDNS_MCP_CMD_LEN 8 | ||
| 131 | #define CDNS_MCP_CMD_WORD_LEN 0x4 | 132 | #define CDNS_MCP_CMD_WORD_LEN 0x4 |
| 132 | 133 | ||
| 133 | #define CDNS_MCP_CMD_SSP_TAG BIT(31) | 134 | #define CDNS_MCP_CMD_SSP_TAG BIT(31) |
| @@ -554,6 +555,29 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns, · 420 unmodified lines | |||
| 554 | return SDW_CMD_OK; | 555 | return SDW_CMD_OK; |
| 555 | } | 556 | } |
| 556 | 557 | ||
| 558 | static void cdns_read_response(struct sdw_cdns *cdns) | ||
| 559 | { | ||
| 560 | u32 num_resp, cmd_base; | ||
| 561 | int i; | ||
| 562 | |||
| 563 | /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ | ||
| 564 | BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2); | ||
| 565 | |||
| 566 | num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); | ||
| 567 | num_resp &= CDNS_MCP_RX_FIFO_AVAIL; | ||
| 568 | if (num_resp > ARRAY_SIZE(cdns->response_buf)) { | ||
| 569 | dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); | ||
| 570 | num_resp = ARRAY_SIZE(cdns->response_buf); | ||
| 571 | } | ||
| 572 | |||
| 573 | cmd_base = CDNS_MCP_CMD_BASE; | ||
| 574 | |||
| 575 | for (i = 0; i < num_resp; i++) { | ||
| 576 | cdns->response_buf[i] = cdns_readl(cdns, cmd_base); | ||
| 577 | cmd_base += CDNS_MCP_CMD_WORD_LEN; | ||
| 578 | } | ||
| 579 | } | ||
| 580 | |||
| 557 | static enum sdw_command_response | 581 | static enum sdw_command_response |
| 558 | _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, | 582 | _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, |
| 559 | int offset, int count, bool defer) | 583 | int offset, int count, bool defer) |
| @@ -595,6 +619,10 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, · 35 unmodified lines | |||
| 595 | dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n", | 619 | dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n", |
| 596 | cmd, msg->dev_num, msg->addr, msg->len); | 620 | cmd, msg->dev_num, msg->addr, msg->len); |
| 597 | msg->len = 0; | 621 | msg->len = 0; |
| 622 | |||
| 623 | /* Drain anything in the RX_FIFO */ | ||
| 624 | cdns_read_response(cdns); | ||
| 625 | |||
| 598 | return SDW_CMD_TIMEOUT; | 626 | return SDW_CMD_TIMEOUT; |
| 599 | } | 627 | } |
| 600 | 628 | ||
| @@ -721,10 +749,11 @@ cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg) · 120 unmodified lines | |||
| 721 | EXPORT_SYMBOL(cdns_xfer_msg); | 749 | EXPORT_SYMBOL(cdns_xfer_msg); |
| 722 | 750 | ||
| 723 | enum sdw_command_response | 751 | enum sdw_command_response |
| 724 | cdns_xfer_msg_defer(struct sdw_bus *bus, | 752 | cdns_xfer_msg_defer(struct sdw_bus *bus) |
| 725 | struct sdw_msg *msg, struct sdw_defer *defer) | ||
| 726 | { | 753 | { |
| 727 | struct sdw_cdns *cdns = bus_to_cdns(bus); | 754 | struct sdw_cdns *cdns = bus_to_cdns(bus); |
| 755 | struct sdw_defer *defer = &bus->defer_msg; | ||
| 756 | struct sdw_msg *msg = defer->msg; | ||
| 728 | int cmd = 0, ret; | 757 | int cmd = 0, ret; |
| 729 | 758 | ||
| 730 | /* for defer only 1 message is supported */ | 759 | /* for defer only 1 message is supported */ |
| @@ -735,27 +764,10 @@ cdns_xfer_msg_defer(struct sdw_bus *bus, · 4 unmodified lines | |||
| 735 | if (ret) | 764 | if (ret) |
| 736 | return SDW_CMD_FAIL_OTHER; | 765 | return SDW_CMD_FAIL_OTHER; |
| 737 | 766 | ||
| 738 | cdns->defer = defer; | ||
| 739 | cdns->defer->length = msg->len; | ||
| 740 | |||
| 741 | return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true); | 767 | return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true); |
| 742 | } | 768 | } |
| 743 | EXPORT_SYMBOL(cdns_xfer_msg_defer); | 769 | EXPORT_SYMBOL(cdns_xfer_msg_defer); |
| 744 | 770 | ||
| 745 | enum sdw_command_response | ||
| 746 | cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num) | ||
| 747 | { | ||
| 748 | struct sdw_cdns *cdns = bus_to_cdns(bus); | ||
| 749 | struct sdw_msg msg; | ||
| 750 | |||
| 751 | /* Create dummy message with valid device number */ | ||
| 752 | memset(&msg, 0, sizeof(msg)); | ||
| 753 | msg.dev_num = dev_num; | ||
| 754 | |||
| 755 | return cdns_program_scp_addr(cdns, &msg); | ||
| 756 | } | ||
| 757 | EXPORT_SYMBOL(cdns_reset_page_addr); | ||
| 758 | |||
| 759 | u32 cdns_read_ping_status(struct sdw_bus *bus) | 771 | u32 cdns_read_ping_status(struct sdw_bus *bus) |
| 760 | { | 772 | { |
| 761 | struct sdw_cdns *cdns = bus_to_cdns(bus); | 773 | struct sdw_cdns *cdns = bus_to_cdns(bus); |
| @@ -768,22 +780,6 @@ EXPORT_SYMBOL(cdns_read_ping_status); · 6 unmodified lines | |||
| 768 | * IRQ handling | 780 | * IRQ handling |
| 769 | */ | 781 | */ |
| 770 | 782 | ||
| 771 | static void cdns_read_response(struct sdw_cdns *cdns) | ||
| 772 | { | ||
| 773 | u32 num_resp, cmd_base; | ||
| 774 | int i; | ||
| 775 | |||
| 776 | num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); | ||
| 777 | num_resp &= CDNS_MCP_RX_FIFO_AVAIL; | ||
| 778 | |||
| 779 | cmd_base = CDNS_MCP_CMD_BASE; | ||
| 780 | |||
| 781 | for (i = 0; i < num_resp; i++) { | ||
| 782 | cdns->response_buf[i] = cdns_readl(cdns, cmd_base); | ||
| 783 | cmd_base += CDNS_MCP_CMD_WORD_LEN; | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | static int cdns_update_slave_status(struct sdw_cdns *cdns, | 783 | static int cdns_update_slave_status(struct sdw_cdns *cdns, |
| 788 | u64 slave_intstat) | 784 | u64 slave_intstat) |
| 789 | { | 785 | { |
| @@ -881,13 +877,15 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id) · 91 unmodified lines | |||
| 881 | return IRQ_NONE; | 877 | return IRQ_NONE; |
| 882 | 878 | ||
| 883 | if (int_status & CDNS_MCP_INT_RX_WL) { | 879 | if (int_status & CDNS_MCP_INT_RX_WL) { |
| 880 | struct sdw_bus *bus = &cdns->bus; | ||
| 881 | struct sdw_defer *defer = &bus->defer_msg; | ||
| 882 | |||
| 884 | cdns_read_response(cdns); | 883 | cdns_read_response(cdns); |
| 885 | 884 | ||
| 886 | if (cdns->defer) { | 885 | if (defer && defer->msg) { |
| 887 | cdns_fill_msg_resp(cdns, cdns->defer->msg, | 886 | cdns_fill_msg_resp(cdns, defer->msg, |
| 888 | cdns->defer->length, 0); | 887 | defer->length, 0); |
| 889 | complete(&cdns->defer->complete); | 888 | complete(&defer->complete); |
| 890 | cdns->defer = NULL; | ||
| 891 | } else { | 889 | } else { |
| 892 | complete(&cdns->tx_complete); | 890 | complete(&cdns->tx_complete); |
| 893 | } | 891 | } |
| @@ -8,6 +8,12 @@ · 7 unmodified lines | |||
| 8 | #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */ | 8 | #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */ |
| 9 | #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) | 9 | #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) |
| 10 | 10 | ||
| 11 | /* | ||
| 12 | * The Cadence IP supports up to 32 entries in the FIFO, though implementations | ||
| 13 | * can configure the IP to have a smaller FIFO. | ||
| 14 | */ | ||
| 15 | #define CDNS_MCP_IP_MAX_CMD_LEN 32 | ||
| 16 | |||
| 11 | /** | 17 | /** |
| 12 | * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance | 18 | * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance |
| 13 | * | 19 | * |
| @@ -103,7 +109,6 @@ struct sdw_cdns_dai_runtime { · 89 unmodified lines | |||
| 103 | * @instance: instance number | 109 | * @instance: instance number |
| 104 | * @response_buf: SoundWire response buffer | 110 | * @response_buf: SoundWire response buffer |
| 105 | * @tx_complete: Tx completion | 111 | * @tx_complete: Tx completion |
| 106 | * @defer: Defer pointer | ||
| 107 | * @ports: Data ports | 112 | * @ports: Data ports |
| 108 | * @num_ports: Total number of data ports | 113 | * @num_ports: Total number of data ports |
| 109 | * @pcm: PCM streams | 114 | * @pcm: PCM streams |
| @@ -117,9 +122,13 @@ struct sdw_cdns { · 7 unmodified lines | |||
| 117 | struct sdw_bus bus; | 122 | struct sdw_bus bus; |
| 118 | unsigned int instance; | 123 | unsigned int instance; |
| 119 | 124 | ||
| 120 | u32 response_buf[0x80]; | 125 | /* |
| 126 | * The datasheet says the RX FIFO AVAIL can be 2 entries more | ||
| 127 | * than the FIFO capacity, so allow for this. | ||
| 128 | */ | ||
| 129 | u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2]; | ||
| 130 | |||
| 121 | struct completion tx_complete; | 131 | struct completion tx_complete; |
| 122 | struct sdw_defer *defer; | ||
| 123 | 132 | ||
| 124 | struct sdw_cdns_port *ports; | 133 | struct sdw_cdns_port *ports; |
| 125 | int num_ports; | 134 | int num_ports; |
| @@ -147,7 +156,6 @@ struct sdw_cdns { · 21 unmodified lines | |||
| 147 | /* Exported symbols */ | 156 | /* Exported symbols */ |
| 148 | 157 | ||
| 149 | int sdw_cdns_probe(struct sdw_cdns *cdns); | 158 | int sdw_cdns_probe(struct sdw_cdns *cdns); |
| 150 | extern struct sdw_master_ops sdw_cdns_master_ops; | ||
| 151 | 159 | ||
| 152 | irqreturn_t sdw_cdns_irq(int irq, void *dev_id); | 160 | irqreturn_t sdw_cdns_irq(int irq, void *dev_id); |
| 153 | irqreturn_t sdw_cdns_thread(int irq, void *dev_id); | 161 | irqreturn_t sdw_cdns_thread(int irq, void *dev_id); |
| @@ -172,15 +180,11 @@ struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, · 18 unmodified lines | |||
| 172 | void sdw_cdns_config_stream(struct sdw_cdns *cdns, | 180 | void sdw_cdns_config_stream(struct sdw_cdns *cdns, |
| 173 | u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); | 181 | u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); |
| 174 | 182 | ||
| 175 | enum sdw_command_response | ||
| 176 | cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num); | ||
| 177 | |||
| 178 | enum sdw_command_response | 183 | enum sdw_command_response |
| 179 | cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg); | 184 | cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg); |
| 180 | 185 | ||
| 181 | enum sdw_command_response | 186 | enum sdw_command_response |
| 182 | cdns_xfer_msg_defer(struct sdw_bus *bus, | 187 | cdns_xfer_msg_defer(struct sdw_bus *bus); |
| 183 | struct sdw_msg *msg, struct sdw_defer *defer); | ||
| 184 | 188 | ||
| 185 | u32 cdns_read_ping_status(struct sdw_bus *bus); | 189 | u32 cdns_read_ping_status(struct sdw_bus *bus); |
| 186 | 190 | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | #include <linux/device.h> | 4 | #include <linux/device.h> |
| 5 | #include <linux/debugfs.h> | 5 | #include <linux/debugfs.h> |
| 6 | #include <linux/mod_devicetable.h> | 6 | #include <linux/mod_devicetable.h> |
| 7 | #include <linux/pm_runtime.h> | ||
| 7 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 8 | #include <linux/soundwire/sdw.h> | 9 | #include <linux/soundwire/sdw.h> |
| 9 | #include <linux/soundwire/sdw_registers.h> | 10 | #include <linux/soundwire/sdw_registers.h> |
| @@ -35,7 +36,7 @@ static ssize_t sdw_sprintf(struct sdw_slave *slave, · 25 unmodified lines | |||
| 35 | { | 36 | { |
| 36 | int value; | 37 | int value; |
| 37 | 38 | ||
| 38 | value = sdw_read(slave, reg); | 39 | value = sdw_read_no_pm(slave, reg); |
| 39 | 40 | ||
| 40 | if (value < 0) | 41 | if (value < 0) |
| 41 | return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg); | 42 | return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg); |
| @@ -55,6 +56,12 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data) · 13 unmodified lines | |||
| 55 | if (!buf) | 56 | if (!buf) |
| 56 | return -ENOMEM; | 57 | return -ENOMEM; |
| 57 | 58 | ||
| 59 | ret = pm_runtime_resume_and_get(&slave->dev); | ||
| 60 | if (ret < 0 && ret != -EACCES) { | ||
| 61 | kfree(buf); | ||
| 62 | return ret; | ||
| 63 | } | ||
| 64 | |||
| 58 | ret = scnprintf(buf, RD_BUF, "Register Value\n"); | 65 | ret = scnprintf(buf, RD_BUF, "Register Value\n"); |
| 59 | 66 | ||
| 60 | /* DP0 non-banked registers */ | 67 | /* DP0 non-banked registers */ |
| @@ -112,6 +119,10 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data) · 51 unmodified lines | |||
| 112 | } | 119 | } |
| 113 | 120 | ||
| 114 | seq_printf(s_file, "%s", buf); | 121 | seq_printf(s_file, "%s", buf); |
| 122 | |||
| 123 | pm_runtime_mark_last_busy(&slave->dev); | ||
| 124 | pm_runtime_put(&slave->dev); | ||
| 125 | |||
| 115 | kfree(buf); | 126 | kfree(buf); |
| 116 | 127 | ||
| 117 | return 0; | 128 | return 0; |
| @@ -778,22 +778,6 @@ unlock: · 777 unmodified lines | |||
| 778 | * DAI routines | 778 | * DAI routines |
| 779 | */ | 779 | */ |
| 780 | 780 | ||
| 781 | static int intel_startup(struct snd_pcm_substream *substream, | ||
| 782 | struct snd_soc_dai *dai) | ||
| 783 | { | ||
| 784 | struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); | ||
| 785 | int ret; | ||
| 786 | |||
| 787 | ret = pm_runtime_resume_and_get(cdns->dev); | ||
| 788 | if (ret < 0 && ret != -EACCES) { | ||
| 789 | dev_err_ratelimited(cdns->dev, | ||
| 790 | "pm_runtime_resume_and_get failed in %s, ret %d\n", | ||
| 791 | __func__, ret); | ||
| 792 | return ret; | ||
| 793 | } | ||
| 794 | return 0; | ||
| 795 | } | ||
| 796 | |||
| 797 | static int intel_hw_params(struct snd_pcm_substream *substream, | 781 | static int intel_hw_params(struct snd_pcm_substream *substream, |
| 798 | struct snd_pcm_hw_params *params, | 782 | struct snd_pcm_hw_params *params, |
| 799 | struct snd_soc_dai *dai) | 783 | struct snd_soc_dai *dai) |
| @@ -954,15 +938,6 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) · 154 unmodified lines | |||
| 954 | return 0; | 938 | return 0; |
| 955 | } | 939 | } |
| 956 | 940 | ||
| 957 | static void intel_shutdown(struct snd_pcm_substream *substream, | ||
| 958 | struct snd_soc_dai *dai) | ||
| 959 | { | ||
| 960 | struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); | ||
| 961 | |||
| 962 | pm_runtime_mark_last_busy(cdns->dev); | ||
| 963 | pm_runtime_put_autosuspend(cdns->dev); | ||
| 964 | } | ||
| 965 | |||
| 966 | static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai, | 941 | static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai, |
| 967 | void *stream, int direction) | 942 | void *stream, int direction) |
| 968 | { | 943 | { |
| @@ -1088,12 +1063,10 @@ static int intel_component_dais_suspend(struct snd_soc_component *component) · 119 unmodified lines | |||
| 1088 | } | 1063 | } |
| 1089 | 1064 | ||
| 1090 | static const struct snd_soc_dai_ops intel_pcm_dai_ops = { | 1065 | static const struct snd_soc_dai_ops intel_pcm_dai_ops = { |
| 1091 | .startup = intel_startup, | ||
| 1092 | .hw_params = intel_hw_params, | 1066 | .hw_params = intel_hw_params, |
| 1093 | .prepare = intel_prepare, | 1067 | .prepare = intel_prepare, |
| 1094 | .hw_free = intel_hw_free, | 1068 | .hw_free = intel_hw_free, |
| 1095 | .trigger = intel_trigger, | 1069 | .trigger = intel_trigger, |
| 1096 | .shutdown = intel_shutdown, | ||
| 1097 | .set_stream = intel_pcm_set_sdw_stream, | 1070 | .set_stream = intel_pcm_set_sdw_stream, |
| 1098 | .get_stream = intel_get_sdw_stream, | 1071 | .get_stream = intel_get_sdw_stream, |
| 1099 | }; | 1072 | }; |
| @@ -113,7 +113,6 @@ static struct sdw_master_ops sdw_intel_ops = { · 112 unmodified lines | |||
| 113 | .override_adr = sdw_dmi_override_adr, | 113 | .override_adr = sdw_dmi_override_adr, |
| 114 | .xfer_msg = cdns_xfer_msg, | 114 | .xfer_msg = cdns_xfer_msg, |
| 115 | .xfer_msg_defer = cdns_xfer_msg_defer, | 115 | .xfer_msg_defer = cdns_xfer_msg_defer, |
| 116 | .reset_page_addr = cdns_reset_page_addr, | ||
| 117 | .set_bus_conf = cdns_bus_conf, | 116 | .set_bus_conf = cdns_bus_conf, |
| 118 | .pre_bank_switch = generic_pre_bank_switch, | 117 | .pre_bank_switch = generic_pre_bank_switch, |
| 119 | .post_bank_switch = generic_post_bank_switch, | 118 | .post_bank_switch = generic_post_bank_switch, |
| @@ -81,14 +81,14 @@ static int _sdw_program_slave_port_params(struct sdw_bus *bus, · 80 unmodified lines | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /* Program DPN_OffsetCtrl2 registers */ | 83 | /* Program DPN_OffsetCtrl2 registers */ |
| 84 | ret = sdw_write(slave, addr1, t_params->offset2); | 84 | ret = sdw_write_no_pm(slave, addr1, t_params->offset2); |
| 85 | if (ret < 0) { | 85 | if (ret < 0) { |
| 86 | dev_err(bus->dev, "DPN_OffsetCtrl2 register write failed\n"); | 86 | dev_err(bus->dev, "DPN_OffsetCtrl2 register write failed\n"); |
| 87 | return ret; | 87 | return ret; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | /* Program DPN_BlockCtrl3 register */ | 90 | /* Program DPN_BlockCtrl3 register */ |
| 91 | ret = sdw_write(slave, addr2, t_params->blk_pkg_mode); | 91 | ret = sdw_write_no_pm(slave, addr2, t_params->blk_pkg_mode); |
| 92 | if (ret < 0) { | 92 | if (ret < 0) { |
| 93 | dev_err(bus->dev, "DPN_BlockCtrl3 register write failed\n"); | 93 | dev_err(bus->dev, "DPN_BlockCtrl3 register write failed\n"); |
| 94 | return ret; | 94 | return ret; |
| @@ -105,7 +105,7 @@ static int _sdw_program_slave_port_params(struct sdw_bus *bus, · 10 unmodified lines | |||
| 105 | /* Program DPN_SampleCtrl2 register */ | 105 | /* Program DPN_SampleCtrl2 register */ |
| 106 | wbuf = FIELD_GET(SDW_DPN_SAMPLECTRL_HIGH, t_params->sample_interval - 1); | 106 | wbuf = FIELD_GET(SDW_DPN_SAMPLECTRL_HIGH, t_params->sample_interval - 1); |
| 107 | 107 | ||
| 108 | ret = sdw_write(slave, addr3, wbuf); | 108 | ret = sdw_write_no_pm(slave, addr3, wbuf); |
| 109 | if (ret < 0) { | 109 | if (ret < 0) { |
| 110 | dev_err(bus->dev, "DPN_SampleCtrl2 register write failed\n"); | 110 | dev_err(bus->dev, "DPN_SampleCtrl2 register write failed\n"); |
| 111 | return ret; | 111 | return ret; |
| @@ -115,7 +115,7 @@ static int _sdw_program_slave_port_params(struct sdw_bus *bus, · 3 unmodified lines | |||
| 115 | wbuf = FIELD_PREP(SDW_DPN_HCTRL_HSTART, t_params->hstart); | 115 | wbuf = FIELD_PREP(SDW_DPN_HCTRL_HSTART, t_params->hstart); |
| 116 | wbuf |= FIELD_PREP(SDW_DPN_HCTRL_HSTOP, t_params->hstop); | 116 | wbuf |= FIELD_PREP(SDW_DPN_HCTRL_HSTOP, t_params->hstop); |
| 117 | 117 | ||
| 118 | ret = sdw_write(slave, addr4, wbuf); | 118 | ret = sdw_write_no_pm(slave, addr4, wbuf); |
| 119 | if (ret < 0) | 119 | if (ret < 0) |
| 120 | dev_err(bus->dev, "DPN_HCtrl register write failed\n"); | 120 | dev_err(bus->dev, "DPN_HCtrl register write failed\n"); |
| 121 | 121 | ||
| @@ -163,7 +163,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 41 unmodified lines | |||
| 163 | wbuf = FIELD_PREP(SDW_DPN_PORTCTRL_DATAMODE, p_params->data_mode); | 163 | wbuf = FIELD_PREP(SDW_DPN_PORTCTRL_DATAMODE, p_params->data_mode); |
| 164 | wbuf |= FIELD_PREP(SDW_DPN_PORTCTRL_FLOWMODE, p_params->flow_mode); | 164 | wbuf |= FIELD_PREP(SDW_DPN_PORTCTRL_FLOWMODE, p_params->flow_mode); |
| 165 | 165 | ||
| 166 | ret = sdw_update(s_rt->slave, addr1, 0xF, wbuf); | 166 | ret = sdw_update_no_pm(s_rt->slave, addr1, 0xF, wbuf); |
| 167 | if (ret < 0) { | 167 | if (ret < 0) { |
| 168 | dev_err(&s_rt->slave->dev, | 168 | dev_err(&s_rt->slave->dev, |
| 169 | "DPN_PortCtrl register write failed for port %d\n", | 169 | "DPN_PortCtrl register write failed for port %d\n", |
| @@ -173,7 +173,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 3 unmodified lines | |||
| 173 | 173 | ||
| 174 | if (!dpn_prop->read_only_wordlength) { | 174 | if (!dpn_prop->read_only_wordlength) { |
| 175 | /* Program DPN_BlockCtrl1 register */ | 175 | /* Program DPN_BlockCtrl1 register */ |
| 176 | ret = sdw_write(s_rt->slave, addr2, (p_params->bps - 1)); | 176 | ret = sdw_write_no_pm(s_rt->slave, addr2, (p_params->bps - 1)); |
| 177 | if (ret < 0) { | 177 | if (ret < 0) { |
| 178 | dev_err(&s_rt->slave->dev, | 178 | dev_err(&s_rt->slave->dev, |
| 179 | "DPN_BlockCtrl1 register write failed for port %d\n", | 179 | "DPN_BlockCtrl1 register write failed for port %d\n", |
| @@ -184,7 +184,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 4 unmodified lines | |||
| 184 | 184 | ||
| 185 | /* Program DPN_SampleCtrl1 register */ | 185 | /* Program DPN_SampleCtrl1 register */ |
| 186 | wbuf = (t_params->sample_interval - 1) & SDW_DPN_SAMPLECTRL_LOW; | 186 | wbuf = (t_params->sample_interval - 1) & SDW_DPN_SAMPLECTRL_LOW; |
| 187 | ret = sdw_write(s_rt->slave, addr3, wbuf); | 187 | ret = sdw_write_no_pm(s_rt->slave, addr3, wbuf); |
| 188 | if (ret < 0) { | 188 | if (ret < 0) { |
| 189 | dev_err(&s_rt->slave->dev, | 189 | dev_err(&s_rt->slave->dev, |
| 190 | "DPN_SampleCtrl1 register write failed for port %d\n", | 190 | "DPN_SampleCtrl1 register write failed for port %d\n", |
| @@ -193,7 +193,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 2 unmodified lines | |||
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | /* Program DPN_OffsetCtrl1 registers */ | 195 | /* Program DPN_OffsetCtrl1 registers */ |
| 196 | ret = sdw_write(s_rt->slave, addr4, t_params->offset1); | 196 | ret = sdw_write_no_pm(s_rt->slave, addr4, t_params->offset1); |
| 197 | if (ret < 0) { | 197 | if (ret < 0) { |
| 198 | dev_err(&s_rt->slave->dev, | 198 | dev_err(&s_rt->slave->dev, |
| 199 | "DPN_OffsetCtrl1 register write failed for port %d\n", | 199 | "DPN_OffsetCtrl1 register write failed for port %d\n", |
| @@ -203,7 +203,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 3 unmodified lines | |||
| 203 | 203 | ||
| 204 | /* Program DPN_BlockCtrl2 register*/ | 204 | /* Program DPN_BlockCtrl2 register*/ |
| 205 | if (t_params->blk_grp_ctrl_valid) { | 205 | if (t_params->blk_grp_ctrl_valid) { |
| 206 | ret = sdw_write(s_rt->slave, addr5, t_params->blk_grp_ctrl); | 206 | ret = sdw_write_no_pm(s_rt->slave, addr5, t_params->blk_grp_ctrl); |
| 207 | if (ret < 0) { | 207 | if (ret < 0) { |
| 208 | dev_err(&s_rt->slave->dev, | 208 | dev_err(&s_rt->slave->dev, |
| 209 | "DPN_BlockCtrl2 reg write failed for port %d\n", | 209 | "DPN_BlockCtrl2 reg write failed for port %d\n", |
| @@ -214,7 +214,7 @@ static int sdw_program_slave_port_params(struct sdw_bus *bus, · 4 unmodified lines | |||
| 214 | 214 | ||
| 215 | /* program DPN_LaneCtrl register */ | 215 | /* program DPN_LaneCtrl register */ |
| 216 | if (slave_prop->lane_control_support) { | 216 | if (slave_prop->lane_control_support) { |
| 217 | ret = sdw_write(s_rt->slave, addr6, t_params->lane_ctrl); | 217 | ret = sdw_write_no_pm(s_rt->slave, addr6, t_params->lane_ctrl); |
| 218 | if (ret < 0) { | 218 | if (ret < 0) { |
| 219 | dev_err(&s_rt->slave->dev, | 219 | dev_err(&s_rt->slave->dev, |
| 220 | "DPN_LaneCtrl register write failed for port %d\n", | 220 | "DPN_LaneCtrl register write failed for port %d\n", |
| @@ -319,9 +319,9 @@ static int sdw_enable_disable_slave_ports(struct sdw_bus *bus, · 98 unmodified lines | |||
| 319 | * it is safe to reset this register | 319 | * it is safe to reset this register |
| 320 | */ | 320 | */ |
| 321 | if (en) | 321 | if (en) |
| 322 | ret = sdw_write(s_rt->slave, addr, p_rt->ch_mask); | 322 | ret = sdw_write_no_pm(s_rt->slave, addr, p_rt->ch_mask); |
| 323 | else | 323 | else |
| 324 | ret = sdw_write(s_rt->slave, addr, 0x0); | 324 | ret = sdw_write_no_pm(s_rt->slave, addr, 0x0); |
| 325 | 325 | ||
| 326 | if (ret < 0) | 326 | if (ret < 0) |
| 327 | dev_err(&s_rt->slave->dev, | 327 | dev_err(&s_rt->slave->dev, |
| @@ -476,9 +476,9 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, · 148 unmodified lines | |||
| 476 | addr = SDW_DPN_PREPARECTRL(p_rt->num); | 476 | addr = SDW_DPN_PREPARECTRL(p_rt->num); |
| 477 | 477 | ||
| 478 | if (prep) | 478 | if (prep) |
| 479 | ret = sdw_write(s_rt->slave, addr, p_rt->ch_mask); | 479 | ret = sdw_write_no_pm(s_rt->slave, addr, p_rt->ch_mask); |
| 480 | else | 480 | else |
| 481 | ret = sdw_write(s_rt->slave, addr, 0x0); | 481 | ret = sdw_write_no_pm(s_rt->slave, addr, 0x0); |
| 482 | 482 | ||
| 483 | if (ret < 0) { | 483 | if (ret < 0) { |
| 484 | dev_err(&s_rt->slave->dev, | 484 | dev_err(&s_rt->slave->dev, |
| @@ -491,7 +491,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, · 6 unmodified lines | |||
| 491 | wait_for_completion_timeout(port_ready, | 491 | wait_for_completion_timeout(port_ready, |
| 492 | msecs_to_jiffies(dpn_prop->ch_prep_timeout)); | 492 | msecs_to_jiffies(dpn_prop->ch_prep_timeout)); |
| 493 | 493 | ||
| 494 | val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); | 494 | val = sdw_read_no_pm(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); |
| 495 | if ((val < 0) || (val & p_rt->ch_mask)) { | 495 | if ((val < 0) || (val & p_rt->ch_mask)) { |
| 496 | ret = (val < 0) ? val : -ETIMEDOUT; | 496 | ret = (val < 0) ? val : -ETIMEDOUT; |
| 497 | dev_err(&s_rt->slave->dev, | 497 | dev_err(&s_rt->slave->dev, |
| @@ -684,8 +684,6 @@ static int sdw_bank_switch(struct sdw_bus *bus, int m_rt_count) · 186 unmodified lines | |||
| 684 | if (!wr_msg) | 684 | if (!wr_msg) |
| 685 | return -ENOMEM; | 685 | return -ENOMEM; |
| 686 | 686 | ||
| 687 | bus->defer_msg.msg = wr_msg; | ||
| 688 | |||
| 689 | wbuf = kzalloc(sizeof(*wbuf), GFP_KERNEL); | 687 | wbuf = kzalloc(sizeof(*wbuf), GFP_KERNEL); |
| 690 | if (!wbuf) { | 688 | if (!wbuf) { |
| 691 | ret = -ENOMEM; | 689 | ret = -ENOMEM; |
| @@ -713,7 +711,7 @@ static int sdw_bank_switch(struct sdw_bus *bus, int m_rt_count) · 21 unmodified lines | |||
| 713 | multi_link = bus->multi_link && (m_rt_count >= bus->hw_sync_min_links); | 711 | multi_link = bus->multi_link && (m_rt_count >= bus->hw_sync_min_links); |
| 714 | 712 | ||
| 715 | if (multi_link) | 713 | if (multi_link) |
| 716 | ret = sdw_transfer_defer(bus, wr_msg, &bus->defer_msg); | 714 | ret = sdw_transfer_defer(bus, wr_msg); |
| 717 | else | 715 | else |
| 718 | ret = sdw_transfer(bus, wr_msg); | 716 | ret = sdw_transfer(bus, wr_msg); |
| 719 | 717 | ||
| @@ -723,8 +721,8 @@ static int sdw_bank_switch(struct sdw_bus *bus, int m_rt_count) · 3 unmodified lines | |||
| 723 | } | 721 | } |
| 724 | 722 | ||
| 725 | if (!multi_link) { | 723 | if (!multi_link) { |
| 726 | kfree(wr_msg); | ||
| 727 | kfree(wbuf); | 724 | kfree(wbuf); |
| 725 | kfree(wr_msg); | ||
| 728 | bus->defer_msg.msg = NULL; | 726 | bus->defer_msg.msg = NULL; |
| 729 | bus->params.curr_bank = !bus->params.curr_bank; | 727 | bus->params.curr_bank = !bus->params.curr_bank; |
| 730 | bus->params.next_bank = !bus->params.next_bank; | 728 | bus->params.next_bank = !bus->params.next_bank; |
| @@ -769,6 +767,7 @@ static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) · 38 unmodified lines | |||
| 769 | if (bus->defer_msg.msg) { | 767 | if (bus->defer_msg.msg) { |
| 770 | kfree(bus->defer_msg.msg->buf); | 768 | kfree(bus->defer_msg.msg->buf); |
| 771 | kfree(bus->defer_msg.msg); | 769 | kfree(bus->defer_msg.msg); |
| 770 | bus->defer_msg.msg = NULL; | ||
| 772 | } | 771 | } |
| 773 | 772 | ||
| 774 | return 0; | 773 | return 0; |
| @@ -867,6 +866,7 @@ error: · 92 unmodified lines | |||
| 867 | if (bus->defer_msg.msg) { | 866 | if (bus->defer_msg.msg) { |
| 868 | kfree(bus->defer_msg.msg->buf); | 867 | kfree(bus->defer_msg.msg->buf); |
| 869 | kfree(bus->defer_msg.msg); | 868 | kfree(bus->defer_msg.msg); |
| 869 | bus->defer_msg.msg = NULL; | ||
| 870 | } | 870 | } |
| 871 | } | 871 | } |
| 872 | 872 | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | #ifndef __SOUNDWIRE_H | 4 | #ifndef __SOUNDWIRE_H |
| 5 | #define __SOUNDWIRE_H | 5 | #define __SOUNDWIRE_H |
| 6 | 6 | ||
| 7 | #include <linux/bug.h> | ||
| 7 | #include <linux/mod_devicetable.h> | 8 | #include <linux/mod_devicetable.h> |
| 8 | #include <linux/bitfield.h> | 9 | #include <linux/bitfield.h> |
| 9 | 10 | ||
| @@ -365,7 +366,9 @@ struct sdw_dpn_prop { · 355 unmodified lines | |||
| 365 | * @sink_dpn_prop: Sink Data Port N properties | 366 | * @sink_dpn_prop: Sink Data Port N properties |
| 366 | * @scp_int1_mask: SCP_INT1_MASK desired settings | 367 | * @scp_int1_mask: SCP_INT1_MASK desired settings |
| 367 | * @quirks: bitmask identifying deltas from the MIPI specification | 368 | * @quirks: bitmask identifying deltas from the MIPI specification |
| 368 | * @is_sdca: the Slave supports the SDCA specification | 369 | * @clock_reg_supported: the Peripheral implements the clock base and scale |
| 370 | * registers introduced with the SoundWire 1.2 specification. SDCA devices | ||
| 371 | * do not need to set this boolean property as the registers are required. | ||
| 369 | */ | 372 | */ |
| 370 | struct sdw_slave_prop { | 373 | struct sdw_slave_prop { |
| 371 | u32 mipi_revision; | 374 | u32 mipi_revision; |
| @@ -389,7 +392,7 @@ struct sdw_slave_prop { · 17 unmodified lines | |||
| 389 | struct sdw_dpn_prop *sink_dpn_prop; | 392 | struct sdw_dpn_prop *sink_dpn_prop; |
| 390 | u8 scp_int1_mask; | 393 | u8 scp_int1_mask; |
| 391 | u32 quirks; | 394 | u32 quirks; |
| 392 | bool is_sdca; | 395 | bool clock_reg_supported; |
| 393 | }; | 396 | }; |
| 394 | 397 | ||
| 395 | #define SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY BIT(0) | 398 | #define SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY BIT(0) |
| @@ -836,8 +839,8 @@ struct sdw_defer { · 440 unmodified lines | |||
| 836 | * @read_prop: Read Master properties | 839 | * @read_prop: Read Master properties |
| 837 | * @override_adr: Override value read from firmware (quirk for buggy firmware) | 840 | * @override_adr: Override value read from firmware (quirk for buggy firmware) |
| 838 | * @xfer_msg: Transfer message callback | 841 | * @xfer_msg: Transfer message callback |
| 839 | * @xfer_msg_defer: Defer version of transfer message callback | 842 | * @xfer_msg_defer: Defer version of transfer message callback. The message is handled with the |
| 840 | * @reset_page_addr: Reset the SCP page address registers | 843 | * bus struct @sdw_defer |
| 841 | * @set_bus_conf: Set the bus configuration | 844 | * @set_bus_conf: Set the bus configuration |
| 842 | * @pre_bank_switch: Callback for pre bank switch | 845 | * @pre_bank_switch: Callback for pre bank switch |
| 843 | * @post_bank_switch: Callback for post bank switch | 846 | * @post_bank_switch: Callback for post bank switch |
| @@ -851,10 +854,7 @@ struct sdw_master_ops { · 7 unmodified lines | |||
| 851 | enum sdw_command_response (*xfer_msg) | 854 | enum sdw_command_response (*xfer_msg) |
| 852 | (struct sdw_bus *bus, struct sdw_msg *msg); | 855 | (struct sdw_bus *bus, struct sdw_msg *msg); |
| 853 | enum sdw_command_response (*xfer_msg_defer) | 856 | enum sdw_command_response (*xfer_msg_defer) |
| 854 | (struct sdw_bus *bus, struct sdw_msg *msg, | 857 | (struct sdw_bus *bus); |
| 855 | struct sdw_defer *defer); | ||
| 856 | enum sdw_command_response (*reset_page_addr) | ||
| 857 | (struct sdw_bus *bus, unsigned int dev_num); | ||
| 858 | int (*set_bus_conf)(struct sdw_bus *bus, | 858 | int (*set_bus_conf)(struct sdw_bus *bus, |
| 859 | struct sdw_bus_params *params); | 859 | struct sdw_bus_params *params); |
| 860 | int (*pre_bank_switch)(struct sdw_bus *bus); | 860 | int (*pre_bank_switch)(struct sdw_bus *bus); |
| @@ -1023,15 +1023,8 @@ int sdw_stream_add_master(struct sdw_bus *bus, · 162 unmodified lines | |||
| 1023 | struct sdw_port_config *port_config, | 1023 | struct sdw_port_config *port_config, |
| 1024 | unsigned int num_ports, | 1024 | unsigned int num_ports, |
| 1025 | struct sdw_stream_runtime *stream); | 1025 | struct sdw_stream_runtime *stream); |
| 1026 | int sdw_stream_add_slave(struct sdw_slave *slave, | ||
| 1027 | struct sdw_stream_config *stream_config, | ||
| 1028 | struct sdw_port_config *port_config, | ||
| 1029 | unsigned int num_ports, | ||
| 1030 | struct sdw_stream_runtime *stream); | ||
| 1031 | int sdw_stream_remove_master(struct sdw_bus *bus, | 1026 | int sdw_stream_remove_master(struct sdw_bus *bus, |
| 1032 | struct sdw_stream_runtime *stream); | 1027 | struct sdw_stream_runtime *stream); |
| 1033 | int sdw_stream_remove_slave(struct sdw_slave *slave, | ||
| 1034 | struct sdw_stream_runtime *stream); | ||
| 1035 | int sdw_startup_stream(void *sdw_substream); | 1028 | int sdw_startup_stream(void *sdw_substream); |
| 1036 | int sdw_prepare_stream(struct sdw_stream_runtime *stream); | 1029 | int sdw_prepare_stream(struct sdw_stream_runtime *stream); |
| 1037 | int sdw_enable_stream(struct sdw_stream_runtime *stream); | 1030 | int sdw_enable_stream(struct sdw_stream_runtime *stream); |
| @@ -1042,18 +1035,111 @@ int sdw_bus_prep_clk_stop(struct sdw_bus *bus); · 4 unmodified lines | |||
| 1042 | int sdw_bus_clk_stop(struct sdw_bus *bus); | 1035 | int sdw_bus_clk_stop(struct sdw_bus *bus); |
| 1043 | int sdw_bus_exit_clk_stop(struct sdw_bus *bus); | 1036 | int sdw_bus_exit_clk_stop(struct sdw_bus *bus); |
| 1044 | 1037 | ||
| 1045 | /* messaging and data APIs */ | 1038 | int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id); |
| 1039 | void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id); | ||
| 1046 | 1040 | ||
| 1041 | #if IS_ENABLED(CONFIG_SOUNDWIRE) | ||
| 1042 | |||
| 1043 | int sdw_stream_add_slave(struct sdw_slave *slave, | ||
| 1044 | struct sdw_stream_config *stream_config, | ||
| 1045 | struct sdw_port_config *port_config, | ||
| 1046 | unsigned int num_ports, | ||
| 1047 | struct sdw_stream_runtime *stream); | ||
| 1048 | int sdw_stream_remove_slave(struct sdw_slave *slave, | ||
| 1049 | struct sdw_stream_runtime *stream); | ||
| 1050 | |||
| 1051 | /* messaging and data APIs */ | ||
| 1047 | int sdw_read(struct sdw_slave *slave, u32 addr); | 1052 | int sdw_read(struct sdw_slave *slave, u32 addr); |
| 1048 | int sdw_write(struct sdw_slave *slave, u32 addr, u8 value); | 1053 | int sdw_write(struct sdw_slave *slave, u32 addr, u8 value); |
| 1049 | int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value); | 1054 | int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value); |
| 1050 | int sdw_read_no_pm(struct sdw_slave *slave, u32 addr); | 1055 | int sdw_read_no_pm(struct sdw_slave *slave, u32 addr); |
| 1051 | int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val); | 1056 | int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val); |
| 1057 | int sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val); | ||
| 1052 | int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val); | 1058 | int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val); |
| 1059 | int sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val); | ||
| 1053 | int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val); | 1060 | int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val); |
| 1054 | int sdw_update_no_pm(struct sdw_slave *slave, u32 addr, u8 mask, u8 val); | 1061 | int sdw_update_no_pm(struct sdw_slave *slave, u32 addr, u8 mask, u8 val); |
| 1055 | 1062 | ||
| 1056 | int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id); | 1063 | #else |
| 1057 | void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id); | 1064 | |
| 1065 | static inline int sdw_stream_add_slave(struct sdw_slave *slave, | ||
| 1066 | struct sdw_stream_config *stream_config, | ||
| 1067 | struct sdw_port_config *port_config, | ||
| 1068 | unsigned int num_ports, | ||
| 1069 | struct sdw_stream_runtime *stream) | ||
| 1070 | { | ||
| 1071 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1072 | return -EINVAL; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | static inline int sdw_stream_remove_slave(struct sdw_slave *slave, | ||
| 1076 | struct sdw_stream_runtime *stream) | ||
| 1077 | { | ||
| 1078 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1079 | return -EINVAL; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | /* messaging and data APIs */ | ||
| 1083 | static inline int sdw_read(struct sdw_slave *slave, u32 addr) | ||
| 1084 | { | ||
| 1085 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1086 | return -EINVAL; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | static inline int sdw_write(struct sdw_slave *slave, u32 addr, u8 value) | ||
| 1090 | { | ||
| 1091 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1092 | return -EINVAL; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | static inline int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value) | ||
| 1096 | { | ||
| 1097 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1098 | return -EINVAL; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | static inline int sdw_read_no_pm(struct sdw_slave *slave, u32 addr) | ||
| 1102 | { | ||
| 1103 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1104 | return -EINVAL; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | static inline int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val) | ||
| 1108 | { | ||
| 1109 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1110 | return -EINVAL; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | static inline int sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val) | ||
| 1114 | { | ||
| 1115 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1116 | return -EINVAL; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | static inline int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val) | ||
| 1120 | { | ||
| 1121 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1122 | return -EINVAL; | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | static inline int sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val) | ||
| 1126 | { | ||
| 1127 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1128 | return -EINVAL; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | static inline int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val) | ||
| 1132 | { | ||
| 1133 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1134 | return -EINVAL; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | static inline int sdw_update_no_pm(struct sdw_slave *slave, u32 addr, u8 mask, u8 val) | ||
| 1138 | { | ||
| 1139 | WARN_ONCE(1, "SoundWire API is disabled"); | ||
| 1140 | return -EINVAL; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | #endif /* CONFIG_SOUNDWIRE */ | ||
| 1058 | 1144 | ||
| 1059 | #endif /* __SOUNDWIRE_H */ | 1145 | #endif /* __SOUNDWIRE_H */ |
| @@ -204,7 +204,6 @@ static int rt1316_read_prop(struct sdw_slave *slave) · 203 unmodified lines | |||
| 204 | 204 | ||
| 205 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; | 205 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; |
| 206 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; | 206 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; |
| 207 | prop->is_sdca = true; | ||
| 208 | 207 | ||
| 209 | prop->paging_support = true; | 208 | prop->paging_support = true; |
| 210 | 209 | ||
| @@ -353,7 +353,6 @@ static int rt1318_read_prop(struct sdw_slave *slave) · 352 unmodified lines | |||
| 353 | 353 | ||
| 354 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; | 354 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; |
| 355 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; | 355 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; |
| 356 | prop->is_sdca = true; | ||
| 357 | 356 | ||
| 358 | prop->paging_support = true; | 357 | prop->paging_support = true; |
| 359 | 358 | ||
| @@ -186,7 +186,6 @@ static int rt711_sdca_read_prop(struct sdw_slave *slave) · 185 unmodified lines | |||
| 186 | 186 | ||
| 187 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; | 187 | prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; |
| 188 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; | 188 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; |
| 189 | prop->is_sdca = true; | ||
| 190 | 189 | ||
| 191 | prop->paging_support = true; | 190 | prop->paging_support = true; |
| 192 | 191 | ||