mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
soundwire: bus: add callbacks for device_number allocation
Rather than add logic in the core for vendor-specific usages, add callbacks for vendor-specific device_number allocation and release. This patch only moves the existing IDA-based allocator used only by Intel to the intel_auxdevice.c file and does not change the functionality. Follow-up patches will extend the behavior by modifying the Intel callbacks. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20230731091333.3593132-3-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
23afc82fb2
commit
39d80b0e5f
3 changed files with 27 additions and 14 deletions
|
@ -12,7 +12,6 @@
|
|||
#include "sysfs_local.h"
|
||||
|
||||
static DEFINE_IDA(sdw_bus_ida);
|
||||
static DEFINE_IDA(sdw_peripheral_ida);
|
||||
|
||||
static int sdw_get_id(struct sdw_bus *bus)
|
||||
{
|
||||
|
@ -168,8 +167,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
|
|||
|
||||
if (slave->dev_num) { /* clear dev_num if assigned */
|
||||
clear_bit(slave->dev_num, bus->assigned);
|
||||
if (bus->dev_num_ida_min)
|
||||
ida_free(&sdw_peripheral_ida, slave->dev_num);
|
||||
if (bus->ops && bus->ops->put_device_num)
|
||||
bus->ops->put_device_num(bus, slave);
|
||||
}
|
||||
list_del_init(&slave->node);
|
||||
mutex_unlock(&bus->bus_lock);
|
||||
|
@ -710,16 +709,15 @@ EXPORT_SYMBOL(sdw_compare_devid);
|
|||
/* called with bus_lock held */
|
||||
static int sdw_get_device_num(struct sdw_slave *slave)
|
||||
{
|
||||
struct sdw_bus *bus = slave->bus;
|
||||
int bit;
|
||||
|
||||
if (slave->bus->dev_num_ida_min) {
|
||||
bit = ida_alloc_range(&sdw_peripheral_ida,
|
||||
slave->bus->dev_num_ida_min, SDW_MAX_DEVICES,
|
||||
GFP_KERNEL);
|
||||
if (bus->ops && bus->ops->get_device_num) {
|
||||
bit = bus->ops->get_device_num(bus, slave);
|
||||
if (bit < 0)
|
||||
goto err;
|
||||
} else {
|
||||
bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
|
||||
bit = find_first_zero_bit(bus->assigned, SDW_MAX_DEVICES);
|
||||
if (bit == SDW_MAX_DEVICES) {
|
||||
bit = -ENODEV;
|
||||
goto err;
|
||||
|
@ -730,7 +728,7 @@ static int sdw_get_device_num(struct sdw_slave *slave)
|
|||
* Do not update dev_num in Slave data structure here,
|
||||
* Update once program dev_num is successful
|
||||
*/
|
||||
set_bit(bit, slave->bus->assigned);
|
||||
set_bit(bit, bus->assigned);
|
||||
|
||||
err:
|
||||
return bit;
|
||||
|
|
|
@ -125,6 +125,20 @@ static int intel_prop_read(struct sdw_bus *bus)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_IDA(intel_peripheral_ida);
|
||||
|
||||
static int intel_get_device_num_ida(struct sdw_bus *bus, struct sdw_slave *slave)
|
||||
{
|
||||
return ida_alloc_range(&intel_peripheral_ida,
|
||||
INTEL_DEV_NUM_IDA_MIN, SDW_MAX_DEVICES,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void intel_put_device_num_ida(struct sdw_bus *bus, struct sdw_slave *slave)
|
||||
{
|
||||
return ida_free(&intel_peripheral_ida, slave->dev_num);
|
||||
}
|
||||
|
||||
static struct sdw_master_ops sdw_intel_ops = {
|
||||
.read_prop = intel_prop_read,
|
||||
.override_adr = sdw_dmi_override_adr,
|
||||
|
@ -134,6 +148,8 @@ static struct sdw_master_ops sdw_intel_ops = {
|
|||
.pre_bank_switch = generic_pre_bank_switch,
|
||||
.post_bank_switch = generic_post_bank_switch,
|
||||
.read_ping_status = cdns_read_ping_status,
|
||||
.get_device_num = intel_get_device_num_ida,
|
||||
.put_device_num = intel_put_device_num_ida,
|
||||
.new_peripheral_assigned = generic_new_peripheral_assigned,
|
||||
};
|
||||
|
||||
|
@ -167,7 +183,6 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
|
|||
cdns->msg_count = 0;
|
||||
|
||||
bus->link_id = auxdev->id;
|
||||
bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN;
|
||||
bus->clk_stop_timeout = 1;
|
||||
|
||||
sdw_cdns_probe(cdns);
|
||||
|
|
|
@ -847,6 +847,8 @@ struct sdw_defer {
|
|||
* @post_bank_switch: Callback for post bank switch
|
||||
* @read_ping_status: Read status from PING frames, reported with two bits per Device.
|
||||
* Bits 31:24 are reserved.
|
||||
* @get_device_num: Callback for vendor-specific device_number allocation
|
||||
* @put_device_num: Callback for vendor-specific device_number release
|
||||
* @new_peripheral_assigned: Callback to handle enumeration of new peripheral.
|
||||
*/
|
||||
struct sdw_master_ops {
|
||||
|
@ -862,6 +864,8 @@ struct sdw_master_ops {
|
|||
int (*pre_bank_switch)(struct sdw_bus *bus);
|
||||
int (*post_bank_switch)(struct sdw_bus *bus);
|
||||
u32 (*read_ping_status)(struct sdw_bus *bus);
|
||||
int (*get_device_num)(struct sdw_bus *bus, struct sdw_slave *slave);
|
||||
void (*put_device_num)(struct sdw_bus *bus, struct sdw_slave *slave);
|
||||
void (*new_peripheral_assigned)(struct sdw_bus *bus,
|
||||
struct sdw_slave *slave,
|
||||
int dev_num);
|
||||
|
@ -898,9 +902,6 @@ struct sdw_master_ops {
|
|||
* meaningful if multi_link is set. If set to 1, hardware-based
|
||||
* synchronization will be used even if a stream only uses a single
|
||||
* SoundWire segment.
|
||||
* @dev_num_ida_min: if set, defines the minimum values for the IDA
|
||||
* used to allocate system-unique device numbers. This value needs to be
|
||||
* identical across all SoundWire bus in the system.
|
||||
*/
|
||||
struct sdw_bus {
|
||||
struct device *dev;
|
||||
|
@ -927,7 +928,6 @@ struct sdw_bus {
|
|||
u32 bank_switch_timeout;
|
||||
bool multi_link;
|
||||
int hw_sync_min_links;
|
||||
int dev_num_ida_min;
|
||||
};
|
||||
|
||||
int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
|
||||
|
|
Loading…
Reference in a new issue