aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/device.h
diff options
context:
space:
mode:
authorSaravana Kannan <saravanak@google.com>2019-07-31 18:17:17 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-01 10:04:14 -0400
commit8f8184d6bf676a8680d6f441e40317d166b46f73 (patch)
tree983cae1baf316a8ad0d7cb81d0784bc37f53a7cd /include/linux/device.h
parent690ff7881b2681afca1c3c063f4a5cb7c71d9d8b (diff)
driver core: Add sync_state driver/bus callback
This sync_state driver/bus callback is called once all the consumers of a supplier have probed successfully. This allows the supplier device's driver/bus to sync the supplier device's state to the software state with the guarantee that all the consumers are actively managing the resources provided by the supplier device. To maintain backwards compatibility and ease transition from existing frameworks and resource cleanup schemes, late_initcall_sync is the earliest when the sync_state callback might be called. There is no upper bound on the time by which the sync_state callback has to be called. This is because if a consumer device never probes, the supplier has to maintain its resources in the state left by the bootloader. For example, if the bootloader leaves the display backlight at a fixed voltage and the backlight driver is never probed, you don't want the backlight to ever be turned off after boot up. Also, when multiple devices are added after kernel init, some suppliers could be added before their consumer devices get added. In these instances, the supplier devices could get their sync_state callback called right after they probe because the consumers devices haven't had a chance to create device links to the suppliers. To handle this correctly, this change also provides APIs to pause/resume sync state callbacks so that when multiple devices are added, their sync_state callback evaluation can be postponed to happen after all of them are added. kbuild test robot reported missing documentation for device.state_synced Reported-by: kbuild test robot <lkp@intel.com> Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20190731221721.187713-5-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/device.h')
-rw-r--r--include/linux/device.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index d3991810f39d..63a3aafabcd6 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -84,6 +84,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
84 * available at the time this function is called. As in, the 84 * available at the time this function is called. As in, the
85 * function should NOT stop at the first failed device link if 85 * function should NOT stop at the first failed device link if
86 * other unlinked supplier devices are present in the system. 86 * other unlinked supplier devices are present in the system.
87 * This is necessary for the sync_state() callback to work
88 * correctly.
87 * 89 *
88 * Return 0 if device links have been successfully created to all 90 * Return 0 if device links have been successfully created to all
89 * the suppliers of this device. Return an error if some of the 91 * the suppliers of this device. Return an error if some of the
@@ -91,6 +93,13 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
91 * reattempted in the future. 93 * reattempted in the future.
92 * @probe: Called when a new device or driver add to this bus, and callback 94 * @probe: Called when a new device or driver add to this bus, and callback
93 * the specific driver's probe to initial the matched device. 95 * the specific driver's probe to initial the matched device.
96 * @sync_state: Called to sync device state to software state after all the
97 * state tracking consumers linked to this device (present at
98 * the time of late_initcall) have successfully bound to a
99 * driver. If the device has no consumers, this function will
100 * be called at late_initcall_sync level. If the device has
101 * consumers that are never bound to a driver, this function
102 * will never get called until they do.
94 * @remove: Called when a device removed from this bus. 103 * @remove: Called when a device removed from this bus.
95 * @shutdown: Called at shut-down time to quiesce the device. 104 * @shutdown: Called at shut-down time to quiesce the device.
96 * 105 *
@@ -135,6 +144,7 @@ struct bus_type {
135 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 144 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
136 int (*add_links)(struct device *dev); 145 int (*add_links)(struct device *dev);
137 int (*probe)(struct device *dev); 146 int (*probe)(struct device *dev);
147 void (*sync_state)(struct device *dev);
138 int (*remove)(struct device *dev); 148 int (*remove)(struct device *dev);
139 void (*shutdown)(struct device *dev); 149 void (*shutdown)(struct device *dev);
140 150
@@ -366,6 +376,13 @@ enum probe_type {
366 * @probe: Called to query the existence of a specific device, 376 * @probe: Called to query the existence of a specific device,
367 * whether this driver can work with it, and bind the driver 377 * whether this driver can work with it, and bind the driver
368 * to a specific device. 378 * to a specific device.
379 * @sync_state: Called to sync device state to software state after all the
380 * state tracking consumers linked to this device (present at
381 * the time of late_initcall) have successfully bound to a
382 * driver. If the device has no consumers, this function will
383 * be called at late_initcall_sync level. If the device has
384 * consumers that are never bound to a driver, this function
385 * will never get called until they do.
369 * @remove: Called when the device is removed from the system to 386 * @remove: Called when the device is removed from the system to
370 * unbind a device from this driver. 387 * unbind a device from this driver.
371 * @shutdown: Called at shut-down time to quiesce the device. 388 * @shutdown: Called at shut-down time to quiesce the device.
@@ -404,6 +421,7 @@ struct device_driver {
404 421
405 int (*edit_links)(struct device *dev); 422 int (*edit_links)(struct device *dev);
406 int (*probe) (struct device *dev); 423 int (*probe) (struct device *dev);
424 void (*sync_state)(struct device *dev);
407 int (*remove) (struct device *dev); 425 int (*remove) (struct device *dev);
408 void (*shutdown) (struct device *dev); 426 void (*shutdown) (struct device *dev);
409 int (*suspend) (struct device *dev, pm_message_t state); 427 int (*suspend) (struct device *dev, pm_message_t state);
@@ -1156,12 +1174,14 @@ enum dl_dev_state {
1156 * @suppliers: List of links to supplier devices. 1174 * @suppliers: List of links to supplier devices.
1157 * @consumers: List of links to consumer devices. 1175 * @consumers: List of links to consumer devices.
1158 * @needs_suppliers: Hook to global list of devices waiting for suppliers. 1176 * @needs_suppliers: Hook to global list of devices waiting for suppliers.
1177 * @defer_sync: Hook to global list of devices that have deferred sync_state.
1159 * @status: Driver status information. 1178 * @status: Driver status information.
1160 */ 1179 */
1161struct dev_links_info { 1180struct dev_links_info {
1162 struct list_head suppliers; 1181 struct list_head suppliers;
1163 struct list_head consumers; 1182 struct list_head consumers;
1164 struct list_head needs_suppliers; 1183 struct list_head needs_suppliers;
1184 struct list_head defer_sync;
1165 enum dl_dev_state status; 1185 enum dl_dev_state status;
1166}; 1186};
1167 1187
@@ -1237,6 +1257,9 @@ struct dev_links_info {
1237 * device. 1257 * device.
1238 * @has_edit_links: This device has a driver than is capable of 1258 * @has_edit_links: This device has a driver than is capable of
1239 * editing the device links created by driver core. 1259 * editing the device links created by driver core.
1260 * @state_synced: The hardware state of this device has been synced to match
1261 * the software state of this device by calling the driver/bus
1262 * sync_state() callback.
1240 * @dma_coherent: this particular device is dma coherent, even if the 1263 * @dma_coherent: this particular device is dma coherent, even if the
1241 * architecture supports non-coherent devices. 1264 * architecture supports non-coherent devices.
1242 * 1265 *
@@ -1331,6 +1354,7 @@ struct device {
1331 bool offline:1; 1354 bool offline:1;
1332 bool of_node_reused:1; 1355 bool of_node_reused:1;
1333 bool has_edit_links:1; 1356 bool has_edit_links:1;
1357 bool state_synced:1;
1334#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \ 1358#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
1335 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \ 1359 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
1336 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) 1360 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
@@ -1674,6 +1698,8 @@ struct device_link *device_link_add(struct device *consumer,
1674void device_link_del(struct device_link *link); 1698void device_link_del(struct device_link *link);
1675void device_link_remove(void *consumer, struct device *supplier); 1699void device_link_remove(void *consumer, struct device *supplier);
1676void device_link_remove_from_wfs(struct device *consumer); 1700void device_link_remove_from_wfs(struct device *consumer);
1701void device_links_supplier_sync_state_pause(void);
1702void device_links_supplier_sync_state_resume(void);
1677 1703
1678#ifndef dev_fmt 1704#ifndef dev_fmt
1679#define dev_fmt(fmt) fmt 1705#define dev_fmt(fmt) fmt