162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org> 462306a36Sopenharmony_ci * Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de> 562306a36Sopenharmony_ci * Copyright (c) 2008-2012 Novell Inc. 662306a36Sopenharmony_ci * Copyright (c) 2012-2019 Greg Kroah-Hartman <gregkh@linuxfoundation.org> 762306a36Sopenharmony_ci * Copyright (c) 2012-2019 Linux Foundation 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Core driver model functions and structures that should not be 1062306a36Sopenharmony_ci * shared outside of the drivers/base/ directory. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci#include <linux/notifier.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/** 1662306a36Sopenharmony_ci * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * @subsys - the struct kset that defines this subsystem 1962306a36Sopenharmony_ci * @devices_kset - the subsystem's 'devices' directory 2062306a36Sopenharmony_ci * @interfaces - list of subsystem interfaces associated 2162306a36Sopenharmony_ci * @mutex - protect the devices, and interfaces lists. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * @drivers_kset - the list of drivers associated 2462306a36Sopenharmony_ci * @klist_devices - the klist to iterate over the @devices_kset 2562306a36Sopenharmony_ci * @klist_drivers - the klist to iterate over the @drivers_kset 2662306a36Sopenharmony_ci * @bus_notifier - the bus notifier list for anything that cares about things 2762306a36Sopenharmony_ci * on this bus. 2862306a36Sopenharmony_ci * @bus - pointer back to the struct bus_type that this structure is associated 2962306a36Sopenharmony_ci * with. 3062306a36Sopenharmony_ci * @dev_root: Default device to use as the parent. 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * @glue_dirs - "glue" directory to put in-between the parent device to 3362306a36Sopenharmony_ci * avoid namespace conflicts 3462306a36Sopenharmony_ci * @class - pointer back to the struct class that this structure is associated 3562306a36Sopenharmony_ci * with. 3662306a36Sopenharmony_ci * @lock_key: Lock class key for use by the lock validator 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * This structure is the one that is the actual kobject allowing struct 3962306a36Sopenharmony_ci * bus_type/class to be statically allocated safely. Nothing outside of the 4062306a36Sopenharmony_ci * driver core should ever touch these fields. 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_cistruct subsys_private { 4362306a36Sopenharmony_ci struct kset subsys; 4462306a36Sopenharmony_ci struct kset *devices_kset; 4562306a36Sopenharmony_ci struct list_head interfaces; 4662306a36Sopenharmony_ci struct mutex mutex; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci struct kset *drivers_kset; 4962306a36Sopenharmony_ci struct klist klist_devices; 5062306a36Sopenharmony_ci struct klist klist_drivers; 5162306a36Sopenharmony_ci struct blocking_notifier_head bus_notifier; 5262306a36Sopenharmony_ci unsigned int drivers_autoprobe:1; 5362306a36Sopenharmony_ci const struct bus_type *bus; 5462306a36Sopenharmony_ci struct device *dev_root; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci struct kset glue_dirs; 5762306a36Sopenharmony_ci const struct class *class; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci struct lock_class_key lock_key; 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci#define to_subsys_private(obj) container_of_const(obj, struct subsys_private, subsys.kobj) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic inline struct subsys_private *subsys_get(struct subsys_private *sp) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci if (sp) 6662306a36Sopenharmony_ci kset_get(&sp->subsys); 6762306a36Sopenharmony_ci return sp; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic inline void subsys_put(struct subsys_private *sp) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci if (sp) 7362306a36Sopenharmony_ci kset_put(&sp->subsys); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistruct subsys_private *class_to_subsys(const struct class *class); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistruct driver_private { 7962306a36Sopenharmony_ci struct kobject kobj; 8062306a36Sopenharmony_ci struct klist klist_devices; 8162306a36Sopenharmony_ci struct klist_node knode_bus; 8262306a36Sopenharmony_ci struct module_kobject *mkobj; 8362306a36Sopenharmony_ci struct device_driver *driver; 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci#define to_driver(obj) container_of(obj, struct driver_private, kobj) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/** 8862306a36Sopenharmony_ci * struct device_private - structure to hold the private to the driver core portions of the device structure. 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * @klist_children - klist containing all children of this device 9162306a36Sopenharmony_ci * @knode_parent - node in sibling list 9262306a36Sopenharmony_ci * @knode_driver - node in driver list 9362306a36Sopenharmony_ci * @knode_bus - node in bus list 9462306a36Sopenharmony_ci * @knode_class - node in class list 9562306a36Sopenharmony_ci * @deferred_probe - entry in deferred_probe_list which is used to retry the 9662306a36Sopenharmony_ci * binding of drivers which were unable to get all the resources needed by 9762306a36Sopenharmony_ci * the device; typically because it depends on another driver getting 9862306a36Sopenharmony_ci * probed first. 9962306a36Sopenharmony_ci * @async_driver - pointer to device driver awaiting probe via async_probe 10062306a36Sopenharmony_ci * @device - pointer back to the struct device that this structure is 10162306a36Sopenharmony_ci * associated with. 10262306a36Sopenharmony_ci * @dead - This device is currently either in the process of or has been 10362306a36Sopenharmony_ci * removed from the system. Any asynchronous events scheduled for this 10462306a36Sopenharmony_ci * device should exit without taking any action. 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * Nothing outside of the driver core should ever touch these fields. 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_cistruct device_private { 10962306a36Sopenharmony_ci struct klist klist_children; 11062306a36Sopenharmony_ci struct klist_node knode_parent; 11162306a36Sopenharmony_ci struct klist_node knode_driver; 11262306a36Sopenharmony_ci struct klist_node knode_bus; 11362306a36Sopenharmony_ci struct klist_node knode_class; 11462306a36Sopenharmony_ci struct list_head deferred_probe; 11562306a36Sopenharmony_ci struct device_driver *async_driver; 11662306a36Sopenharmony_ci char *deferred_probe_reason; 11762306a36Sopenharmony_ci struct device *device; 11862306a36Sopenharmony_ci u8 dead:1; 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci#define to_device_private_parent(obj) \ 12162306a36Sopenharmony_ci container_of(obj, struct device_private, knode_parent) 12262306a36Sopenharmony_ci#define to_device_private_driver(obj) \ 12362306a36Sopenharmony_ci container_of(obj, struct device_private, knode_driver) 12462306a36Sopenharmony_ci#define to_device_private_bus(obj) \ 12562306a36Sopenharmony_ci container_of(obj, struct device_private, knode_bus) 12662306a36Sopenharmony_ci#define to_device_private_class(obj) \ 12762306a36Sopenharmony_ci container_of(obj, struct device_private, knode_class) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* initialisation functions */ 13062306a36Sopenharmony_ciint devices_init(void); 13162306a36Sopenharmony_ciint buses_init(void); 13262306a36Sopenharmony_ciint classes_init(void); 13362306a36Sopenharmony_ciint firmware_init(void); 13462306a36Sopenharmony_ci#ifdef CONFIG_SYS_HYPERVISOR 13562306a36Sopenharmony_ciint hypervisor_init(void); 13662306a36Sopenharmony_ci#else 13762306a36Sopenharmony_cistatic inline int hypervisor_init(void) { return 0; } 13862306a36Sopenharmony_ci#endif 13962306a36Sopenharmony_ciint platform_bus_init(void); 14062306a36Sopenharmony_civoid cpu_dev_init(void); 14162306a36Sopenharmony_civoid container_dev_init(void); 14262306a36Sopenharmony_ci#ifdef CONFIG_AUXILIARY_BUS 14362306a36Sopenharmony_civoid auxiliary_bus_init(void); 14462306a36Sopenharmony_ci#else 14562306a36Sopenharmony_cistatic inline void auxiliary_bus_init(void) { } 14662306a36Sopenharmony_ci#endif 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistruct kobject *virtual_device_parent(struct device *dev); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciint bus_add_device(struct device *dev); 15162306a36Sopenharmony_civoid bus_probe_device(struct device *dev); 15262306a36Sopenharmony_civoid bus_remove_device(struct device *dev); 15362306a36Sopenharmony_civoid bus_notify(struct device *dev, enum bus_notifier_event value); 15462306a36Sopenharmony_cibool bus_is_registered(const struct bus_type *bus); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ciint bus_add_driver(struct device_driver *drv); 15762306a36Sopenharmony_civoid bus_remove_driver(struct device_driver *drv); 15862306a36Sopenharmony_civoid device_release_driver_internal(struct device *dev, struct device_driver *drv, 15962306a36Sopenharmony_ci struct device *parent); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_civoid driver_detach(struct device_driver *drv); 16262306a36Sopenharmony_civoid driver_deferred_probe_del(struct device *dev); 16362306a36Sopenharmony_civoid device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); 16462306a36Sopenharmony_cistatic inline int driver_match_device(struct device_driver *drv, 16562306a36Sopenharmony_ci struct device *dev) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci return drv->bus->match ? drv->bus->match(dev, drv) : 1; 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic inline void dev_sync_state(struct device *dev) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci if (dev->bus->sync_state) 17362306a36Sopenharmony_ci dev->bus->sync_state(dev); 17462306a36Sopenharmony_ci else if (dev->driver && dev->driver->sync_state) 17562306a36Sopenharmony_ci dev->driver->sync_state(dev); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ciint driver_add_groups(struct device_driver *drv, const struct attribute_group **groups); 17962306a36Sopenharmony_civoid driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups); 18062306a36Sopenharmony_civoid device_driver_detach(struct device *dev); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ciint devres_release_all(struct device *dev); 18362306a36Sopenharmony_civoid device_block_probing(void); 18462306a36Sopenharmony_civoid device_unblock_probing(void); 18562306a36Sopenharmony_civoid deferred_probe_extend_timeout(void); 18662306a36Sopenharmony_civoid driver_deferred_probe_trigger(void); 18762306a36Sopenharmony_ciconst char *device_get_devnode(const struct device *dev, umode_t *mode, 18862306a36Sopenharmony_ci kuid_t *uid, kgid_t *gid, const char **tmp); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* /sys/devices directory */ 19162306a36Sopenharmony_ciextern struct kset *devices_kset; 19262306a36Sopenharmony_civoid devices_kset_move_last(struct device *dev); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) 19562306a36Sopenharmony_civoid module_add_driver(struct module *mod, struct device_driver *drv); 19662306a36Sopenharmony_civoid module_remove_driver(struct device_driver *drv); 19762306a36Sopenharmony_ci#else 19862306a36Sopenharmony_cistatic inline void module_add_driver(struct module *mod, 19962306a36Sopenharmony_ci struct device_driver *drv) { } 20062306a36Sopenharmony_cistatic inline void module_remove_driver(struct device_driver *drv) { } 20162306a36Sopenharmony_ci#endif 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#ifdef CONFIG_DEVTMPFS 20462306a36Sopenharmony_ciint devtmpfs_init(void); 20562306a36Sopenharmony_ci#else 20662306a36Sopenharmony_cistatic inline int devtmpfs_init(void) { return 0; } 20762306a36Sopenharmony_ci#endif 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#ifdef CONFIG_BLOCK 21062306a36Sopenharmony_ciextern struct class block_class; 21162306a36Sopenharmony_cistatic inline bool is_blockdev(struct device *dev) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci return dev->class == &block_class; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci#else 21662306a36Sopenharmony_cistatic inline bool is_blockdev(struct device *dev) { return false; } 21762306a36Sopenharmony_ci#endif 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci/* Device links support */ 22062306a36Sopenharmony_ciint device_links_read_lock(void); 22162306a36Sopenharmony_civoid device_links_read_unlock(int idx); 22262306a36Sopenharmony_ciint device_links_read_lock_held(void); 22362306a36Sopenharmony_ciint device_links_check_suppliers(struct device *dev); 22462306a36Sopenharmony_civoid device_links_force_bind(struct device *dev); 22562306a36Sopenharmony_civoid device_links_driver_bound(struct device *dev); 22662306a36Sopenharmony_civoid device_links_driver_cleanup(struct device *dev); 22762306a36Sopenharmony_civoid device_links_no_driver(struct device *dev); 22862306a36Sopenharmony_cibool device_links_busy(struct device *dev); 22962306a36Sopenharmony_civoid device_links_unbind_consumers(struct device *dev); 23062306a36Sopenharmony_civoid fw_devlink_drivers_done(void); 23162306a36Sopenharmony_civoid fw_devlink_probing_done(void); 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci/* device pm support */ 23462306a36Sopenharmony_civoid device_pm_move_to_tail(struct device *dev); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci#ifdef CONFIG_DEVTMPFS 23762306a36Sopenharmony_ciint devtmpfs_create_node(struct device *dev); 23862306a36Sopenharmony_ciint devtmpfs_delete_node(struct device *dev); 23962306a36Sopenharmony_ci#else 24062306a36Sopenharmony_cistatic inline int devtmpfs_create_node(struct device *dev) { return 0; } 24162306a36Sopenharmony_cistatic inline int devtmpfs_delete_node(struct device *dev) { return 0; } 24262306a36Sopenharmony_ci#endif 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_civoid software_node_notify(struct device *dev); 24562306a36Sopenharmony_civoid software_node_notify_remove(struct device *dev); 246