Commit fc75f216 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'driver-core-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
 "Here are a small set of changes for 6.5-rc1 for some driver core
  changes. Included in here are:

   - device property cleanups to make it easier to write "agnostic"
     drivers when regards to the firmware layer underneath them (DT vs.
     ACPI)

   - debugfs documentation updates

   - devres additions

   - sysfs documentation and changes to handle empty directory creation
     logic better

   - tiny kernfs optimizations

   - other tiny changes

  All of these have been in linux-next for a while with no reported
  problems"

* tag 'driver-core-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  sysfs: Skip empty folders creation
  sysfs: Improve readability by following the kernel coding style
  drivers: fwnode: fix fwnode_irq_get[_byname]()
  ata: ahci_platform: Make code agnostic to OF/ACPI
  device property: Implement device_is_compatible()
  ACPI: Move ACPI_DEVICE_CLASS() to mod_devicetable.h
  base/node: Use 'property' to identify an access parameter
  driver core: device.h: add some missing kerneldocs
  kernfs: fix missing kernfs_idr_lock to remove an ID from the IDR
  isa: Remove unnecessary checks
  MAINTAINERS: add entry for auxiliary bus
  debugfs: Correct the 'debugfs_create_str' docs
  serial: qcom_geni: Comment use of devm_krealloc rather than devm_krealloc_array
  iio: adc: Use devm_krealloc_array
  hwmon: pmbus: Use devm_krealloc_array
parents 44aeec83 a91845b9
...@@ -3385,6 +3385,16 @@ F: include/uapi/linux/audit.h ...@@ -3385,6 +3385,16 @@ F: include/uapi/linux/audit.h
F: kernel/audit* F: kernel/audit*
F: lib/*audit.c F: lib/*audit.c
AUXILIARY BUS DRIVER
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
R: Dave Ertman <david.m.ertman@intel.com>
R: Ira Weiny <ira.weiny@intel.com>
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
F: Documentation/driver-api/auxiliary_bus.rst
F: drivers/base/auxiliary.c
F: include/linux/auxiliary_bus.h
AUXILIARY DISPLAY DRIVERS AUXILIARY DISPLAY DRIVERS
M: Miguel Ojeda <ojeda@kernel.org> M: Miguel Ojeda <ojeda@kernel.org>
S: Maintained S: Maintained
......
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/libata.h> #include <linux/libata.h>
#include <linux/ahci_platform.h> #include <linux/ahci_platform.h>
#include <linux/acpi.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include "ahci.h" #include "ahci.h"
...@@ -56,10 +56,10 @@ static int ahci_probe(struct platform_device *pdev) ...@@ -56,10 +56,10 @@ static int ahci_probe(struct platform_device *pdev)
if (rc) if (rc)
return rc; return rc;
if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) if (device_is_compatible(dev, "hisilicon,hisi-ahci"))
hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
port = acpi_device_get_match_data(dev); port = device_get_match_data(dev);
if (!port) if (!port)
port = &ahci_port_info; port = &ahci_port_info;
......
...@@ -149,11 +149,8 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) ...@@ -149,11 +149,8 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
break; break;
} }
if (isa_dev->dev.platform_data) { isa_dev->next = isa_driver->devices;
isa_dev->next = isa_driver->devices; isa_driver->devices = &isa_dev->dev;
isa_driver->devices = &isa_dev->dev;
} else
device_unregister(&isa_dev->dev);
} }
if (!error && !isa_driver->devices) if (!error && !isa_driver->devices)
......
...@@ -162,15 +162,15 @@ static struct node_access_nodes *node_init_node_access(struct node *node, ...@@ -162,15 +162,15 @@ static struct node_access_nodes *node_init_node_access(struct node *node,
} }
#ifdef CONFIG_HMEM_REPORTING #ifdef CONFIG_HMEM_REPORTING
#define ACCESS_ATTR(name) \ #define ACCESS_ATTR(property) \
static ssize_t name##_show(struct device *dev, \ static ssize_t property##_show(struct device *dev, \
struct device_attribute *attr, \ struct device_attribute *attr, \
char *buf) \ char *buf) \
{ \ { \
return sysfs_emit(buf, "%u\n", \ return sysfs_emit(buf, "%u\n", \
to_access_nodes(dev)->hmem_attrs.name); \ to_access_nodes(dev)->hmem_attrs.property); \
} \ } \
static DEVICE_ATTR_RO(name) static DEVICE_ATTR_RO(property)
ACCESS_ATTR(read_bandwidth); ACCESS_ATTR(read_bandwidth);
ACCESS_ATTR(read_latency); ACCESS_ATTR(read_latency);
......
...@@ -987,12 +987,18 @@ EXPORT_SYMBOL(fwnode_iomap); ...@@ -987,12 +987,18 @@ EXPORT_SYMBOL(fwnode_iomap);
* @fwnode: Pointer to the firmware node * @fwnode: Pointer to the firmware node
* @index: Zero-based index of the IRQ * @index: Zero-based index of the IRQ
* *
* Return: Linux IRQ number on success. Other values are determined * Return: Linux IRQ number on success. Negative errno on failure.
* according to acpi_irq_get() or of_irq_get() operation.
*/ */
int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
{ {
return fwnode_call_int_op(fwnode, irq_get, index); int ret;
ret = fwnode_call_int_op(fwnode, irq_get, index);
/* We treat mapping errors as invalid case */
if (ret == 0)
return -EINVAL;
return ret;
} }
EXPORT_SYMBOL(fwnode_irq_get); EXPORT_SYMBOL(fwnode_irq_get);
......
...@@ -1191,9 +1191,9 @@ static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) ...@@ -1191,9 +1191,9 @@ static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
{ {
if (data->num_attributes >= data->max_attributes - 1) { if (data->num_attributes >= data->max_attributes - 1) {
int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE;
void *new_attrs = devm_krealloc(data->dev, data->group.attrs, void *new_attrs = devm_krealloc_array(data->dev, data->group.attrs,
new_max_attrs * sizeof(void *), new_max_attrs, sizeof(void *),
GFP_KERNEL); GFP_KERNEL);
if (!new_attrs) if (!new_attrs)
return -ENOMEM; return -ENOMEM;
data->group.attrs = new_attrs; data->group.attrs = new_attrs;
......
...@@ -1263,7 +1263,7 @@ static int ams_parse_firmware(struct iio_dev *indio_dev) ...@@ -1263,7 +1263,7 @@ static int ams_parse_firmware(struct iio_dev *indio_dev)
struct device *dev = indio_dev->dev.parent; struct device *dev = indio_dev->dev.parent;
struct fwnode_handle *child = NULL; struct fwnode_handle *child = NULL;
struct fwnode_handle *fwnode = dev_fwnode(dev); struct fwnode_handle *fwnode = dev_fwnode(dev);
size_t ams_size, dev_size; size_t ams_size;
int ret, ch_cnt = 0, i, rising_off, falling_off; int ret, ch_cnt = 0, i, rising_off, falling_off;
unsigned int num_channels = 0; unsigned int num_channels = 0;
...@@ -1320,11 +1320,8 @@ static int ams_parse_firmware(struct iio_dev *indio_dev) ...@@ -1320,11 +1320,8 @@ static int ams_parse_firmware(struct iio_dev *indio_dev)
} }
} }
dev_size = array_size(sizeof(*dev_channels), num_channels); dev_channels = devm_krealloc_array(dev, ams_channels, num_channels,
if (dev_size == SIZE_MAX) sizeof(*dev_channels), GFP_KERNEL);
return -ENOMEM;
dev_channels = devm_krealloc(dev, ams_channels, dev_size, GFP_KERNEL);
if (!dev_channels) if (!dev_channels)
return -ENOMEM; return -ENOMEM;
......
...@@ -613,20 +613,17 @@ static int xadc_update_scan_mode(struct iio_dev *indio_dev, ...@@ -613,20 +613,17 @@ static int xadc_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *mask) const unsigned long *mask)
{ {
struct xadc *xadc = iio_priv(indio_dev); struct xadc *xadc = iio_priv(indio_dev);
size_t new_size, n; size_t n;
void *data; void *data;
n = bitmap_weight(mask, indio_dev->masklength); n = bitmap_weight(mask, indio_dev->masklength);
if (check_mul_overflow(n, sizeof(*xadc->data), &new_size)) data = devm_krealloc_array(indio_dev->dev.parent, xadc->data,
return -ENOMEM; n, sizeof(*xadc->data), GFP_KERNEL);
data = devm_krealloc(indio_dev->dev.parent, xadc->data,
new_size, GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
memset(data, 0, new_size); memset(data, 0, n * sizeof(*xadc->data));
xadc->data = data; xadc->data = data;
return 0; return 0;
...@@ -1281,9 +1278,9 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, unsigned int *conf, int irq) ...@@ -1281,9 +1278,9 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, unsigned int *conf, int irq)
} }
indio_dev->num_channels = num_channels; indio_dev->num_channels = num_channels;
indio_dev->channels = devm_krealloc(dev, channels, indio_dev->channels = devm_krealloc_array(dev, channels,
sizeof(*channels) * num_channels, num_channels, sizeof(*channels),
GFP_KERNEL); GFP_KERNEL);
/* If we can't resize the channels array, just use the original */ /* If we can't resize the channels array, just use the original */
if (!indio_dev->channels) if (!indio_dev->channels)
indio_dev->channels = channels; indio_dev->channels = channels;
......
...@@ -1053,6 +1053,11 @@ static int setup_fifos(struct qcom_geni_serial_port *port) ...@@ -1053,6 +1053,11 @@ static int setup_fifos(struct qcom_geni_serial_port *port)
(port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE; (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) { if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) {
/*
* Use krealloc rather than krealloc_array because rx_buf is
* accessed as 1 byte entries as well as 4 byte entries so it's
* not necessarily an array.
*/
port->rx_buf = devm_krealloc(uport->dev, port->rx_buf, port->rx_buf = devm_krealloc(uport->dev, port->rx_buf,
port->rx_fifo_depth * sizeof(u32), port->rx_fifo_depth * sizeof(u32),
GFP_KERNEL); GFP_KERNEL);
......
...@@ -940,15 +940,6 @@ static const struct file_operations fops_str_wo = { ...@@ -940,15 +940,6 @@ static const struct file_operations fops_str_wo = {
* This function creates a file in debugfs with the given name that * This function creates a file in debugfs with the given name that
* contains the value of the variable @value. If the @mode variable is so * contains the value of the variable @value. If the @mode variable is so
* set, it can be read from, and written to. * set, it can be read from, and written to.
*
* This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the file is
* to be removed (no automatic cleanup happens if your module is unloaded,
* you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be
* returned.
*
* If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
* be returned.
*/ */
void debugfs_create_str(const char *name, umode_t mode, void debugfs_create_str(const char *name, umode_t mode,
struct dentry *parent, char **value) struct dentry *parent, char **value)
......
...@@ -655,7 +655,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, ...@@ -655,7 +655,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
return kn; return kn;
err_out3: err_out3:
spin_lock(&kernfs_idr_lock);
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
spin_unlock(&kernfs_idr_lock);
err_out2: err_out2:
kmem_cache_free(kernfs_node_cache, kn); kmem_cache_free(kernfs_node_cache, kn);
err_out1: err_out1:
......
...@@ -118,11 +118,13 @@ static int internal_create_group(struct kobject *kobj, int update, ...@@ -118,11 +118,13 @@ static int internal_create_group(struct kobject *kobj, int update,
/* Updates may happen before the object has been instantiated */ /* Updates may happen before the object has been instantiated */
if (unlikely(update && !kobj->sd)) if (unlikely(update && !kobj->sd))
return -EINVAL; return -EINVAL;
if (!grp->attrs && !grp->bin_attrs) { if (!grp->attrs && !grp->bin_attrs) {
WARN(1, "sysfs: (bin_)attrs not set by subsystem for group: %s/%s\n", pr_debug("sysfs: (bin_)attrs not set by subsystem for group: %s/%s, skipping\n",
kobj->name, grp->name ?: ""); kobj->name, grp->name ?: "");
return -EINVAL; return 0;
} }
kobject_get_ownership(kobj, &uid, &gid); kobject_get_ownership(kobj, &uid, &gid);
if (grp->name) { if (grp->name) {
if (update) { if (update) {
...@@ -142,8 +144,10 @@ static int internal_create_group(struct kobject *kobj, int update, ...@@ -142,8 +144,10 @@ static int internal_create_group(struct kobject *kobj, int update,
return PTR_ERR(kn); return PTR_ERR(kn);
} }
} }
} else } else {
kn = kobj->sd; kn = kobj->sd;
}
kernfs_get(kn); kernfs_get(kn);
error = create_files(kn, kobj, uid, gid, grp, update); error = create_files(kn, kobj, uid, gid, grp, update);
if (error) { if (error) {
......
...@@ -70,19 +70,6 @@ static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) ...@@ -70,19 +70,6 @@ static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode)
kfree(fwnode); kfree(fwnode);
} }
/**
* ACPI_DEVICE_CLASS - macro used to describe an ACPI device with
* the PCI-defined class-code information
*
* @_cls : the class, subclass, prog-if triple for this device
* @_msk : the class mask for this device
*
* This macro is used to create a struct acpi_device_id that matches a
* specific PCI class. The .id and .driver_data fields will be left
* initialized with the default value.
*/
#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk),
static inline bool has_acpi_companion(struct device *dev) static inline bool has_acpi_companion(struct device *dev)
{ {
return is_acpi_device_node(dev->fwnode); return is_acpi_device_node(dev->fwnode);
...@@ -782,7 +769,6 @@ const char *acpi_get_subsystem_id(acpi_handle handle); ...@@ -782,7 +769,6 @@ const char *acpi_get_subsystem_id(acpi_handle handle);
#define ACPI_COMPANION_SET(dev, adev) do { } while (0) #define ACPI_COMPANION_SET(dev, adev) do { } while (0)
#define ACPI_HANDLE(dev) (NULL) #define ACPI_HANDLE(dev) (NULL)
#define ACPI_HANDLE_FWNODE(fwnode) (NULL) #define ACPI_HANDLE_FWNODE(fwnode) (NULL)
#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (0), .cls_msk = (0),
#include <acpi/acpi_numa.h> #include <acpi/acpi_numa.h>
......
...@@ -96,7 +96,12 @@ struct device_type { ...@@ -96,7 +96,12 @@ struct device_type {
const struct dev_pm_ops *pm; 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 device_attribute {
struct attribute attr; struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr, ssize_t (*show)(struct device *dev, struct device_attribute *attr,
...@@ -105,6 +110,11 @@ struct device_attribute { ...@@ -105,6 +110,11 @@ struct device_attribute {
const char *buf, size_t count); 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 dev_ext_attribute {
struct device_attribute attr; struct device_attribute attr;
void *var; void *var;
...@@ -123,30 +133,124 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, ...@@ -123,30 +133,124 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count); const char *buf, size_t count);
/**
* 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) \ #define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __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) \ #define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = \ struct device_attribute dev_attr_##_name = \
__ATTR_PREALLOC(_name, _mode, _show, _store) __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) \ #define DEVICE_ATTR_RW(_name) \
struct device_attribute dev_attr_##_name = __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) \ #define DEVICE_ATTR_ADMIN_RW(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RW_MODE(_name, 0600) 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) \ #define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_##_name = __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) \ #define DEVICE_ATTR_ADMIN_RO(_name) \
struct device_attribute dev_attr_##_name = __ATTR_RO_MODE(_name, 0400) 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) \ #define DEVICE_ATTR_WO(_name) \
struct device_attribute dev_attr_##_name = __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) \ #define DEVICE_ULONG_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \ struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } { __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) \ #define DEVICE_INT_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \ struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) } { __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) \ #define DEVICE_BOOL_ATTR(_name, _mode, _var) \
struct dev_ext_attribute dev_attr_##_name = \ struct dev_ext_attribute dev_attr_##_name = \
{ __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) } { __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) }
#define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = \ struct device_attribute dev_attr_##_name = \
__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
...@@ -711,6 +815,11 @@ static inline bool device_iommu_mapped(struct device *dev) ...@@ -711,6 +815,11 @@ static inline bool device_iommu_mapped(struct device *dev)
/* Get the wakeup routines, which depend on struct device */ /* Get the wakeup routines, which depend on struct device */
#include <linux/pm_wakeup.h> #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) static inline const char *dev_name(const struct device *dev)
{ {
/* Use the init name until the kobject becomes available */ /* Use the init name until the kobject becomes available */
......
...@@ -221,6 +221,19 @@ struct acpi_device_id { ...@@ -221,6 +221,19 @@ struct acpi_device_id {
__u32 cls_msk; __u32 cls_msk;
}; };
/**
* ACPI_DEVICE_CLASS - macro used to describe an ACPI device with
* the PCI-defined class-code information
*
* @_cls : the class, subclass, prog-if triple for this device
* @_msk : the class mask for this device
*
* This macro is used to create a struct acpi_device_id that matches a
* specific PCI class. The .id and .driver_data fields will be left
* initialized with the default value.
*/
#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk),
#define PNP_ID_LEN 8 #define PNP_ID_LEN 8
#define PNP_MAX_DEVICES 8 #define PNP_MAX_DEVICES 8
......
...@@ -85,6 +85,18 @@ bool fwnode_device_is_compatible(const struct fwnode_handle *fwnode, const char ...@@ -85,6 +85,18 @@ bool fwnode_device_is_compatible(const struct fwnode_handle *fwnode, const char
return fwnode_property_match_string(fwnode, "compatible", compat) >= 0; return fwnode_property_match_string(fwnode, "compatible", compat) >= 0;
} }
/**
* device_is_compatible - match 'compatible' property of the device with a given string
* @dev: Pointer to the struct device
* @compat: The string to match 'compatible' property with
*
* Returns: true if matches, otherwise false.
*/
static inline bool device_is_compatible(const struct device *dev, const char *compat)
{
return fwnode_device_is_compatible(dev_fwnode(dev), compat);
}
int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop, const char *prop, const char *nargs_prop,
unsigned int nargs, unsigned int index, unsigned int nargs, unsigned int index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment