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