driver core: Make state_synced device attribute writeable
If the file is written to and sync_state() hasn't been called for the device yet, then call sync_state() for the device independent of the state of its consumers. This is useful for supplier devices that have one or more consumers that don't have a driver but the consumers are in a state that don't use the resources supplied by the supplier device. This gives finer grained control than using the fw_devlink.sync_state=timeout kernel commandline parameter. Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20230304005355.746421-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ffbe08a8e8
commit
f8fb576658
@ -21,4 +21,9 @@ Description:
|
||||
at the time the kernel starts are not affected or limited in
|
||||
any way by sync_state() callbacks.
|
||||
|
||||
Writing "1" to this file will force a call to the device's
|
||||
sync_state() function if it hasn't been called already. The
|
||||
sync_state() call happens independent of the state of the
|
||||
consumer devices.
|
||||
|
||||
|
||||
|
@ -164,6 +164,14 @@ static inline int driver_match_device(struct device_driver *drv,
|
||||
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
|
||||
}
|
||||
|
||||
static inline void dev_sync_state(struct device *dev)
|
||||
{
|
||||
if (dev->bus->sync_state)
|
||||
dev->bus->sync_state(dev);
|
||||
else if (dev->driver && dev->driver->sync_state)
|
||||
dev->driver->sync_state(dev);
|
||||
}
|
||||
|
||||
extern int driver_add_groups(struct device_driver *drv,
|
||||
const struct attribute_group **groups);
|
||||
extern void driver_remove_groups(struct device_driver *drv,
|
||||
|
@ -1160,10 +1160,7 @@ static void device_links_flush_sync_list(struct list_head *list,
|
||||
if (dev != dont_lock_dev)
|
||||
device_lock(dev);
|
||||
|
||||
if (dev->bus->sync_state)
|
||||
dev->bus->sync_state(dev);
|
||||
else if (dev->driver && dev->driver->sync_state)
|
||||
dev->driver->sync_state(dev);
|
||||
dev_sync_state(dev);
|
||||
|
||||
if (dev != dont_lock_dev)
|
||||
device_unlock(dev);
|
||||
|
@ -510,6 +510,27 @@ EXPORT_SYMBOL_GPL(device_bind_driver);
|
||||
static atomic_t probe_count = ATOMIC_INIT(0);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
|
||||
|
||||
static ssize_t state_synced_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (strcmp("1", buf))
|
||||
return -EINVAL;
|
||||
|
||||
device_lock(dev);
|
||||
if (!dev->state_synced) {
|
||||
dev->state_synced = true;
|
||||
dev_sync_state(dev);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
device_unlock(dev);
|
||||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
|
||||
static ssize_t state_synced_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -521,7 +542,7 @@ static ssize_t state_synced_show(struct device *dev,
|
||||
|
||||
return sysfs_emit(buf, "%u\n", val);
|
||||
}
|
||||
static DEVICE_ATTR_RO(state_synced);
|
||||
static DEVICE_ATTR_RW(state_synced);
|
||||
|
||||
static void device_unbind_cleanup(struct device *dev)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user