diff options
Diffstat (limited to 'include/linux/device.h')
| -rw-r--r-- | include/linux/device.h | 450 |
1 files changed, 274 insertions, 176 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 44e3acae7b36..0be95294b6e6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -26,10 +26,11 @@ #include <linux/atomic.h> #include <linux/uidgid.h> #include <linux/gfp.h> -#include <linux/overflow.h> #include <linux/device/bus.h> #include <linux/device/class.h> +#include <linux/device/devres.h> #include <linux/device/driver.h> +#include <linux/cleanup.h> #include <asm/device.h> struct device; @@ -41,7 +42,6 @@ struct class; struct subsys_private; struct device_node; struct fwnode_handle; -struct iommu_ops; struct iommu_group; struct dev_pin_info; struct dev_iommu; @@ -62,7 +62,7 @@ struct msi_device_data; */ struct subsys_interface { const char *name; - struct bus_type *subsys; + const struct bus_type *subsys; struct list_head node; int (*add_dev)(struct device *dev, struct subsys_interface *sif); void (*remove_dev)(struct device *dev, struct subsys_interface *sif); @@ -71,9 +71,9 @@ struct subsys_interface { int subsys_interface_register(struct subsys_interface *sif); void subsys_interface_unregister(struct subsys_interface *sif); -int subsys_system_register(struct bus_type *subsys, +int subsys_system_register(const struct bus_type *subsys, const struct attribute_group **groups); -int subsys_virtual_register(struct bus_type *subsys, +int subsys_virtual_register(const struct bus_type *subsys, const struct attribute_group **groups); /* @@ -88,15 +88,20 @@ int subsys_virtual_register(struct bus_type *subsys, struct device_type { const char *name; const struct attribute_group **groups; - int (*uevent)(struct device *dev, struct kobj_uevent_env *env); - char *(*devnode)(struct device *dev, umode_t *mode, + int (*uevent)(const struct device *dev, struct kobj_uevent_env *env); + char *(*devnode)(const struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid); void (*release)(struct device *dev); const struct dev_pm_ops *pm; }; -/* interface for exporting device attributes */ +/** + * struct device_attribute - Interface for exporting device attributes. + * @attr: sysfs attribute definition. + * @show: Show handler. + * @store: Store handler. + */ struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, @@ -105,6 +110,11 @@ struct device_attribute { const char *buf, size_t count); }; +/** + * struct dev_ext_attribute - Exported device attribute with extra context. + * @attr: Exported device attribute. + * @var: Pointer to context. + */ struct dev_ext_attribute { struct device_attribute attr; void *var; @@ -122,31 +132,140 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, char *buf); ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +ssize_t device_show_string(struct device *dev, struct device_attribute *attr, + char *buf); +/** + * DEVICE_ATTR - Define a device attribute. + * @_name: Attribute name. + * @_mode: File mode. + * @_show: Show handler. Optional, but mandatory if attribute is readable. + * @_store: Store handler. Optional, but mandatory if attribute is writable. + * + * Convenience macro for defining a struct device_attribute. + * + * For example, ``DEVICE_ATTR(foo, 0644, foo_show, foo_store);`` expands to: + * + * .. code-block:: c + * + * struct device_attribute dev_attr_foo = { + * .attr = { .name = "foo", .mode = 0644 }, + * .show = foo_show, + * .store = foo_store, + * }; + */ #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) + +/** + * DEVICE_ATTR_PREALLOC - Define a preallocated device attribute. + * @_name: Attribute name. + * @_mode: File mode. + * @_show: Show handler. Optional, but mandatory if attribute is readable. + * @_store: Store handler. Optional, but mandatory if attribute is writable. + * + * Like DEVICE_ATTR(), but ``SYSFS_PREALLOC`` is set on @_mode. + */ #define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = \ __ATTR_PREALLOC(_name, _mode, _show, _store) + +/** + * DEVICE_ATTR_RW - Define a read-write device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0644, @_show is <_name>_show, + * and @_store is <_name>_store. + */ #define DEVICE_ATTR_RW(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RW(_name) + +/** + * DEVICE_ATTR_ADMIN_RW - Define an admin-only read-write device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR_RW(), but @_mode is 0600. + */ #define DEVICE_ATTR_ADMIN_RW(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RW_MODE(_name, 0600) + +/** + * DEVICE_ATTR_RO - Define a readable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0444 and @_show is <_name>_show. + */ #define DEVICE_ATTR_RO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RO(_name) + +/** + * DEVICE_ATTR_ADMIN_RO - Define an admin-only readable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR_RO(), but @_mode is 0400. + */ #define DEVICE_ATTR_ADMIN_RO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RO_MODE(_name, 0400) + +/** + * DEVICE_ATTR_WO - Define an admin-only writable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0200 and @_store is <_name>_store. + */ #define DEVICE_ATTR_WO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_WO(_name) + +/** + * DEVICE_ULONG_ATTR - Define a device attribute backed by an unsigned long. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of unsigned long. + * + * Like DEVICE_ATTR(), but @_show and @_store are automatically provided + * such that reads and writes to the attribute from userspace affect @_var. + */ #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } + +/** + * DEVICE_INT_ATTR - Define a device attribute backed by an int. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of int. + * + * Like DEVICE_ULONG_ATTR(), but @_var is an int. + */ #define DEVICE_INT_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) } + +/** + * DEVICE_BOOL_ATTR - Define a device attribute backed by a bool. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of bool. + * + * Like DEVICE_ULONG_ATTR(), but @_var is a bool. + */ #define DEVICE_BOOL_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) } + +/** + * DEVICE_STRING_ATTR_RO - Define a device attribute backed by a r/o string. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of string. + * + * Like DEVICE_ULONG_ATTR(), but @_var is a string. Because the length of the + * string allocation is unknown, the attribute must be read-only. + */ +#define DEVICE_STRING_ATTR_RO(_name, _mode, _var) \ + struct dev_ext_attribute dev_attr_##_name = \ + { __ATTR(_name, (_mode) & ~0222, device_show_string, NULL), (_var) } + #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = \ __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) @@ -162,122 +281,6 @@ int __must_check device_create_bin_file(struct device *dev, void device_remove_bin_file(struct device *dev, const struct bin_attribute *attr); -/* device resource management */ -typedef void (*dr_release_t)(struct device *dev, void *res); -typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data); - -void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, - int nid, const char *name) __malloc; -#define devres_alloc(release, size, gfp) \ - __devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release) -#define devres_alloc_node(release, size, gfp, nid) \ - __devres_alloc_node(release, size, gfp, nid, #release) - -void devres_for_each_res(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data, - void (*fn)(struct device *, void *, void *), - void *data); -void devres_free(void *res); -void devres_add(struct device *dev, void *res); -void *devres_find(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data); -void *devres_get(struct device *dev, void *new_res, - dr_match_t match, void *match_data); -void *devres_remove(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data); -int devres_destroy(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data); -int devres_release(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data); - -/* devres group */ -void * __must_check devres_open_group(struct device *dev, void *id, gfp_t gfp); -void devres_close_group(struct device *dev, void *id); -void devres_remove_group(struct device *dev, void *id); -int devres_release_group(struct device *dev, void *id); - -/* managed devm_k.alloc/kfree for device drivers */ -void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) __alloc_size(2); -void *devm_krealloc(struct device *dev, void *ptr, size_t size, - gfp_t gfp) __must_check __realloc_size(3); -__printf(3, 0) char *devm_kvasprintf(struct device *dev, gfp_t gfp, - const char *fmt, va_list ap) __malloc; -__printf(3, 4) char *devm_kasprintf(struct device *dev, gfp_t gfp, - const char *fmt, ...) __malloc; -static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) -{ - return devm_kmalloc(dev, size, gfp | __GFP_ZERO); -} -static inline void *devm_kmalloc_array(struct device *dev, - size_t n, size_t size, gfp_t flags) -{ - size_t bytes; - - if (unlikely(check_mul_overflow(n, size, &bytes))) - return NULL; - - return devm_kmalloc(dev, bytes, flags); -} -static inline void *devm_kcalloc(struct device *dev, - size_t n, size_t size, gfp_t flags) -{ - return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); -} -void devm_kfree(struct device *dev, const void *p); -char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; -const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp); -void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp) - __realloc_size(3); - -unsigned long devm_get_free_pages(struct device *dev, - gfp_t gfp_mask, unsigned int order); -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, - resource_size_t *size); - -/* allows to add/remove a custom action to devres stack */ -int devm_add_action(struct device *dev, void (*action)(void *), void *data); -void devm_remove_action(struct device *dev, void (*action)(void *), void *data); -void devm_release_action(struct device *dev, void (*action)(void *), void *data); - -static inline int devm_add_action_or_reset(struct device *dev, - void (*action)(void *), void *data) -{ - int ret; - - ret = devm_add_action(dev, action, data); - if (ret) - action(data); - - return ret; -} - -/** - * devm_alloc_percpu - Resource-managed alloc_percpu - * @dev: Device to allocate per-cpu memory for - * @type: Type to allocate per-cpu memory for - * - * Managed alloc_percpu. Per-cpu memory allocated with this function is - * automatically freed on driver detach. - * - * RETURNS: - * Pointer to allocated memory on success, NULL on failure. - */ -#define devm_alloc_percpu(dev, type) \ - ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \ - __alignof__(type))) - -void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, - size_t align); -void devm_free_percpu(struct device *dev, void __percpu *pdata); - struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about @@ -328,6 +331,7 @@ enum device_link_state { #define DL_FLAG_MANAGED BIT(6) #define DL_FLAG_SYNC_STATE_ONLY BIT(7) #define DL_FLAG_INFERRED BIT(8) +#define DL_FLAG_CYCLE BIT(9) /** * enum dl_dev_state - Device driver presence tracking information. @@ -503,7 +507,10 @@ struct device_physical_location { * @dma_pools: Dma pools (if dma'ble device). * @dma_mem: Internal for coherent mem override. * @cma_area: Contiguous memory area for dma allocations - * @dma_io_tlb_mem: Pointer to the swiotlb pool used. Not for driver use. + * @dma_io_tlb_mem: Software IO TLB allocator. Not for driver use. + * @dma_io_tlb_pools: List of transient swiotlb memory pools. + * @dma_io_tlb_lock: Protects changes to the list of active pools. + * @dma_uses_io_tlb: %true if device has used the software IO TLB. * @archdata: For arch-specific additions. * @of_node: Associated device tree node. * @fwnode: Associated device node supplied by platform firmware. @@ -511,7 +518,6 @@ struct device_physical_location { * @id: device instance * @devres_lock: Spinlock to protect the resource of the device. * @devres_head: The resources list of the device. - * @knode_class: The node used to add the device to the class list. * @class: The class of the device. * @groups: Optional attribute groups. * @release: Callback to free the device after all references have @@ -542,6 +548,9 @@ struct device_physical_location { * and optionall (if the coherent mask is large enough) also * for dma allocations. This flag is managed by the dma ops * instance from ->dma_supported. + * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers. + * @dma_iommu: Device is using default IOMMU implementation for DMA and + * doesn't rely on dma_ops structure. * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -560,7 +569,7 @@ struct device { const char *init_name; /* initial name of the device */ const struct device_type *type; - struct bus_type *bus; /* type of bus device is on */ + const struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *platform_data; /* Platform specific data, device @@ -583,7 +592,7 @@ struct device { struct dev_pin_info *pins; #endif struct dev_msi_info msi; -#ifdef CONFIG_DMA_OPS +#ifdef CONFIG_ARCH_HAS_DMA_OPS const struct dma_map_ops *dma_ops; #endif u64 *dma_mask; /* dma mask (if dma'able device) */ @@ -610,6 +619,11 @@ struct device { #ifdef CONFIG_SWIOTLB struct io_tlb_mem *dma_io_tlb_mem; #endif +#ifdef CONFIG_SWIOTLB_DYNAMIC + struct list_head dma_io_tlb_pools; + spinlock_t dma_io_tlb_lock; + bool dma_uses_io_tlb; +#endif /* arch specific additions */ struct dev_archdata archdata; @@ -625,7 +639,7 @@ struct device { spinlock_t devres_lock; struct list_head devres_head; - struct class *class; + const struct class *class; const struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev); @@ -649,6 +663,12 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif +#ifdef CONFIG_DMA_NEED_SYNC + bool dma_skip_sync:1; +#endif +#ifdef CONFIG_IOMMU_DMA + bool dma_iommu:1; +#endif }; /** @@ -694,6 +714,11 @@ static inline bool device_iommu_mapped(struct device *dev) /* Get the wakeup routines, which depend on struct device */ #include <linux/pm_wakeup.h> +/** + * dev_name - Return a device's name. + * @dev: Device with name to get. + * Return: The kobject name of the device, or its initial name if unavailable. + */ static inline const char *dev_name(const struct device *dev) { /* Use the init name until the kobject becomes available */ @@ -807,6 +832,9 @@ static inline bool device_pm_not_required(struct device *dev) static inline void device_set_pm_not_required(struct device *dev) { dev->power.no_pm = true; +#ifdef CONFIG_PM + dev->power.no_callbacks = true; +#endif } static inline void dev_pm_syscore_device(struct device *dev, bool val) @@ -826,6 +854,42 @@ static inline bool dev_pm_test_driver_flags(struct device *dev, u32 flags) return !!(dev->power.driver_flags & flags); } +static inline bool dev_pm_smart_suspend(struct device *dev) +{ +#ifdef CONFIG_PM_SLEEP + return dev->power.smart_suspend; +#else + return false; +#endif +} + +/* + * dev_pm_set_strict_midlayer - Update the device's power.strict_midlayer flag + * @dev: Target device. + * @val: New flag value. + * + * When set, power.strict_midlayer means that the middle layer power management + * code (typically, a bus type or a PM domain) does not expect its runtime PM + * suspend callback to be invoked at all during system-wide PM transitions and + * it does not expect its runtime PM resume callback to be invoked at any point + * when runtime PM is disabled for the device during system-wide PM transitions. + */ +static inline void dev_pm_set_strict_midlayer(struct device *dev, bool val) +{ +#ifdef CONFIG_PM_SLEEP + dev->power.strict_midlayer = val; +#endif +} + +static inline bool dev_pm_strict_midlayer_is_set(struct device *dev) +{ +#ifdef CONFIG_PM_SLEEP + return dev->power.strict_midlayer; +#else + return false; +#endif +} + static inline void device_lock(struct device *dev) { mutex_lock(&dev->mutex); @@ -846,18 +910,13 @@ static inline void device_unlock(struct device *dev) mutex_unlock(&dev->mutex); } +DEFINE_GUARD(device, struct device *, device_lock(_T), device_unlock(_T)) + static inline void device_lock_assert(struct device *dev) { lockdep_assert_held(&dev->mutex); } -static inline struct device_node *dev_of_node(struct device *dev) -{ - if (!IS_ENABLED(CONFIG_OF) || !dev) - return NULL; - return dev->of_node; -} - static inline bool dev_has_sync_state(struct device *dev) { if (!dev) @@ -869,6 +928,18 @@ static inline bool dev_has_sync_state(struct device *dev) return false; } +static inline int dev_set_drv_sync_state(struct device *dev, + void (*fn)(struct device *dev)) +{ + if (!dev || !dev->driver) + return 0; + if (dev->driver->sync_state && dev->driver->sync_state != fn) + return -EBUSY; + if (!dev->driver->sync_state) + dev->driver->sync_state = fn; + return 0; +} + static inline void dev_set_removable(struct device *dev, enum device_removable removable) { @@ -893,23 +964,52 @@ void device_unregister(struct device *dev); void device_initialize(struct device *dev); int __must_check device_add(struct device *dev); void device_del(struct device *dev); -int device_for_each_child(struct device *dev, void *data, - int (*fn)(struct device *dev, void *data)); -int device_for_each_child_reverse(struct device *dev, void *data, - int (*fn)(struct device *dev, void *data)); -struct device *device_find_child(struct device *dev, void *data, - int (*match)(struct device *dev, void *data)); -struct device *device_find_child_by_name(struct device *parent, - const char *name); -struct device *device_find_any_child(struct device *parent); + +DEFINE_FREE(device_del, struct device *, if (_T) device_del(_T)) + +int device_for_each_child(struct device *parent, void *data, + device_iter_t fn); +int device_for_each_child_reverse(struct device *parent, void *data, + device_iter_t fn); +int device_for_each_child_reverse_from(struct device *parent, + struct device *from, void *data, + device_iter_t fn); +struct device *device_find_child(struct device *parent, const void *data, + device_match_t match); +/** + * device_find_child_by_name - device iterator for locating a child device. + * @parent: parent struct device + * @name: name of the child device + * + * This is similar to the device_find_child() function above, but it + * returns a reference to a device that has the name @name. + * + * NOTE: you will need to drop the reference with put_device() after use. + */ +static inline struct device *device_find_child_by_name(struct device *parent, + const char *name) +{ + return device_find_child(parent, name, device_match_name); +} + +/** + * device_find_any_child - device iterator for locating a child device, if any. + * @parent: parent struct device + * + * This is similar to the device_find_child() function above, but it + * returns a reference to a child device, if any. + * + * NOTE: you will need to drop the reference with put_device() after use. + */ +static inline struct device *device_find_any_child(struct device *parent) +{ + return device_find_child(parent, NULL, device_match_any); +} int device_rename(struct device *dev, const char *new_name); int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order); int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid); -const char *device_get_devnode(struct device *dev, umode_t *mode, kuid_t *uid, - kgid_t *gid, const char **tmp); -int device_is_dependent(struct device *dev, void *target); static inline bool device_supports_offline(struct device *dev) { @@ -964,10 +1064,21 @@ void unlock_device_hotplug(void); int lock_device_hotplug_sysfs(void); int device_offline(struct device *dev); int device_online(struct device *dev); + void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); -void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); void device_set_node(struct device *dev, struct fwnode_handle *fwnode); +int device_add_of_node(struct device *dev, struct device_node *of_node); +void device_remove_of_node(struct device *dev); +void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); +struct device *get_dev_from_fwnode(struct fwnode_handle *fwnode); + +static inline struct device_node *dev_of_node(struct device *dev) +{ + if (!IS_ENABLED(CONFIG_OF) || !dev) + return NULL; + return dev->of_node; +} static inline int dev_num_vf(struct device *dev) { @@ -996,12 +1107,12 @@ static inline void *dev_get_platdata(const struct device *dev) * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ -int __must_check device_driver_attach(struct device_driver *drv, +int __must_check device_driver_attach(const struct device_driver *drv, struct device *dev); int __must_check device_bind_driver(struct device *dev); void device_release_driver(struct device *dev); int __must_check device_attach(struct device *dev); -int __must_check driver_attach(struct device_driver *drv); +int __must_check driver_attach(const struct device_driver *drv); void device_initial_probe(struct device *dev); int __must_check device_reprobe(struct device *dev); @@ -1011,13 +1122,13 @@ bool device_is_bound(struct device *dev); * Easy functions for dynamically creating devices on the fly */ __printf(5, 6) struct device * -device_create(struct class *cls, struct device *parent, dev_t devt, +device_create(const struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); __printf(6, 7) struct device * -device_create_with_groups(struct class *cls, struct device *parent, dev_t devt, +device_create_with_groups(const struct class *cls, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...); -void device_destroy(struct class *cls, dev_t devt); +void device_destroy(const struct class *cls, dev_t devt); int __must_check device_add_groups(struct device *dev, const struct attribute_group **groups); @@ -1037,31 +1148,21 @@ static inline void device_remove_group(struct device *dev, { const struct attribute_group *groups[] = { grp, NULL }; - return device_remove_groups(dev, groups); + device_remove_groups(dev, groups); } -int __must_check devm_device_add_groups(struct device *dev, - const struct attribute_group **groups); int __must_check devm_device_add_group(struct device *dev, const struct attribute_group *grp); /* - * Platform "fixup" functions - allow the platform to have their say - * about devices and actions that the general device layer doesn't - * know about. - */ -/* Notify platform of device discovery */ -extern int (*platform_notify)(struct device *dev); - -extern int (*platform_notify_remove)(struct device *dev); - - -/* * get_device - atomically increment the reference count for the device. * */ struct device *get_device(struct device *dev); void put_device(struct device *dev); + +DEFINE_FREE(put_device, struct device *, if (_T) put_device(_T)) + bool kill_device(struct device *dev); #ifdef CONFIG_DEVTMPFS @@ -1083,9 +1184,12 @@ 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); +void device_link_wait_removal(void); -extern __printf(3, 4) -int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); +static inline bool device_link_test(const struct device_link *link, u32 flags) +{ + return !!(link->flags & flags); +} /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ @@ -1093,10 +1197,4 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ MODULE_ALIAS("char-major-" __stringify(major) "-*") -#ifdef CONFIG_SYSFS_DEPRECATED -extern long sysfs_deprecated; -#else -#define sysfs_deprecated 0 -#endif - #endif /* _DEVICE_H_ */ |
