diff options
-rw-r--r-- | drivers/soundwire/bus.c | 2 | ||||
-rw-r--r-- | drivers/soundwire/bus_type.c | 10 | ||||
-rw-r--r-- | drivers/soundwire/irq.c | 6 | ||||
-rw-r--r-- | 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 6cfec4a2af33..377ab21c9cf0 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; |