Skip to content

Commit 8fd456e

Browse files
Saravana Kannangregkh
authored andcommitted
driver core: Add state_synced sysfs file for devices that support it
This can be used to check if a device supports sync_state() callbacks and therefore keeps resources left on by the bootloader enabled till all its consumers have probed. This can also be used to check if sync_state() has been called for a device or whether it is still trying to keep resources enabled because they were left enabled by the bootloader and all its consumers haven't probed yet. Signed-off-by: Saravana Kannan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 287905e commit 8fd456e

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
What: /sys/devices/.../state_synced
2+
Date: May 2020
3+
Contact: Saravana Kannan <[email protected]>
4+
Description:
5+
The /sys/devices/.../state_synced attribute is only present for
6+
devices whose bus types or driver provides the .sync_state()
7+
callback. The number read from it (0 or 1) reflects the value
8+
of the device's 'state_synced' field. A value of 0 means the
9+
.sync_state() callback hasn't been called yet. A value of 1
10+
means the .sync_state() callback has been called.
11+
12+
Generally, if a device has sync_state() support and has some of
13+
the resources it provides enabled at the time the kernel starts
14+
(Eg: enabled by hardware reset or bootloader or anything that
15+
run before the kernel starts), then it'll keep those resources
16+
enabled and in a state that's compatible with the state they
17+
were in at the start of the kernel. The device will stop doing
18+
this only when the sync_state() callback has been called --
19+
which happens only when all its consumer devices are registered
20+
and have probed successfully. Resources that were left disabled
21+
at the time the kernel starts are not affected or limited in
22+
any way by sync_state() callbacks.
23+
24+

drivers/base/dd.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,18 @@ static void driver_deferred_probe_add_trigger(struct device *dev,
462462
driver_deferred_probe_trigger();
463463
}
464464

465+
static ssize_t state_synced_show(struct device *dev,
466+
struct device_attribute *attr, char *buf)
467+
{
468+
bool val;
469+
470+
device_lock(dev);
471+
val = dev->state_synced;
472+
device_unlock(dev);
473+
return sprintf(buf, "%u\n", val);
474+
}
475+
static DEVICE_ATTR_RO(state_synced);
476+
465477
static int really_probe(struct device *dev, struct device_driver *drv)
466478
{
467479
int ret = -EPROBE_DEFER;
@@ -535,9 +547,16 @@ static int really_probe(struct device *dev, struct device_driver *drv)
535547
goto dev_groups_failed;
536548
}
537549

550+
if (dev_has_sync_state(dev) &&
551+
device_create_file(dev, &dev_attr_state_synced)) {
552+
dev_err(dev, "state_synced sysfs add failed\n");
553+
goto dev_sysfs_state_synced_failed;
554+
}
555+
538556
if (test_remove) {
539557
test_remove = false;
540558

559+
device_remove_file(dev, &dev_attr_state_synced);
541560
device_remove_groups(dev, drv->dev_groups);
542561

543562
if (dev->bus->remove)
@@ -567,6 +586,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
567586
drv->bus->name, __func__, dev_name(dev), drv->name);
568587
goto done;
569588

589+
dev_sysfs_state_synced_failed:
590+
device_remove_groups(dev, drv->dev_groups);
570591
dev_groups_failed:
571592
if (dev->bus->remove)
572593
dev->bus->remove(dev);
@@ -1104,6 +1125,7 @@ static void __device_release_driver(struct device *dev, struct device *parent)
11041125

11051126
pm_runtime_put_sync(dev);
11061127

1128+
device_remove_file(dev, &dev_attr_state_synced);
11071129
device_remove_groups(dev, drv->dev_groups);
11081130

11091131
if (dev->bus && dev->bus->remove)

0 commit comments

Comments
 (0)