* [PATCH v2 1/2] soundwire: bus: Simplify sdw_assign_device_num()
2025-04-29 10:18 [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Charles Keepax
@ 2025-04-29 10:18 ` Charles Keepax
2025-04-29 10:18 ` [PATCH v2 2/2] soundwire: bus: Add internal slave ID and use for IRQs Charles Keepax
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Charles Keepax @ 2025-04-29 10:18 UTC (permalink / raw)
To: vkoul
Cc: yung-chuan.liao, pierre-louis.bossart, linux-sound, linux-kernel,
patches
Simplify the code in sdw_assign_device_num(). Remove the new_device
flag which can be simply handled inline and do a bit less shuffling of
dev_num in and out of various variables. This patch should cause no
functional changes.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
No changes since v1.
drivers/soundwire/bus.c | 29 ++++++++++++-----------------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 39aecd34c641..3f1d8ff55022 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -751,41 +751,36 @@ static int sdw_get_device_num(struct sdw_slave *slave)
static int sdw_assign_device_num(struct sdw_slave *slave)
{
struct sdw_bus *bus = slave->bus;
- int ret, dev_num;
- bool new_device = false;
+ struct device *dev = bus->dev;
+ int ret;
/* check first if device number is assigned, if so reuse that */
if (!slave->dev_num) {
if (!slave->dev_num_sticky) {
+ int dev_num;
+
mutex_lock(&slave->bus->bus_lock);
dev_num = sdw_get_device_num(slave);
mutex_unlock(&slave->bus->bus_lock);
if (dev_num < 0) {
- dev_err(bus->dev, "Get dev_num failed: %d\n",
- dev_num);
+ dev_err(dev, "Get dev_num failed: %d\n", dev_num);
return dev_num;
}
- slave->dev_num = dev_num;
+
slave->dev_num_sticky = dev_num;
- new_device = true;
} else {
- slave->dev_num = slave->dev_num_sticky;
+ dev_dbg(dev, "Slave already registered, reusing dev_num: %d\n",
+ slave->dev_num_sticky);
}
}
- if (!new_device)
- dev_dbg(bus->dev,
- "Slave already registered, reusing dev_num:%d\n",
- slave->dev_num);
-
/* Clear the slave->dev_num to transfer message on device 0 */
- dev_num = slave->dev_num;
slave->dev_num = 0;
- ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, dev_num);
+ ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, slave->dev_num_sticky);
if (ret < 0) {
- dev_err(bus->dev, "Program device_num %d failed: %d\n",
- dev_num, ret);
+ dev_err(dev, "Program device_num %d failed: %d\n",
+ slave->dev_num_sticky, ret);
return ret;
}
@@ -793,7 +788,7 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
slave->dev_num = slave->dev_num_sticky;
if (bus->ops && bus->ops->new_peripheral_assigned)
- bus->ops->new_peripheral_assigned(bus, slave, dev_num);
+ bus->ops->new_peripheral_assigned(bus, slave, slave->dev_num);
return 0;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/2] soundwire: bus: Add internal slave ID and use for IRQs
2025-04-29 10:18 [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Charles Keepax
2025-04-29 10:18 ` [PATCH v2 1/2] soundwire: bus: Simplify sdw_assign_device_num() Charles Keepax
@ 2025-04-29 10:18 ` Charles Keepax
2025-05-05 10:03 ` [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Pierre-Louis Bossart
2025-05-14 11:45 ` Vinod Koul
3 siblings, 0 replies; 5+ messages in thread
From: Charles Keepax @ 2025-04-29 10:18 UTC (permalink / raw)
To: vkoul
Cc: yung-chuan.liao, pierre-louis.bossart, linux-sound, linux-kernel,
patches
Currently the SoundWire IRQ code uses the dev_num to create an IRQ
mapping for each slave. However, there is an issue there, the dev_num
is only allocated when the slave enumerates on the bus and enumeration
may happen before or after probe of the slave driver. In the case
enumeration happens after probe of the slave driver then the IRQ
mapping will use dev_num before it is set. This could cause multiple
slaves to use zero as their IRQ mapping.
It is very desirable to have the IRQ mapped before the slave probe
is called, so drivers can do resource allocation in probe as normal. To
solve these issues add an internal ID created for each slave when it is
probed and use that for mapping the IRQ.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
Changes since v1:
- Don't reuse the new IDA for the dev_num
- Expand the number of devices allowed on a bus to 16
drivers/soundwire/bus.c | 2 ++
drivers/soundwire/bus_type.c | 10 ++++++++++
drivers/soundwire/irq.c | 6 +++---
include/linux/soundwire/sdw.h | 6 ++++++
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 3f1d8ff55022..68db4b67a86f 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -56,6 +56,8 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
return ret;
}
+ ida_init(&bus->slave_ida);
+
ret = sdw_master_device_add(bus, parent, fwnode);
if (ret < 0) {
dev_err(parent, "Failed to add master device at link %d\n",
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
index e98d5db81b1c..75d6f16efced 100644
--- a/drivers/soundwire/bus_type.c
+++ b/drivers/soundwire/bus_type.c
@@ -105,9 +105,17 @@ static int sdw_drv_probe(struct device *dev)
if (ret)
return ret;
+ ret = ida_alloc_max(&slave->bus->slave_ida, SDW_FW_MAX_DEVICES, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(dev, "Failed to allocated ID: %d\n", ret);
+ return ret;
+ }
+ slave->index = ret;
+
ret = drv->probe(slave, id);
if (ret) {
dev_pm_domain_detach(dev, false);
+ ida_free(&slave->bus->slave_ida, slave->index);
return ret;
}
@@ -174,6 +182,8 @@ static int sdw_drv_remove(struct device *dev)
dev_pm_domain_detach(dev, false);
+ ida_free(&slave->bus->slave_ida, slave->index);
+
return ret;
}
diff --git a/drivers/soundwire/irq.c b/drivers/soundwire/irq.c
index c237e6d0766b..f18be37efef8 100644
--- a/drivers/soundwire/irq.c
+++ b/drivers/soundwire/irq.c
@@ -31,7 +31,7 @@ int sdw_irq_create(struct sdw_bus *bus,
{
bus->irq_chip.name = dev_name(bus->dev);
- bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES,
+ bus->domain = irq_domain_create_linear(fwnode, SDW_FW_MAX_DEVICES,
&sdw_domain_ops, bus);
if (!bus->domain) {
dev_err(bus->dev, "Failed to add IRQ domain\n");
@@ -50,12 +50,12 @@ static void sdw_irq_dispose_mapping(void *data)
{
struct sdw_slave *slave = data;
- irq_dispose_mapping(irq_find_mapping(slave->bus->domain, slave->dev_num));
+ irq_dispose_mapping(slave->irq);
}
void sdw_irq_create_mapping(struct sdw_slave *slave)
{
- slave->irq = irq_create_mapping(slave->bus->domain, slave->dev_num);
+ slave->irq = irq_create_mapping(slave->bus->domain, slave->index);
if (!slave->irq)
dev_warn(&slave->dev, "Failed to map IRQ\n");
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 2362f621d94c..0832776262ac 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -8,6 +8,7 @@
#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/device.h>
+#include <linux/idr.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/lockdep_types.h>
@@ -50,6 +51,7 @@ struct sdw_slave;
#define SDW_FRAME_CTRL_BITS 48
#define SDW_MAX_DEVICES 11
+#define SDW_FW_MAX_DEVICES 16
#define SDW_MAX_PORTS 15
#define SDW_VALID_PORT_RANGE(n) ((n) < SDW_MAX_PORTS && (n) >= 1)
@@ -630,6 +632,7 @@ struct sdw_slave_ops {
* struct sdw_slave - SoundWire Slave
* @id: MIPI device ID
* @dev: Linux device
+ * @index: internal ID for this slave
* @irq: IRQ number
* @status: Status reported by the Slave
* @bus: Bus handle
@@ -661,6 +664,7 @@ struct sdw_slave_ops {
struct sdw_slave {
struct sdw_slave_id id;
struct device dev;
+ int index;
int irq;
enum sdw_slave_status status;
struct sdw_bus *bus;
@@ -968,6 +972,7 @@ struct sdw_stream_runtime {
* @md: Master device
* @bus_lock_key: bus lock key associated to @bus_lock
* @bus_lock: bus lock
+ * @slave_ida: IDA for allocating internal slave IDs
* @slaves: list of Slaves on this bus
* @msg_lock_key: message lock key associated to @msg_lock
* @msg_lock: message lock
@@ -1010,6 +1015,7 @@ struct sdw_bus {
struct sdw_master_device *md;
struct lock_class_key bus_lock_key;
struct mutex bus_lock;
+ struct ida slave_ida;
struct list_head slaves;
struct lock_class_key msg_lock_key;
struct mutex msg_lock;
--
2.39.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping
2025-04-29 10:18 [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Charles Keepax
2025-04-29 10:18 ` [PATCH v2 1/2] soundwire: bus: Simplify sdw_assign_device_num() Charles Keepax
2025-04-29 10:18 ` [PATCH v2 2/2] soundwire: bus: Add internal slave ID and use for IRQs Charles Keepax
@ 2025-05-05 10:03 ` Pierre-Louis Bossart
2025-05-14 11:45 ` Vinod Koul
3 siblings, 0 replies; 5+ messages in thread
From: Pierre-Louis Bossart @ 2025-05-05 10:03 UTC (permalink / raw)
To: Charles Keepax, vkoul; +Cc: yung-chuan.liao, linux-sound, linux-kernel, patches
On 4/29/25 05:18, Charles Keepax wrote:
> Currently there would be problems if multiple devices on the same bus
> attempted to use SoundWire IRQ handling rather than the IRQ callback
> mechanism. So far only cs42l43 uses this system so this hasn't caused
> any problems.
>
> Thanks,
> Charles
>
> Changes since v1:
> - Don't reuse the new IDA for the dev_num
> - Expand the number of devices allowed on a bus to 16
>
> Charles Keepax (2):
> soundwire: bus: Simplify sdw_assign_device_num()
> soundwire: bus: Add internal slave ID and use for IRQs
LGTM,
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
>
> drivers/soundwire/bus.c | 31 ++++++++++++++-----------------
> drivers/soundwire/bus_type.c | 10 ++++++++++
> drivers/soundwire/irq.c | 6 +++---
> include/linux/soundwire/sdw.h | 6 ++++++
> 4 files changed, 33 insertions(+), 20 deletions(-)
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping
2025-04-29 10:18 [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Charles Keepax
` (2 preceding siblings ...)
2025-05-05 10:03 ` [PATCH v2 0/2] Fix minor issue in SoundWire slave IRQ mapping Pierre-Louis Bossart
@ 2025-05-14 11:45 ` Vinod Koul
3 siblings, 0 replies; 5+ messages in thread
From: Vinod Koul @ 2025-05-14 11:45 UTC (permalink / raw)
To: Charles Keepax
Cc: yung-chuan.liao, pierre-louis.bossart, linux-sound, linux-kernel,
patches
On Tue, 29 Apr 2025 11:18:06 +0100, Charles Keepax wrote:
> Currently there would be problems if multiple devices on the same bus
> attempted to use SoundWire IRQ handling rather than the IRQ callback
> mechanism. So far only cs42l43 uses this system so this hasn't caused
> any problems.
>
> Thanks,
> Charles
>
> [...]
Applied, thanks!
[1/2] soundwire: bus: Simplify sdw_assign_device_num()
commit: 5b1a2927c4f63878d2c108cebad09358e69caa20
[2/2] soundwire: bus: Add internal slave ID and use for IRQs
commit: aab12022b076f0b385b7a9a78e1161bd2df5d1e3
Best regards,
--
~Vinod
^ permalink raw reply [flat|nested] 5+ messages in thread