diff options
Diffstat (limited to 'include/linux/device.h')
| -rw-r--r-- | include/linux/device.h | 43 | 
1 files changed, 38 insertions, 5 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 297239a08bb7..96ff76731e93 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -80,6 +80,13 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);   *		that generate uevents to add the environment variables.   * @probe:	Called when a new device or driver add to this bus, and callback   *		the specific driver's probe to initial the matched device. + * @sync_state:	Called to sync device state to software state after all the + *		state tracking consumers linked to this device (present at + *		the time of late_initcall) have successfully bound to a + *		driver. If the device has no consumers, this function will + *		be called at late_initcall_sync level. If the device has + *		consumers that are never bound to a driver, this function + *		will never get called until they do.   * @remove:	Called when a device removed from this bus.   * @shutdown:	Called at shut-down time to quiesce the device.   * @@ -123,6 +130,7 @@ struct bus_type {  	int (*match)(struct device *dev, struct device_driver *drv);  	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  	int (*probe)(struct device *dev); +	void (*sync_state)(struct device *dev);  	int (*remove)(struct device *dev);  	void (*shutdown)(struct device *dev); @@ -340,6 +348,13 @@ enum probe_type {   * @probe:	Called to query the existence of a specific device,   *		whether this driver can work with it, and bind the driver   *		to a specific device. + * @sync_state:	Called to sync device state to software state after all the + *		state tracking consumers linked to this device (present at + *		the time of late_initcall) have successfully bound to a + *		driver. If the device has no consumers, this function will + *		be called at late_initcall_sync level. If the device has + *		consumers that are never bound to a driver, this function + *		will never get called until they do.   * @remove:	Called when the device is removed from the system to   *		unbind a device from this driver.   * @shutdown:	Called at shut-down time to quiesce the device. @@ -379,6 +394,7 @@ struct device_driver {  	const struct acpi_device_id	*acpi_match_table;  	int (*probe) (struct device *dev); +	void (*sync_state)(struct device *dev);  	int (*remove) (struct device *dev);  	void (*shutdown) (struct device *dev);  	int (*suspend) (struct device *dev, pm_message_t state); @@ -946,6 +962,8 @@ extern void devm_free_pages(struct device *dev, unsigned long addr);  void __iomem *devm_ioremap_resource(struct device *dev,  				    const struct resource *res); +void __iomem *devm_ioremap_resource_wc(struct device *dev, +				       const struct resource *res);  void __iomem *devm_of_iomap(struct device *dev,  			    struct device_node *node, int index, @@ -1080,6 +1098,7 @@ enum device_link_state {   * AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind.   * AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds.   * MANAGED: The core tracks presence of supplier/consumer drivers (internal). + * SYNC_STATE_ONLY: Link only affects sync_state() behavior.   */  #define DL_FLAG_STATELESS		BIT(0)  #define DL_FLAG_AUTOREMOVE_CONSUMER	BIT(1) @@ -1088,6 +1107,7 @@ enum device_link_state {  #define DL_FLAG_AUTOREMOVE_SUPPLIER	BIT(4)  #define DL_FLAG_AUTOPROBE_CONSUMER	BIT(5)  #define DL_FLAG_MANAGED			BIT(6) +#define DL_FLAG_SYNC_STATE_ONLY		BIT(7)  /**   * struct device_link - Device link representation. @@ -1135,11 +1155,18 @@ enum dl_dev_state {   * struct dev_links_info - Device data related to device links.   * @suppliers: List of links to supplier devices.   * @consumers: List of links to consumer devices. + * @needs_suppliers: Hook to global list of devices waiting for suppliers. + * @defer_sync: Hook to global list of devices that have deferred sync_state. + * @need_for_probe: If needs_suppliers is on a list, this indicates if the + *		    suppliers are needed for probe or not.   * @status: Driver status information.   */  struct dev_links_info {  	struct list_head suppliers;  	struct list_head consumers; +	struct list_head needs_suppliers; +	struct list_head defer_sync; +	bool need_for_probe;  	enum dl_dev_state status;  }; @@ -1186,8 +1213,8 @@ struct dev_links_info {   * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all   * 		hardware supports 64-bit addresses for consistent allocations   * 		such descriptors. - * @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA - *		limit than the device itself supports. + * @bus_dma_limit: Limit of an upstream bridge or bus which imposes a smaller + *		DMA limit than the device itself supports.   * @dma_pfn_offset: offset of DMA memory range relatively of RAM   * @dma_parms:	A low level driver may set these to teach IOMMU code about   * 		segment limitations. @@ -1215,6 +1242,9 @@ struct dev_links_info {   * @offline:	Set after successful invocation of bus type's .offline().   * @of_node_reused: Set if the device-tree node is shared with an ancestor   *              device. + * @state_synced: The hardware state of this device has been synced to match + *		  the software state of this device by calling the driver/bus + *		  sync_state() callback.   * @dma_coherent: this particular device is dma coherent, even if the   *		architecture supports non-coherent devices.   * @@ -1270,7 +1300,7 @@ struct device {  					     not all hardware supports  					     64 bit addresses for consistent  					     allocations such descriptors. */ -	u64		bus_dma_mask;	/* upstream dma_mask constraint */ +	u64		bus_dma_limit;	/* upstream dma constraint */  	unsigned long	dma_pfn_offset;  	struct device_dma_parameters *dma_parms; @@ -1311,6 +1341,7 @@ struct device {  	bool			offline_disabled:1;  	bool			offline:1;  	bool			of_node_reused:1; +	bool			state_synced:1;  #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \      defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \      defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) @@ -1635,11 +1666,11 @@ extern bool kill_device(struct device *dev);  #ifdef CONFIG_DEVTMPFS  extern int devtmpfs_create_node(struct device *dev);  extern int devtmpfs_delete_node(struct device *dev); -extern int devtmpfs_mount(const char *mntdir); +extern int devtmpfs_mount(void);  #else  static inline int devtmpfs_create_node(struct device *dev) { return 0; }  static inline int devtmpfs_delete_node(struct device *dev) { return 0; } -static inline int devtmpfs_mount(const char *mountpoint) { return 0; } +static inline int devtmpfs_mount(void) { return 0; }  #endif  /* drivers/base/power/shutdown.c */ @@ -1653,6 +1684,8 @@ struct device_link *device_link_add(struct device *consumer,  				    struct device *supplier, u32 flags);  void device_link_del(struct device_link *link);  void device_link_remove(void *consumer, struct device *supplier); +void device_links_supplier_sync_state_pause(void); +void device_links_supplier_sync_state_resume(void);  #ifndef dev_fmt  #define dev_fmt(fmt) fmt  |