diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-03 11:36:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-03 11:36:34 -0700 |
commit | 6f9b5ed8caddfbc94af8307c557ed57a8ec5c65c (patch) | |
tree | dda90fb07a35fc07cf0cedc22f0f6be61b29cf53 /drivers/soundwire/cadence_master.c | |
parent | 54c2cc79194c961a213c1d375fe3aa4165664cc4 (diff) | |
parent | 90de6805267f8c79cd2b1a36805071e257c39b5c (diff) |
Merge tag 'char-misc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc / other smaller driver subsystem updates from Greg KH:
"Here is the large set of char, misc, and other driver subsystem
updates for 5.19-rc1. The merge request for this has been delayed as I
wanted to get lots of linux-next testing due to some late arrivals of
changes for the habannalabs driver.
Highlights of this merge are:
- habanalabs driver updates for new hardware types and fixes and
other updates
- IIO driver tree merge which includes loads of new IIO drivers and
cleanups and additions
- PHY driver tree merge with new drivers and small updates to
existing ones
- interconnect driver tree merge with fixes and updates
- soundwire driver tree merge with some small fixes
- coresight driver tree merge with small fixes and updates
- mhi bus driver tree merge with lots of updates and new device
support
- firmware driver updates
- fpga driver updates
- lkdtm driver updates (with a merge conflict, more on that below)
- extcon driver tree merge with small updates
- lots of other tiny driver updates and fixes and cleanups, full
details in the shortlog.
All of these have been in linux-next for almost 2 weeks with no
reported problems"
* tag 'char-misc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (387 commits)
habanalabs: use separate structure info for each error collect data
habanalabs: fix missing handle shift during mmap
habanalabs: remove hdev from hl_ctx_get args
habanalabs: do MMU prefetch as deferred work
habanalabs: order memory manager messages
habanalabs: return -EFAULT on copy_to_user error
habanalabs: use NULL for eventfd
habanalabs: update firmware header
habanalabs: add support for notification via eventfd
habanalabs: add topic to memory manager buffer
habanalabs: handle race in driver fini
habanalabs: add device memory scrub ability through debugfs
habanalabs: use unified memory manager for CB flow
habanalabs: unified memory manager new code for CB flow
habanalabs/gaudi: set arbitration timeout to a high value
habanalabs: add put by handle method to memory manager
habanalabs: hide memory manager page shift
habanalabs: Add separate poll interval value for protocol
habanalabs: use get_task_pid() to take PID
habanalabs: add prefetch flag to the MAP operation
...
Diffstat (limited to 'drivers/soundwire/cadence_master.c')
-rw-r--r-- | drivers/soundwire/cadence_master.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 558390af44b6..4fbb19557f5e 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -386,12 +386,11 @@ static int cdns_parity_error_injection(void *data, u64 value) * Resume Master device. If this results in a bus reset, the * Slave devices will re-attach and be re-enumerated. */ - ret = pm_runtime_get_sync(bus->dev); + ret = pm_runtime_resume_and_get(bus->dev); if (ret < 0 && ret != -EACCES) { dev_err_ratelimited(cdns->dev, - "pm_runtime_get_sync failed in %s, ret %d\n", + "pm_runtime_resume_and_get failed in %s, ret %d\n", __func__, ret); - pm_runtime_put_noidle(bus->dev); return ret; } @@ -959,6 +958,8 @@ static void cdns_update_slave_status_work(struct work_struct *work) container_of(work, struct sdw_cdns, work); u32 slave0, slave1; u64 slave_intstat; + u32 device0_status; + int retry_count = 0; slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0); slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1); @@ -968,10 +969,45 @@ static void cdns_update_slave_status_work(struct work_struct *work) dev_dbg_ratelimited(cdns->dev, "Slave status change: 0x%llx\n", slave_intstat); +update_status: cdns_update_slave_status(cdns, slave_intstat); cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0); cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1); + /* + * When there is more than one peripheral per link, it's + * possible that a deviceB becomes attached after we deal with + * the attachment of deviceA. Since the hardware does a + * logical AND, the attachment of the second device does not + * change the status seen by the driver. + * + * In that case, clearing the registers above would result in + * the deviceB never being detected - until a change of status + * is observed on the bus. + * + * To avoid this race condition, re-check if any device0 needs + * attention with PING commands. There is no need to check for + * ALERTS since they are not allowed until a non-zero + * device_number is assigned. + */ + + device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT); + device0_status &= 3; + + if (device0_status == SDW_SLAVE_ATTACHED) { + if (retry_count++ < SDW_MAX_DEVICES) { + dev_dbg_ratelimited(cdns->dev, + "Device0 detected after clearing status, iteration %d\n", + retry_count); + slave_intstat = CDNS_MCP_SLAVE_INTSTAT_ATTACHED; + goto update_status; + } else { + dev_err_ratelimited(cdns->dev, + "Device0 detected after %d iterations\n", + retry_count); + } + } + /* clear and unmask Slave interrupt now */ cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK); cdns_updatel(cdns, CDNS_MCP_INTMASK, |