Driver core patches for 5.4-rc1

Here is the big driver core update for 5.4-rc1.
 
 There was a bit of a churn in here, with a number of core and OF
 platform patches being added to the tree, and then after much discussion
 and review and a day-long in-person meeting, they were decided to be
 reverted and a new set of patches is currently being reviewed on the
 mailing list.
 
 Other than that churn, there are two "persistent" branches in here that
 other trees will be pulling in as well during the merge window.  One
 branch to add support for drivers to have the driver core automatically
 add sysfs attribute files when a driver is bound to a device so that the
 driver doesn't have to manually do it (and then clean it up, as it
 always gets it wrong).
 
 There's another branch in here for generic lookup helpers for the driver
 core that lots of busses are starting to use.  That's the majority of
 the non-driver-core changes in this patch series.
 
 There's also some on-going debugfs file creation cleanup that has been
 slowly happening over the past few releases, with the goal to hopefully
 get that done sometime next year.
 
 All of these have been in linux-next for a while now with no reported
 issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXYIVHA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymEVwCfRPxQHQplI6ZR6h0jPscLSaZnaFIAn1a+rjO2
 EFuuXJ5Ip72F5Ch9AW3G
 =r8lH
 -----END PGP SIGNATURE-----

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

Pull driver core updates from Greg Kroah-Hartman:
 "Here is the big driver core update for 5.4-rc1.

  There was a bit of a churn in here, with a number of core and OF
  platform patches being added to the tree, and then after much
  discussion and review and a day-long in-person meeting, they were
  decided to be reverted and a new set of patches is currently being
  reviewed on the mailing list.

  Other than that churn, there are two "persistent" branches in here
  that other trees will be pulling in as well during the merge window.
  One branch to add support for drivers to have the driver core
  automatically add sysfs attribute files when a driver is bound to a
  device so that the driver doesn't have to manually do it (and then
  clean it up, as it always gets it wrong).

  There's another branch in here for generic lookup helpers for the
  driver core that lots of busses are starting to use. That's the
  majority of the non-driver-core changes in this patch series.

  There's also some on-going debugfs file creation cleanup that has been
  slowly happening over the past few releases, with the goal to
  hopefully get that done sometime next year.

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

[ Note that the above-mentioned generic lookup helpers branch was
  already brought in by the LED merge (commit 4feaab05dc) that had
  shared it.

  Also note that that common branch introduced an i2c bug due to a bad
  conversion, which got fixed here. - Linus ]

* tag 'driver-core-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (49 commits)
  coccinelle: platform_get_irq: Fix parse error
  driver-core: add include guard to linux/container.h
  sysfs: add BIN_ATTR_WO() macro
  driver core: platform: Export platform_get_irq_optional()
  hwmon: pwm-fan: Use platform_get_irq_optional()
  driver core: platform: Introduce platform_get_irq_optional()
  Revert "driver core: Add support for linking devices during device addition"
  Revert "driver core: Add edit_links() callback for drivers"
  Revert "of/platform: Add functional dependency link from DT bindings"
  Revert "driver core: Add sync_state driver/bus callback"
  Revert "of/platform: Pause/resume sync state during init and of_platform_populate()"
  Revert "of/platform: Create device links for all child-supplier depencencies"
  Revert "of/platform: Don't create device links for default busses"
  Revert "of/platform: Fix fn definitons for of_link_is_valid() and of_link_property()"
  Revert "of/platform: Fix device_links_supplier_sync_state_resume() warning"
  Revert "of/platform: Disable generic device linking code for PowerPC"
  devcoredump: fix typo in comment
  devcoredump: use memory_read_from_buffer
  of/platform: Disable generic device linking code for PowerPC
  device.h: Fix warnings for mismatched parameter names in comments
  ...
This commit is contained in:
Linus Torvalds 2019-09-18 10:04:39 -07:00
commit 1f7d290a72
26 changed files with 495 additions and 514 deletions

View File

@ -78,8 +78,8 @@ typically deleted in its ``->remove`` callback for symmetry. That way, if the
driver is compiled as a module, the device link is added on module load and
orderly deleted on unload. The same restrictions that apply to device link
addition (e.g. exclusion of a parallel suspend/resume transition) apply equally
to deletion. Device links with ``DL_FLAG_STATELESS`` unset (i.e. managed
device links) are deleted automatically by the driver core.
to deletion. Device links managed by the driver core are deleted automatically
by it.
Several flags may be specified on device link addition, two of which
have already been mentioned above: ``DL_FLAG_STATELESS`` to express that no

View File

@ -157,6 +157,12 @@ static ssize_t lid_wake_mode_set(struct device *dev,
static DEVICE_ATTR(lid_wake_mode, S_IWUSR | S_IRUGO, lid_wake_mode_show,
lid_wake_mode_set);
static struct attribute *lid_attrs[] = {
&dev_attr_lid_wake_mode.attr,
NULL,
};
ATTRIBUTE_GROUPS(lid);
/*
* Process all items in the EC's SCI queue.
*
@ -510,17 +516,8 @@ static int setup_lid_switch(struct platform_device *pdev)
goto err_register;
}
r = device_create_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode);
if (r) {
dev_err(&pdev->dev, "failed to create wake mode attr: %d\n", r);
goto err_create_attr;
}
return 0;
err_create_attr:
input_unregister_device(lid_switch_idev);
lid_switch_idev = NULL;
err_register:
input_free_device(lid_switch_idev);
return r;
@ -528,7 +525,6 @@ err_register:
static void free_lid_switch(void)
{
device_remove_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode);
input_unregister_device(lid_switch_idev);
}
@ -624,6 +620,7 @@ static int xo1_sci_remove(struct platform_device *pdev)
static struct platform_driver xo1_sci_driver = {
.driver = {
.name = "olpc-xo1-sci-acpi",
.dev_groups = lid_groups,
},
.probe = xo1_sci_probe,
.remove = xo1_sci_remove,

View File

@ -136,6 +136,50 @@ static int device_is_dependent(struct device *dev, void *target)
return ret;
}
static void device_link_init_status(struct device_link *link,
struct device *consumer,
struct device *supplier)
{
switch (supplier->links.status) {
case DL_DEV_PROBING:
switch (consumer->links.status) {
case DL_DEV_PROBING:
/*
* A consumer driver can create a link to a supplier
* that has not completed its probing yet as long as it
* knows that the supplier is already functional (for
* example, it has just acquired some resources from the
* supplier).
*/
link->status = DL_STATE_CONSUMER_PROBE;
break;
default:
link->status = DL_STATE_DORMANT;
break;
}
break;
case DL_DEV_DRIVER_BOUND:
switch (consumer->links.status) {
case DL_DEV_PROBING:
link->status = DL_STATE_CONSUMER_PROBE;
break;
case DL_DEV_DRIVER_BOUND:
link->status = DL_STATE_ACTIVE;
break;
default:
link->status = DL_STATE_AVAILABLE;
break;
}
break;
case DL_DEV_UNBINDING:
link->status = DL_STATE_SUPPLIER_UNBIND;
break;
default:
link->status = DL_STATE_DORMANT;
break;
}
}
static int device_reorder_to_tail(struct device *dev, void *not_used)
{
struct device_link *link;
@ -177,6 +221,13 @@ void device_pm_move_to_tail(struct device *dev)
device_links_read_unlock(idx);
}
#define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \
DL_FLAG_AUTOREMOVE_SUPPLIER | \
DL_FLAG_AUTOPROBE_CONSUMER)
#define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \
DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE)
/**
* device_link_add - Create a link between two devices.
* @consumer: Consumer end of the link.
@ -191,9 +242,9 @@ void device_pm_move_to_tail(struct device *dev)
* of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be
* ignored.
*
* If DL_FLAG_STATELESS is set in @flags, the link is not going to be managed by
* the driver core and, in particular, the caller of this function is expected
* to drop the reference to the link acquired by it directly.
* If DL_FLAG_STATELESS is set in @flags, the caller of this function is
* expected to release the link returned by it directly with the help of either
* device_link_del() or device_link_remove().
*
* If that flag is not set, however, the caller of this function is handing the
* management of the link over to the driver core entirely and its return value
@ -213,9 +264,16 @@ void device_pm_move_to_tail(struct device *dev)
* be used to request the driver core to automaticall probe for a consmer
* driver after successfully binding a driver to the supplier device.
*
* The combination of DL_FLAG_STATELESS and either DL_FLAG_AUTOREMOVE_CONSUMER
* or DL_FLAG_AUTOREMOVE_SUPPLIER set in @flags at the same time is invalid and
* will cause NULL to be returned upfront.
* The combination of DL_FLAG_STATELESS and one of DL_FLAG_AUTOREMOVE_CONSUMER,
* DL_FLAG_AUTOREMOVE_SUPPLIER, or DL_FLAG_AUTOPROBE_CONSUMER set in @flags at
* the same time is invalid and will cause NULL to be returned upfront.
* However, if a device link between the given @consumer and @supplier pair
* exists already when this function is called for them, the existing link will
* be returned regardless of its current type and status (the link's flags may
* be modified then). The caller of this function is then expected to treat
* the link as though it has just been created, so (in particular) if
* DL_FLAG_STATELESS was passed in @flags, the link needs to be released
* explicitly when not needed any more (as stated above).
*
* A side effect of the link creation is re-ordering of dpm_list and the
* devices_kset list by moving the consumer device and all devices depending
@ -231,11 +289,8 @@ struct device_link *device_link_add(struct device *consumer,
{
struct device_link *link;
if (!consumer || !supplier ||
(flags & DL_FLAG_STATELESS &&
flags & (DL_FLAG_AUTOREMOVE_CONSUMER |
DL_FLAG_AUTOREMOVE_SUPPLIER |
DL_FLAG_AUTOPROBE_CONSUMER)) ||
if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS ||
(flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) ||
(flags & DL_FLAG_AUTOPROBE_CONSUMER &&
flags & (DL_FLAG_AUTOREMOVE_CONSUMER |
DL_FLAG_AUTOREMOVE_SUPPLIER)))
@ -248,6 +303,9 @@ struct device_link *device_link_add(struct device *consumer,
}
}
if (!(flags & DL_FLAG_STATELESS))
flags |= DL_FLAG_MANAGED;
device_links_write_lock();
device_pm_lock();
@ -274,15 +332,6 @@ struct device_link *device_link_add(struct device *consumer,
if (link->consumer != consumer)
continue;
/*
* Don't return a stateless link if the caller wants a stateful
* one and vice versa.
*/
if (WARN_ON((flags & DL_FLAG_STATELESS) != (link->flags & DL_FLAG_STATELESS))) {
link = NULL;
goto out;
}
if (flags & DL_FLAG_PM_RUNTIME) {
if (!(link->flags & DL_FLAG_PM_RUNTIME)) {
pm_runtime_new_link(consumer);
@ -293,6 +342,7 @@ struct device_link *device_link_add(struct device *consumer,
}
if (flags & DL_FLAG_STATELESS) {
link->flags |= DL_FLAG_STATELESS;
kref_get(&link->kref);
goto out;
}
@ -311,6 +361,11 @@ struct device_link *device_link_add(struct device *consumer,
link->flags &= ~(DL_FLAG_AUTOREMOVE_CONSUMER |
DL_FLAG_AUTOREMOVE_SUPPLIER);
}
if (!(link->flags & DL_FLAG_MANAGED)) {
kref_get(&link->kref);
link->flags |= DL_FLAG_MANAGED;
device_link_init_status(link, consumer, supplier);
}
goto out;
}
@ -337,48 +392,10 @@ struct device_link *device_link_add(struct device *consumer,
kref_init(&link->kref);
/* Determine the initial link state. */
if (flags & DL_FLAG_STATELESS) {
if (flags & DL_FLAG_STATELESS)
link->status = DL_STATE_NONE;
} else {
switch (supplier->links.status) {
case DL_DEV_PROBING:
switch (consumer->links.status) {
case DL_DEV_PROBING:
/*
* A consumer driver can create a link to a
* supplier that has not completed its probing
* yet as long as it knows that the supplier is
* already functional (for example, it has just
* acquired some resources from the supplier).
*/
link->status = DL_STATE_CONSUMER_PROBE;
break;
default:
link->status = DL_STATE_DORMANT;
break;
}
break;
case DL_DEV_DRIVER_BOUND:
switch (consumer->links.status) {
case DL_DEV_PROBING:
link->status = DL_STATE_CONSUMER_PROBE;
break;
case DL_DEV_DRIVER_BOUND:
link->status = DL_STATE_ACTIVE;
break;
default:
link->status = DL_STATE_AVAILABLE;
break;
}
break;
case DL_DEV_UNBINDING:
link->status = DL_STATE_SUPPLIER_UNBIND;
break;
default:
link->status = DL_STATE_DORMANT;
break;
}
}
else
device_link_init_status(link, consumer, supplier);
/*
* Some callers expect the link creation during consumer driver probe to
@ -540,7 +557,7 @@ static void device_links_missing_supplier(struct device *dev)
* mark the link as "consumer probe in progress" to make the supplier removal
* wait for us to complete (or bad things may happen).
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
int device_links_check_suppliers(struct device *dev)
{
@ -550,7 +567,7 @@ int device_links_check_suppliers(struct device *dev)
device_links_write_lock();
list_for_each_entry(link, &dev->links.suppliers, c_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
if (link->status != DL_STATE_AVAILABLE) {
@ -575,7 +592,7 @@ int device_links_check_suppliers(struct device *dev)
*
* Also change the status of @dev's links to suppliers to "active".
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
void device_links_driver_bound(struct device *dev)
{
@ -584,7 +601,7 @@ void device_links_driver_bound(struct device *dev)
device_links_write_lock();
list_for_each_entry(link, &dev->links.consumers, s_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
/*
@ -605,7 +622,7 @@ void device_links_driver_bound(struct device *dev)
}
list_for_each_entry(link, &dev->links.suppliers, c_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
@ -617,6 +634,13 @@ void device_links_driver_bound(struct device *dev)
device_links_write_unlock();
}
static void device_link_drop_managed(struct device_link *link)
{
link->flags &= ~DL_FLAG_MANAGED;
WRITE_ONCE(link->status, DL_STATE_NONE);
kref_put(&link->kref, __device_link_del);
}
/**
* __device_links_no_driver - Update links of a device without a driver.
* @dev: Device without a drvier.
@ -627,18 +651,18 @@ void device_links_driver_bound(struct device *dev)
* unless they already are in the "supplier unbind in progress" state in which
* case they need not be updated.
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
static void __device_links_no_driver(struct device *dev)
{
struct device_link *link, *ln;
list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER)
__device_link_del(&link->kref);
device_link_drop_managed(link);
else if (link->status == DL_STATE_CONSUMER_PROBE ||
link->status == DL_STATE_ACTIVE)
WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
@ -655,7 +679,7 @@ static void __device_links_no_driver(struct device *dev)
* %__device_links_no_driver() to update links to suppliers for it as
* appropriate.
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
void device_links_no_driver(struct device *dev)
{
@ -664,7 +688,7 @@ void device_links_no_driver(struct device *dev)
device_links_write_lock();
list_for_each_entry(link, &dev->links.consumers, s_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
/*
@ -692,7 +716,7 @@ void device_links_no_driver(struct device *dev)
* invoke %__device_links_no_driver() to update links to suppliers for it as
* appropriate.
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
void device_links_driver_cleanup(struct device *dev)
{
@ -701,7 +725,7 @@ void device_links_driver_cleanup(struct device *dev)
device_links_write_lock();
list_for_each_entry_safe(link, ln, &dev->links.consumers, s_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER);
@ -714,7 +738,7 @@ void device_links_driver_cleanup(struct device *dev)
*/
if (link->status == DL_STATE_SUPPLIER_UNBIND &&
link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
__device_link_del(&link->kref);
device_link_drop_managed(link);
WRITE_ONCE(link->status, DL_STATE_DORMANT);
}
@ -736,7 +760,7 @@ void device_links_driver_cleanup(struct device *dev)
*
* Return 'false' if there are no probing or active consumers.
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
bool device_links_busy(struct device *dev)
{
@ -746,7 +770,7 @@ bool device_links_busy(struct device *dev)
device_links_write_lock();
list_for_each_entry(link, &dev->links.consumers, s_node) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
if (link->status == DL_STATE_CONSUMER_PROBE
@ -776,7 +800,7 @@ bool device_links_busy(struct device *dev)
* driver to unbind and start over (the consumer will not re-probe as we have
* changed the state of the link already).
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links without the DL_FLAG_MANAGED flag set are ignored.
*/
void device_links_unbind_consumers(struct device *dev)
{
@ -788,7 +812,7 @@ void device_links_unbind_consumers(struct device *dev)
list_for_each_entry(link, &dev->links.consumers, s_node) {
enum device_link_state status;
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
status = link->status;

View File

@ -554,9 +554,16 @@ re_probe:
goto probe_failed;
}
if (device_add_groups(dev, drv->dev_groups)) {
dev_err(dev, "device_add_groups() failed\n");
goto dev_groups_failed;
}
if (test_remove) {
test_remove = false;
device_remove_groups(dev, drv->dev_groups);
if (dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
@ -584,6 +591,11 @@ re_probe:
drv->bus->name, __func__, dev_name(dev), drv->name);
goto done;
dev_groups_failed:
if (dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);
probe_failed:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
@ -1114,6 +1126,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
pm_runtime_put_sync(dev);
device_remove_groups(dev, drv->dev_groups);
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)

View File

@ -164,16 +164,7 @@ static struct class devcd_class = {
static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
void *data, size_t datalen)
{
if (offset > datalen)
return -EINVAL;
if (offset + count > datalen)
count = datalen - offset;
if (count)
memcpy(buffer, ((u8 *)data) + offset, count);
return count;
return memory_read_from_buffer(buffer, count, &offset, data, datalen);
}
static void devcd_freev(void *data)
@ -323,7 +314,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
EXPORT_SYMBOL_GPL(dev_coredumpm);
/**
* dev_coredumpmsg - create device coredump that uses scatterlist as data
* dev_coredumpsg - create device coredump that uses scatterlist as data
* parameter
* @dev: the struct device for the crashed device
* @table: the dump data

View File

@ -99,12 +99,7 @@ void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource);
#endif /* CONFIG_HAS_IOMEM */
/**
* platform_get_irq - get an IRQ for a device
* @dev: platform device
* @num: IRQ number index
*/
int platform_get_irq(struct platform_device *dev, unsigned int num)
static int __platform_get_irq(struct platform_device *dev, unsigned int num)
{
#ifdef CONFIG_SPARC
/* sparc does not have irqs represented as IORESOURCE_IRQ resources */
@ -168,8 +163,58 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
return -ENXIO;
#endif
}
/**
* platform_get_irq - get an IRQ for a device
* @dev: platform device
* @num: IRQ number index
*
* Gets an IRQ for a platform device and prints an error message if finding the
* IRQ fails. Device drivers should check the return value for errors so as to
* not pass a negative integer value to the request_irq() APIs.
*
* Example:
* int irq = platform_get_irq(pdev, 0);
* if (irq < 0)
* return irq;
*
* Return: IRQ number on success, negative error number on failure.
*/
int platform_get_irq(struct platform_device *dev, unsigned int num)
{
int ret;
ret = __platform_get_irq(dev, num);
if (ret < 0 && ret != -EPROBE_DEFER)
dev_err(&dev->dev, "IRQ index %u not found\n", num);
return ret;
}
EXPORT_SYMBOL_GPL(platform_get_irq);
/**
* platform_get_irq_optional - get an optional IRQ for a device
* @dev: platform device
* @num: IRQ number index
*
* Gets an IRQ for a platform device. Device drivers should check the return
* value for errors so as to not pass a negative integer value to the
* request_irq() APIs. This is the same as platform_get_irq(), except that it
* does not print an error message if an IRQ can not be obtained.
*
* Example:
* int irq = platform_get_irq_optional(pdev, 0);
* if (irq < 0)
* return irq;
*
* Return: IRQ number on success, negative error number on failure.
*/
int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
{
return __platform_get_irq(dev, num);
}
EXPORT_SYMBOL_GPL(platform_get_irq_optional);
/**
* platform_irq_count - Count the number of IRQs a platform device uses
* @dev: platform device
@ -180,7 +225,7 @@ int platform_irq_count(struct platform_device *dev)
{
int ret, nr = 0;
while ((ret = platform_get_irq(dev, nr)) >= 0)
while ((ret = __platform_get_irq(dev, nr)) >= 0)
nr++;
if (ret == -EPROBE_DEFER)
@ -233,7 +278,11 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name)
}
r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
return r ? r->start : -ENXIO;
if (r)
return r->start;
dev_err(&dev->dev, "IRQ %s not found\n", name);
return -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname);

View File

@ -1626,7 +1626,7 @@ void pm_runtime_remove(struct device *dev)
* runtime PM references to the device, drop the usage counter of the device
* (as many times as needed).
*
* Links with the DL_FLAG_STATELESS flag set are ignored.
* Links with the DL_FLAG_MANAGED flag unset are ignored.
*
* Since the device is guaranteed to be runtime-active at the point this is
* called, nothing else needs to be done here.
@ -1644,7 +1644,7 @@ void pm_runtime_clean_up_links(struct device *dev)
list_for_each_entry_rcu(link, &dev->links.consumers, s_node,
device_links_read_lock_held()) {
if (link->flags & DL_FLAG_STATELESS)
if (!(link->flags & DL_FLAG_MANAGED))
continue;
while (refcount_dec_not_one(&link->rpm_active))

View File

@ -1011,10 +1011,6 @@ static int scpi_probe(struct platform_device *pdev)
scpi_info->firmware_version));
scpi_info->scpi_ops = &scpi_ops;
ret = devm_device_add_groups(dev, versions_groups);
if (ret)
dev_err(dev, "unable to create sysfs version group\n");
return devm_of_platform_populate(dev);
}
@ -1030,6 +1026,7 @@ static struct platform_driver scpi_driver = {
.driver = {
.name = "scpi_protocol",
.of_match_table = scpi_of_match,
.dev_groups = versions_groups,
},
.probe = scpi_probe,
.remove = scpi_remove,

View File

@ -304,7 +304,7 @@ static int pwm_fan_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ctx->irq = platform_get_irq(pdev, 0);
ctx->irq = platform_get_irq_optional(pdev, 0);
if (ctx->irq == -EPROBE_DEFER)
return ctx->irq;

View File

@ -344,9 +344,22 @@ u32 i2c_acpi_find_bus_speed(struct device *dev)
}
EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
static int i2c_acpi_find_match_adapter(struct device *dev, const void *data)
{
struct i2c_adapter *adapter = i2c_verify_adapter(dev);
if (!adapter)
return 0;
return ACPI_HANDLE(dev) == (acpi_handle)data;
}
struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
{
struct device *dev = bus_find_device_by_acpi_dev(&i2c_bus_type, handle);
struct device *dev;
dev = bus_find_device(&i2c_bus_type, NULL, handle,
i2c_acpi_find_match_adapter);
return dev ? i2c_verify_adapter(dev) : NULL;
}

View File

@ -321,18 +321,9 @@ static const struct file_operations aat2870_reg_fops = {
static void aat2870_init_debugfs(struct aat2870_data *aat2870)
{
aat2870->dentry_root = debugfs_create_dir("aat2870", NULL);
if (!aat2870->dentry_root) {
dev_warn(aat2870->dev,
"Failed to create debugfs root directory\n");
return;
}
aat2870->dentry_reg = debugfs_create_file("regs", 0644,
aat2870->dentry_root,
aat2870, &aat2870_reg_fops);
if (!aat2870->dentry_reg)
dev_warn(aat2870->dev,
"Failed to create debugfs register file\n");
debugfs_create_file("regs", 0644, aat2870->dentry_root, aat2870,
&aat2870_reg_fops);
}
#else

View File

@ -575,58 +575,27 @@ static const struct file_operations ab3100_get_set_reg_fops = {
.llseek = noop_llseek,
};
static struct dentry *ab3100_dir;
static struct dentry *ab3100_reg_file;
static struct ab3100_get_set_reg_priv ab3100_get_priv;
static struct dentry *ab3100_get_reg_file;
static struct ab3100_get_set_reg_priv ab3100_set_priv;
static struct dentry *ab3100_set_reg_file;
static void ab3100_setup_debugfs(struct ab3100 *ab3100)
{
int err;
struct dentry *ab3100_dir;
ab3100_dir = debugfs_create_dir("ab3100", NULL);
if (!ab3100_dir)
goto exit_no_debugfs;
ab3100_reg_file = debugfs_create_file("registers",
S_IRUGO, ab3100_dir, ab3100,
&ab3100_registers_fops);
if (!ab3100_reg_file) {
err = -ENOMEM;
goto exit_destroy_dir;
}
debugfs_create_file("registers", S_IRUGO, ab3100_dir, ab3100,
&ab3100_registers_fops);
ab3100_get_priv.ab3100 = ab3100;
ab3100_get_priv.mode = false;
ab3100_get_reg_file = debugfs_create_file("get_reg",
S_IWUSR, ab3100_dir, &ab3100_get_priv,
&ab3100_get_set_reg_fops);
if (!ab3100_get_reg_file) {
err = -ENOMEM;
goto exit_destroy_reg;
}
debugfs_create_file("get_reg", S_IWUSR, ab3100_dir, &ab3100_get_priv,
&ab3100_get_set_reg_fops);
ab3100_set_priv.ab3100 = ab3100;
ab3100_set_priv.mode = true;
ab3100_set_reg_file = debugfs_create_file("set_reg",
S_IWUSR, ab3100_dir, &ab3100_set_priv,
&ab3100_get_set_reg_fops);
if (!ab3100_set_reg_file) {
err = -ENOMEM;
goto exit_destroy_get_reg;
}
return;
exit_destroy_get_reg:
debugfs_remove(ab3100_get_reg_file);
exit_destroy_reg:
debugfs_remove(ab3100_reg_file);
exit_destroy_dir:
debugfs_remove(ab3100_dir);
exit_no_debugfs:
return;
debugfs_create_file("set_reg", S_IWUSR, ab3100_dir, &ab3100_set_priv,
&ab3100_get_set_reg_fops);
}
#else
static inline void ab3100_setup_debugfs(struct ab3100 *ab3100)

View File

@ -122,17 +122,11 @@ static const struct file_operations ab3100_otp_operations = {
.release = single_release,
};
static int __init ab3100_otp_init_debugfs(struct device *dev,
struct ab3100_otp *otp)
static void __init ab3100_otp_init_debugfs(struct device *dev,
struct ab3100_otp *otp)
{
otp->debugfs = debugfs_create_file("ab3100_otp", S_IFREG | S_IRUGO,
NULL, otp,
&ab3100_otp_operations);
if (!otp->debugfs) {
dev_err(dev, "AB3100 debugfs OTP file registration failed!\n");
return -ENOENT;
}
return 0;
NULL, otp, &ab3100_otp_operations);
}
static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
@ -141,10 +135,9 @@ static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
}
#else
/* Compile this out if debugfs not selected */
static inline int __init ab3100_otp_init_debugfs(struct device *dev,
struct ab3100_otp *otp)
static inline void __init ab3100_otp_init_debugfs(struct device *dev,
struct ab3100_otp *otp)
{
return 0;
}
static inline void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
@ -211,9 +204,7 @@ static int __init ab3100_otp_probe(struct platform_device *pdev)
}
/* debugfs entries */
err = ab3100_otp_init_debugfs(&pdev->dev, otp);
if (err)
goto err;
ab3100_otp_init_debugfs(&pdev->dev, otp);
return 0;

View File

@ -2644,12 +2644,10 @@ static const struct file_operations ab8500_hwreg_fops = {
.owner = THIS_MODULE,
};
static struct dentry *ab8500_dir;
static struct dentry *ab8500_gpadc_dir;
static int ab8500_debug_probe(struct platform_device *plf)
{
struct dentry *file;
struct dentry *ab8500_dir;
struct dentry *ab8500_gpadc_dir;
struct ab8500 *ab8500;
struct resource *res;
@ -2694,47 +2692,22 @@ static int ab8500_debug_probe(struct platform_device *plf)
}
ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
if (!ab8500_dir)
goto err;
ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
ab8500_dir);
if (!ab8500_gpadc_dir)
goto err;
file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
&plf->dev, &ab8500_bank_registers_fops);
if (!file)
goto err;
file = debugfs_create_file("all-banks", S_IRUGO, ab8500_dir,
&plf->dev, &ab8500_all_banks_fops);
if (!file)
goto err;
file = debugfs_create_file("register-bank",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_bank_fops);
if (!file)
goto err;
file = debugfs_create_file("register-address",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_address_fops);
if (!file)
goto err;
file = debugfs_create_file("register-value",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_val_fops);
if (!file)
goto err;
file = debugfs_create_file("irq-subscribe",
(S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
&plf->dev, &ab8500_subscribe_fops);
if (!file)
goto err;
debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
&plf->dev, &ab8500_bank_registers_fops);
debugfs_create_file("all-banks", S_IRUGO, ab8500_dir,
&plf->dev, &ab8500_all_banks_fops);
debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_bank_fops);
debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_address_fops);
debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_val_fops);
debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
if (is_ab8500(ab8500)) {
debug_ranges = ab8500_debug_ranges;
@ -2750,194 +2723,93 @@ static int ab8500_debug_probe(struct platform_device *plf)
num_interrupt_lines = AB8540_NR_IRQS;
}
file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir,
&plf->dev, &ab8500_interrupts_fops);
if (!file)
goto err;
file = debugfs_create_file("irq-unsubscribe",
(S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
&plf->dev, &ab8500_unsubscribe_fops);
if (!file)
goto err;
file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
if (!file)
goto err;
file = debugfs_create_file("all-modem-registers",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_modem_fops);
if (!file)
goto err;
file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_bat_ctrl_fops);
if (!file)
goto err;
file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir,
&plf->dev, &ab8500_gpadc_btemp_ball_fops);
if (!file)
goto err;
file = debugfs_create_file("main_charger_v",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_charger_v_fops);
if (!file)
goto err;
file = debugfs_create_file("acc_detect1",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_acc_detect1_fops);
if (!file)
goto err;
file = debugfs_create_file("acc_detect2",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_acc_detect2_fops);
if (!file)
goto err;
file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_aux1_fops);
if (!file)
goto err;
file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_aux2_fops);
if (!file)
goto err;
file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_bat_v_fops);
if (!file)
goto err;
file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_vbus_v_fops);
if (!file)
goto err;
file = debugfs_create_file("main_charger_c",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_charger_c_fops);
if (!file)
goto err;
file = debugfs_create_file("usb_charger_c",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir,
&plf->dev, &ab8500_gpadc_usb_charger_c_fops);
if (!file)
goto err;
file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_bk_bat_v_fops);
if (!file)
goto err;
file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_die_temp_fops);
if (!file)
goto err;
file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_usb_id_fops);
if (!file)
goto err;
debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev,
&ab8500_interrupts_fops);
debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
&plf->dev, &ab8500_hwreg_fops);
debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_dir, &plf->dev, &ab8500_modem_fops);
debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_bat_ctrl_fops);
debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_btemp_ball_fops);
debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_charger_v_fops);
debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_acc_detect1_fops);
debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_acc_detect2_fops);
debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_aux1_fops);
debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_aux2_fops);
debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_bat_v_fops);
debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_vbus_v_fops);
debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_main_charger_c_fops);
debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_usb_charger_c_fops);
debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_bk_bat_v_fops);
debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_die_temp_fops);
debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_usb_id_fops);
if (is_ab8540(ab8500)) {
file = debugfs_create_file("xtal_temp",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_xtal_temp_fops);
if (!file)
goto err;
file = debugfs_create_file("vbattruemeas",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_vbat_true_meas_fops);
if (!file)
goto err;
file = debugfs_create_file("batctrl_and_ibat",
(S_IRUGO | S_IWUGO),
ab8500_gpadc_dir,
&plf->dev,
&ab8540_gpadc_bat_ctrl_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("vbatmeas_and_ibat",
(S_IRUGO | S_IWUGO),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_vbat_meas_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("vbattruemeas_and_ibat",
(S_IRUGO | S_IWUGO),
ab8500_gpadc_dir,
&plf->dev,
&ab8540_gpadc_vbat_true_meas_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("battemp_and_ibat",
(S_IRUGO | S_IWUGO),
ab8500_gpadc_dir,
&plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("otp_calib",
(S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir,
&plf->dev, &ab8540_gpadc_otp_calib_fops);
if (!file)
goto err;
debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_xtal_temp_fops);
debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_vbat_true_meas_fops);
debugfs_create_file("batctrl_and_ibat", (S_IRUGO | S_IWUGO),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_bat_ctrl_and_ibat_fops);
debugfs_create_file("vbatmeas_and_ibat", (S_IRUGO | S_IWUGO),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_vbat_meas_and_ibat_fops);
debugfs_create_file("vbattruemeas_and_ibat", (S_IRUGO | S_IWUGO),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_vbat_true_meas_and_ibat_fops);
debugfs_create_file("battemp_and_ibat", (S_IRUGO | S_IWUGO),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_bat_temp_and_ibat_fops);
debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8540_gpadc_otp_calib_fops);
}
file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_avg_sample_fops);
if (!file)
goto err;
file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_trig_edge_fops);
if (!file)
goto err;
file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_trig_timer_fops);
if (!file)
goto err;
file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_conv_type_fops);
if (!file)
goto err;
debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_avg_sample_fops);
debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_trig_edge_fops);
debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_trig_timer_fops);
debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP),
ab8500_gpadc_dir, &plf->dev,
&ab8500_gpadc_conv_type_fops);
return 0;
err:
debugfs_remove_recursive(ab8500_dir);
dev_err(&plf->dev, "failed to create debugfs entries.\n");
return -ENOMEM;
}
static struct platform_driver ab8500_debug_driver = {

View File

@ -502,6 +502,17 @@ static DEVICE_ATTR_RO(dock);
static DEVICE_ATTR_RO(tablet);
static DEVICE_ATTR_RW(postcode);
static struct attribute *hp_wmi_attrs[] = {
&dev_attr_display.attr,
&dev_attr_hddtemp.attr,
&dev_attr_als.attr,
&dev_attr_dock.attr,
&dev_attr_tablet.attr,
&dev_attr_postcode.attr,
NULL,
};
ATTRIBUTE_GROUPS(hp_wmi);
static void hp_wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
@ -678,16 +689,6 @@ static void hp_wmi_input_destroy(void)
input_unregister_device(hp_wmi_input_dev);
}
static void cleanup_sysfs(struct platform_device *device)
{
device_remove_file(&device->dev, &dev_attr_display);
device_remove_file(&device->dev, &dev_attr_hddtemp);
device_remove_file(&device->dev, &dev_attr_als);
device_remove_file(&device->dev, &dev_attr_dock);
device_remove_file(&device->dev, &dev_attr_tablet);
device_remove_file(&device->dev, &dev_attr_postcode);
}
static int __init hp_wmi_rfkill_setup(struct platform_device *device)
{
int err, wireless;
@ -858,8 +859,6 @@ fail:
static int __init hp_wmi_bios_setup(struct platform_device *device)
{
int err;
/* clear detected rfkill devices */
wifi_rfkill = NULL;
bluetooth_rfkill = NULL;
@ -869,35 +868,12 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
if (hp_wmi_rfkill_setup(device))
hp_wmi_rfkill2_setup(device);
err = device_create_file(&device->dev, &dev_attr_display);
if (err)
goto add_sysfs_error;
err = device_create_file(&device->dev, &dev_attr_hddtemp);
if (err)
goto add_sysfs_error;
err = device_create_file(&device->dev, &dev_attr_als);
if (err)
goto add_sysfs_error;
err = device_create_file(&device->dev, &dev_attr_dock);
if (err)
goto add_sysfs_error;
err = device_create_file(&device->dev, &dev_attr_tablet);
if (err)
goto add_sysfs_error;
err = device_create_file(&device->dev, &dev_attr_postcode);
if (err)
goto add_sysfs_error;
return 0;
add_sysfs_error:
cleanup_sysfs(device);
return err;
}
static int __exit hp_wmi_bios_remove(struct platform_device *device)
{
int i;
cleanup_sysfs(device);
for (i = 0; i < rfkill2_count; i++) {
rfkill_unregister(rfkill2[i].rfkill);
@ -966,6 +942,7 @@ static struct platform_driver hp_wmi_driver = {
.driver = {
.name = "hp-wmi",
.pm = &hp_wmi_pm_ops,
.dev_groups = hp_wmi_groups,
},
.remove = __exit_p(hp_wmi_bios_remove),
};

View File

@ -71,6 +71,13 @@ static ssize_t reg_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(reg_br, 0664, reg_show, reg_store);
static DEVICE_ATTR(reg_or, 0664, reg_show, reg_store);
static struct attribute *uio_fsl_elbc_gpcm_attrs[] = {
&dev_attr_reg_br.attr,
&dev_attr_reg_or.attr,
NULL,
};
ATTRIBUTE_GROUPS(uio_fsl_elbc_gpcm);
static ssize_t reg_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@ -411,25 +418,12 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev)
/* store private data */
platform_set_drvdata(pdev, info);
/* create sysfs files */
ret = device_create_file(priv->dev, &dev_attr_reg_br);
if (ret)
goto out_err3;
ret = device_create_file(priv->dev, &dev_attr_reg_or);
if (ret)
goto out_err4;
dev_info(priv->dev,
"eLBC/GPCM device (%s) at 0x%llx, bank %d, irq=%d\n",
priv->name, (unsigned long long)res.start, priv->bank,
irq != NO_IRQ ? irq : -1);
return 0;
out_err4:
device_remove_file(priv->dev, &dev_attr_reg_br);
out_err3:
platform_set_drvdata(pdev, NULL);
uio_unregister_device(info);
out_err2:
if (priv->shutdown)
priv->shutdown(info, true);
@ -448,8 +442,6 @@ static int uio_fsl_elbc_gpcm_remove(struct platform_device *pdev)
struct uio_info *info = platform_get_drvdata(pdev);
struct fsl_elbc_gpcm *priv = info->priv;
device_remove_file(priv->dev, &dev_attr_reg_or);
device_remove_file(priv->dev, &dev_attr_reg_br);
platform_set_drvdata(pdev, NULL);
uio_unregister_device(info);
if (priv->shutdown)
@ -474,6 +466,7 @@ static struct platform_driver uio_fsl_elbc_gpcm_driver = {
.driver = {
.name = "fsl,elbc-gpcm-uio",
.of_match_table = uio_fsl_elbc_gpcm_match,
.dev_groups = uio_fsl_elbc_gpcm_groups,
},
.probe = uio_fsl_elbc_gpcm_probe,
.remove = uio_fsl_elbc_gpcm_remove,

View File

@ -1271,6 +1271,14 @@ static ssize_t sm501fb_debug_show_pnl(struct device *dev,
static DEVICE_ATTR(fbregs_pnl, 0444, sm501fb_debug_show_pnl, NULL);
static struct attribute *sm501fb_attrs[] = {
&dev_attr_crt_src.attr,
&dev_attr_fbregs_pnl.attr,
&dev_attr_fbregs_crt.attr,
NULL,
};
ATTRIBUTE_GROUPS(sm501fb);
/* acceleration operations */
static int sm501fb_sync(struct fb_info *info)
{
@ -2011,33 +2019,9 @@ static int sm501fb_probe(struct platform_device *pdev)
goto err_started_crt;
}
/* create device files */
ret = device_create_file(dev, &dev_attr_crt_src);
if (ret)
goto err_started_panel;
ret = device_create_file(dev, &dev_attr_fbregs_pnl);
if (ret)
goto err_attached_crtsrc_file;
ret = device_create_file(dev, &dev_attr_fbregs_crt);
if (ret)
goto err_attached_pnlregs_file;
/* we registered, return ok */
return 0;
err_attached_pnlregs_file:
device_remove_file(dev, &dev_attr_fbregs_pnl);
err_attached_crtsrc_file:
device_remove_file(dev, &dev_attr_crt_src);
err_started_panel:
unregister_framebuffer(info->fb[HEAD_PANEL]);
sm501_free_init_fb(info, HEAD_PANEL);
err_started_crt:
unregister_framebuffer(info->fb[HEAD_CRT]);
sm501_free_init_fb(info, HEAD_CRT);
@ -2067,10 +2051,6 @@ static int sm501fb_remove(struct platform_device *pdev)
struct fb_info *fbinfo_crt = info->fb[0];
struct fb_info *fbinfo_pnl = info->fb[1];
device_remove_file(&pdev->dev, &dev_attr_fbregs_crt);
device_remove_file(&pdev->dev, &dev_attr_fbregs_pnl);
device_remove_file(&pdev->dev, &dev_attr_crt_src);
sm501_free_init_fb(info, HEAD_CRT);
sm501_free_init_fb(info, HEAD_PANEL);
@ -2234,6 +2214,7 @@ static struct platform_driver sm501fb_driver = {
.resume = sm501fb_resume,
.driver = {
.name = "sm501-fb",
.dev_groups = sm501fb_groups,
},
};

View File

@ -164,6 +164,15 @@ static ssize_t fastpllclk_store(struct device *dev, struct device_attribute *att
static DEVICE_ATTR_RW(fastpllclk);
static struct attribute *w100fb_attrs[] = {
&dev_attr_fastpllclk.attr,
&dev_attr_reg_read.attr,
&dev_attr_reg_write.attr,
&dev_attr_flip.attr,
NULL,
};
ATTRIBUTE_GROUPS(w100fb);
/*
* Some touchscreens need hsync information from the video driver to
* function correctly. We export it here.
@ -752,14 +761,6 @@ int w100fb_probe(struct platform_device *pdev)
goto out;
}
err = device_create_file(&pdev->dev, &dev_attr_fastpllclk);
err |= device_create_file(&pdev->dev, &dev_attr_reg_read);
err |= device_create_file(&pdev->dev, &dev_attr_reg_write);
err |= device_create_file(&pdev->dev, &dev_attr_flip);
if (err != 0)
fb_warn(info, "failed to register attributes (%d)\n", err);
fb_info(info, "%s frame buffer device\n", info->fix.id);
return 0;
out:
@ -784,11 +785,6 @@ static int w100fb_remove(struct platform_device *pdev)
struct fb_info *info = platform_get_drvdata(pdev);
struct w100fb_par *par=info->par;
device_remove_file(&pdev->dev, &dev_attr_fastpllclk);
device_remove_file(&pdev->dev, &dev_attr_reg_read);
device_remove_file(&pdev->dev, &dev_attr_reg_write);
device_remove_file(&pdev->dev, &dev_attr_flip);
unregister_framebuffer(info);
vfree(par->saved_intmem);
@ -1625,6 +1621,7 @@ static struct platform_driver w100fb_driver = {
.resume = w100fb_resume,
.driver = {
.name = "w100fb",
.dev_groups = w100fb_groups,
},
};

View File

@ -176,6 +176,12 @@ static ssize_t contrast_store(struct device *dev,
static DEVICE_ATTR_RW(contrast);
static struct attribute *wm8505fb_attrs[] = {
&dev_attr_contrast.attr,
NULL,
};
ATTRIBUTE_GROUPS(wm8505fb);
static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
@ -361,10 +367,6 @@ static int wm8505fb_probe(struct platform_device *pdev)
return ret;
}
ret = device_create_file(&pdev->dev, &dev_attr_contrast);
if (ret < 0)
fb_warn(&fbi->fb, "failed to register attributes (%d)\n", ret);
fb_info(&fbi->fb, "%s frame buffer at 0x%lx-0x%lx\n",
fbi->fb.fix.id, fbi->fb.fix.smem_start,
fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1);
@ -376,8 +378,6 @@ static int wm8505fb_remove(struct platform_device *pdev)
{
struct wm8505fb_info *fbi = platform_get_drvdata(pdev);
device_remove_file(&pdev->dev, &dev_attr_contrast);
unregister_framebuffer(&fbi->fb);
writel(0, fbi->regbase);
@ -399,6 +399,7 @@ static struct platform_driver wm8505fb_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = wmt_dt_ids,
.dev_groups = wm8505fb_groups,
},
};

View File

@ -137,6 +137,9 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
if (kn_from == kn_to)
return strlcpy(buf, "/", buflen);
if (!buf)
return -EINVAL;
common = kernfs_common_ancestor(kn_from, kn_to);
if (WARN_ON(!common))
return -EINVAL;
@ -144,8 +147,7 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
depth_to = kernfs_depth(common, kn_to);
depth_from = kernfs_depth(common, kn_from);
if (buf)
buf[0] = '\0';
buf[0] = '\0';
for (i = 0; i < depth_from; i++)
len += strlcpy(buf + len, parent_str,
@ -430,7 +432,6 @@ struct kernfs_node *kernfs_get_active(struct kernfs_node *kn)
*/
void kernfs_put_active(struct kernfs_node *kn)
{
struct kernfs_root *root = kernfs_root(kn);
int v;
if (unlikely(!kn))
@ -442,7 +443,7 @@ void kernfs_put_active(struct kernfs_node *kn)
if (likely(v != KN_DEACTIVATED_BIAS))
return;
wake_up_all(&root->deactivate_waitq);
wake_up_all(&kernfs_root(kn)->deactivate_waitq);
}
/**

View File

@ -6,6 +6,9 @@
* Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
*/
#ifndef _LINUX_CONTAINER_H
#define _LINUX_CONTAINER_H
#include <linux/device.h>
/* drivers/base/power/container.c */
@ -20,3 +23,5 @@ static inline struct container_dev *to_container_dev(struct device *dev)
{
return container_of(dev, struct container_dev, dev);
}
#endif /* _LINUX_CONTAINER_H */

View File

@ -229,6 +229,8 @@ static inline struct device *bus_find_device_by_devt(struct bus_type *bus,
/**
* bus_find_next_device - Find the next device after a given device in a
* given bus.
* @bus: bus type
* @cur: device to begin the search with.
*/
static inline struct device *
bus_find_next_device(struct bus_type *bus,struct device *cur)
@ -346,6 +348,8 @@ enum probe_type {
* @resume: Called to bring a device from sleep mode.
* @groups: Default attributes that get created by the driver core
* automatically.
* @dev_groups: Additional attributes attached to device instance once the
* it is bound to the driver.
* @pm: Power management operations of the device which matched
* this driver.
* @coredump: Called when sysfs entry is written to. The device driver
@ -380,6 +384,7 @@ struct device_driver {
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct attribute_group **dev_groups;
const struct dev_pm_ops *pm;
void (*coredump) (struct device *dev);
@ -429,7 +434,7 @@ struct device *driver_find_device(struct device_driver *drv,
/**
* driver_find_device_by_name - device iterator for locating a particular device
* of a specific name.
* @driver: the driver we're iterating
* @drv: the driver we're iterating
* @name: name of the device to match
*/
static inline struct device *driver_find_device_by_name(struct device_driver *drv,
@ -441,7 +446,7 @@ static inline struct device *driver_find_device_by_name(struct device_driver *dr
/**
* driver_find_device_by_of_node- device iterator for locating a particular device
* by of_node pointer.
* @driver: the driver we're iterating
* @drv: the driver we're iterating
* @np: of_node pointer to match.
*/
static inline struct device *
@ -454,7 +459,7 @@ driver_find_device_by_of_node(struct device_driver *drv,
/**
* driver_find_device_by_fwnode- device iterator for locating a particular device
* by fwnode pointer.
* @driver: the driver we're iterating
* @drv: the driver we're iterating
* @fwnode: fwnode pointer to match.
*/
static inline struct device *
@ -467,7 +472,7 @@ driver_find_device_by_fwnode(struct device_driver *drv,
/**
* driver_find_device_by_devt- device iterator for locating a particular device
* by devt.
* @driver: the driver we're iterating
* @drv: the driver we're iterating
* @devt: devt pointer to match.
*/
static inline struct device *driver_find_device_by_devt(struct device_driver *drv,
@ -486,7 +491,7 @@ static inline struct device *driver_find_next_device(struct device_driver *drv,
/**
* driver_find_device_by_acpi_dev : device iterator for locating a particular
* device matching the ACPI_COMPANION device.
* @driver: the driver we're iterating
* @drv: the driver we're iterating
* @adev: ACPI_COMPANION device to match.
*/
static inline struct device *
@ -1064,12 +1069,13 @@ enum device_link_state {
/*
* Device link flags.
*
* STATELESS: The core won't track the presence of supplier/consumer drivers.
* STATELESS: The core will not remove this link automatically.
* AUTOREMOVE_CONSUMER: Remove the link automatically on consumer driver unbind.
* PM_RUNTIME: If set, the runtime PM framework will use this link.
* RPM_ACTIVE: Run pm_runtime_get_sync() on the supplier during link creation.
* 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).
*/
#define DL_FLAG_STATELESS BIT(0)
#define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1)
@ -1077,6 +1083,7 @@ enum device_link_state {
#define DL_FLAG_RPM_ACTIVE BIT(3)
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
#define DL_FLAG_AUTOPROBE_CONSUMER BIT(5)
#define DL_FLAG_MANAGED BIT(6)
/**
* struct device_link - Device link representation.

View File

@ -136,7 +136,6 @@ struct aat2870_data {
/* for debugfs */
struct dentry *dentry_root;
struct dentry *dentry_reg;
};
struct aat2870_subdev_info {

View File

@ -58,6 +58,7 @@ extern void __iomem *
devm_platform_ioremap_resource(struct platform_device *pdev,
unsigned int index);
extern int platform_get_irq(struct platform_device *, unsigned int);
extern int platform_get_irq_optional(struct platform_device *, unsigned int);
extern int platform_irq_count(struct platform_device *);
extern struct resource *platform_get_resource_byname(struct platform_device *,
unsigned int,

View File

@ -196,6 +196,12 @@ struct bin_attribute {
.size = _size, \
}
#define __BIN_ATTR_WO(_name) { \
.attr = { .name = __stringify(_name), .mode = 0200 }, \
.store = _name##_store, \
.size = _size, \
}
#define __BIN_ATTR_RW(_name, _size) \
__BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size)
@ -208,6 +214,9 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read, \
#define BIN_ATTR_RO(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size)
#define BIN_ATTR_WO(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_WO(_name, _size)
#define BIN_ATTR_RW(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)

View File

@ -0,0 +1,102 @@
// SPDX-License-Identifier: GPL-2.0
/// Remove dev_err() messages after platform_get_irq*() failures
//
// Confidence: Medium
// Options: --include-headers
virtual patch
virtual context
virtual org
virtual report
@depends on context@
expression ret;
struct platform_device *E;
@@
ret =
(
platform_get_irq
|
platform_get_irq_byname
)(E, ...);
if ( \( ret < 0 \| ret <= 0 \) )
{
(
if (ret != -EPROBE_DEFER)
{ ...
*dev_err(...);
... }
|
...
*dev_err(...);
)
...
}
@depends on patch@
expression ret;
struct platform_device *E;
@@
ret =
(
platform_get_irq
|
platform_get_irq_byname
)(E, ...);
if ( \( ret < 0 \| ret <= 0 \) )
{
(
-if (ret != -EPROBE_DEFER)
-{ ...
-dev_err(...);
-... }
|
...
-dev_err(...);
)
...
}
@r depends on org || report@
position p1;
expression ret;
struct platform_device *E;
@@
ret =
(
platform_get_irq
|
platform_get_irq_byname
)(E, ...);
if ( \( ret < 0 \| ret <= 0 \) )
{
(
if (ret != -EPROBE_DEFER)
{ ...
dev_err@p1(...);
... }
|
...
dev_err@p1(...);
)
...
}
@script:python depends on org@
p1 << r.p1;
@@
cocci.print_main(p1)
@script:python depends on report@
p1 << r.p1;
@@
msg = "line %s is redundant because platform_get_irq() already prints an error" % (p1[0].line)
coccilib.report.print_report(p1[0],msg)