aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/driver-api/driver-model/driver.rst32
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/dd.c28
-rw-r--r--drivers/base/firmware_loader/fallback.c3
-rw-r--r--drivers/base/firmware_loader/fallback_table.c2
-rw-r--r--drivers/base/firmware_loader/main.c3
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/base/soc.c2
-rw-r--r--fs/debugfs/internal.h2
-rw-r--r--fs/kernfs/file.c2
-rw-r--r--include/linux/firmware.h1
-rw-r--r--lib/test_firmware.c26
12 files changed, 54 insertions, 53 deletions
diff --git a/Documentation/driver-api/driver-model/driver.rst b/Documentation/driver-api/driver-model/driver.rst
index 63887b813005..7d5040f6a3d8 100644
--- a/Documentation/driver-api/driver-model/driver.rst
+++ b/Documentation/driver-api/driver-model/driver.rst
@@ -4,7 +4,6 @@ Device Drivers
See the kerneldoc for the struct device_driver.
-
Allocation
~~~~~~~~~~
@@ -167,9 +166,26 @@ the driver to that device.
A driver's probe() may return a negative errno value to indicate that
the driver did not bind to this device, in which case it should have
-released all resources it allocated::
+released all resources it allocated.
+
+Optionally, probe() may return -EPROBE_DEFER if the driver depends on
+resources that are not yet available (e.g., supplied by a driver that
+hasn't initialized yet). The driver core will put the device onto the
+deferred probe list and will try to call it again later. If a driver
+must defer, it should return -EPROBE_DEFER as early as possible to
+reduce the amount of time spent on setup work that will need to be
+unwound and reexecuted at a later time.
+
+.. warning::
+ -EPROBE_DEFER must not be returned if probe() has already created
+ child devices, even if those child devices are removed again
+ in a cleanup path. If -EPROBE_DEFER is returned after a child
+ device has been registered, it may result in an infinite loop of
+ .probe() calls to the same driver.
+
+::
- void (*sync_state)(struct device *dev);
+ void (*sync_state) (struct device *dev);
sync_state is called only once for a device. It's called when all the consumer
devices of the device have successfully probed. The list of consumers of the
@@ -212,6 +228,8 @@ over management of devices from the bootloader, the usage of sync_state() is
not restricted to that. Use it whenever it makes sense to take an action after
all the consumers of a device have probed::
+::
+
int (*remove) (struct device *dev);
remove is called to unbind a driver from a device. This may be
@@ -224,11 +242,15 @@ not. It should free any resources allocated specifically for the
device; i.e. anything in the device's driver_data field.
If the device is still present, it should quiesce the device and place
-it into a supported low-power state::
+it into a supported low-power state.
+
+::
int (*suspend) (struct device *dev, pm_message_t state);
-suspend is called to put the device in a low power state::
+suspend is called to put the device in a low power state.
+
+::
int (*resume) (struct device *dev);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 073045cb214e..c9045521596f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2345,7 +2345,7 @@ static int device_private_init(struct device *dev)
return 0;
}
-static u32 fw_devlink_flags;
+static u32 fw_devlink_flags = DL_FLAG_SYNC_STATE_ONLY;
static int __init fw_devlink_setup(char *arg)
{
if (!arg)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 94037be7f5d7..48ca81cb8ebc 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -254,12 +254,12 @@ __setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
int driver_deferred_probe_check_state(struct device *dev)
{
if (!IS_ENABLED(CONFIG_MODULES) && initcalls_done) {
- dev_warn(dev, "ignoring dependency for device, assuming no driver");
+ dev_warn(dev, "ignoring dependency for device, assuming no driver\n");
return -ENODEV;
}
if (!driver_deferred_probe_timeout && initcalls_done) {
- dev_warn(dev, "deferred probe timeout, ignoring dependency");
+ dev_warn(dev, "deferred probe timeout, ignoring dependency\n");
return -ETIMEDOUT;
}
@@ -275,7 +275,7 @@ static void deferred_probe_timeout_work_func(struct work_struct *work)
flush_work(&deferred_probe_work);
list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe)
- dev_info(private->device, "deferred probe pending");
+ dev_info(private->device, "deferred probe pending\n");
wake_up(&probe_timeout_waitqueue);
}
static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);
@@ -336,7 +336,7 @@ bool device_is_bound(struct device *dev)
static void driver_bound(struct device *dev)
{
if (device_is_bound(dev)) {
- printk(KERN_WARNING "%s: device %s already bound\n",
+ pr_warn("%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
}
@@ -505,8 +505,8 @@ re_probe:
}
if (driver_sysfs_add(dev)) {
- printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
- __func__, dev_name(dev));
+ pr_err("%s: driver_sysfs_add(%s) failed\n",
+ __func__, dev_name(dev));
goto probe_failed;
}
@@ -597,9 +597,8 @@ pinctrl_bind_failed:
break;
default:
/* driver matched but the probe failed */
- printk(KERN_WARNING
- "%s: probe of %s failed with error %d\n",
- drv->name, dev_name(dev), ret);
+ pr_warn("%s: probe of %s failed with error %d\n",
+ drv->name, dev_name(dev), ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
@@ -624,8 +623,8 @@ static int really_probe_debug(struct device *dev, struct device_driver *drv)
ret = really_probe(dev, drv);
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
- printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n",
- dev_name(dev), ret, (s64) ktime_to_us(delta));
+ pr_debug("probe of %s returned %d after %lld usecs\n",
+ dev_name(dev), ret, (s64) ktime_to_us(delta));
return ret;
}
@@ -713,8 +712,7 @@ static inline bool cmdline_requested_async_probing(const char *drv_name)
static int __init save_async_options(char *buf)
{
if (strlen(buf) >= ASYNC_DRV_NAMES_MAX_LEN)
- printk(KERN_WARNING
- "Too long list of driver names for 'driver_async_probe'!\n");
+ pr_warn("Too long list of driver names for 'driver_async_probe'!\n");
strlcpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN);
return 0;
@@ -789,7 +787,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
dev_dbg(dev, "Device match requests probe deferral\n");
driver_deferred_probe_add(dev);
} else if (ret < 0) {
- dev_dbg(dev, "Bus failed to match device: %d", ret);
+ dev_dbg(dev, "Bus failed to match device: %d\n", ret);
return ret;
} /* ret > 0 means positive match */
@@ -1022,7 +1020,7 @@ static int __driver_attach(struct device *dev, void *data)
dev_dbg(dev, "Device match requests probe deferral\n");
driver_deferred_probe_add(dev);
} else if (ret < 0) {
- dev_dbg(dev, "Bus failed to match device: %d", ret);
+ dev_dbg(dev, "Bus failed to match device: %d\n", ret);
return ret;
} /* ret > 0 means positive match */
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 1e9c96e3ed63..d9ac7296205e 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -9,6 +9,7 @@
#include <linux/umh.h>
#include <linux/sysctl.h>
#include <linux/vmalloc.h>
+#include <linux/module.h>
#include "fallback.h"
#include "firmware.h"
@@ -17,6 +18,8 @@
* firmware fallback mechanism
*/
+MODULE_IMPORT_NS(FIRMWARE_LOADER_PRIVATE);
+
extern struct firmware_fallback_config fw_fallback_config;
/* These getters are vetted to use int properly */
diff --git a/drivers/base/firmware_loader/fallback_table.c b/drivers/base/firmware_loader/fallback_table.c
index a182e318bd09..46a731dede6f 100644
--- a/drivers/base/firmware_loader/fallback_table.c
+++ b/drivers/base/firmware_loader/fallback_table.c
@@ -21,7 +21,7 @@ struct firmware_fallback_config fw_fallback_config = {
.loading_timeout = 60,
.old_timeout = 60,
};
-EXPORT_SYMBOL_GPL(fw_fallback_config);
+EXPORT_SYMBOL_NS_GPL(fw_fallback_config, FIRMWARE_LOADER_PRIVATE);
#ifdef CONFIG_SYSCTL
struct ctl_table firmware_config_table[] = {
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 76f79913916d..5296aaca35cf 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -548,9 +548,6 @@ static void firmware_free_data(const struct firmware *fw)
static void fw_set_page_data(struct fw_priv *fw_priv, struct firmware *fw)
{
fw->priv = fw_priv;
-#ifdef CONFIG_FW_LOADER_USER_HELPER
- fw->pages = fw_priv->pages;
-#endif
fw->size = fw_priv->size;
fw->data = fw_priv->data;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index b27d0f6c18c9..4ed3dc38f45c 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -670,7 +670,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
struct platform_device *platform_device_register_full(
const struct platform_device_info *pdevinfo)
{
- int ret = -ENOMEM;
+ int ret;
struct platform_device *pdev;
pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id);
@@ -851,6 +851,8 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
/* temporary section violation during probe() */
drv->probe = probe;
retval = code = __platform_driver_register(drv, module);
+ if (retval)
+ return retval;
/*
* Fixup that section violation, being paranoid about code scanning
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 4af11a423475..a5bae551167d 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -46,7 +46,7 @@ static umode_t soc_attribute_mode(struct kobject *kobj,
struct attribute *attr,
int index)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev = kobj_to_dev(kobj);
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
if ((attr == &dev_attr_machine.attr)
diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h
index f0d73d86cc1a..034e6973cead 100644
--- a/fs/debugfs/internal.h
+++ b/fs/debugfs/internal.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* internal.h - declarations internal to debugfs
*
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 34366db3620d..fd6ddfe4cd94 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -1010,7 +1010,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
#ifdef CONFIG_DEBUG_LOCK_ALLOC
if (key) {
- lockdep_init_map(&kn->dep_map, "kn->count", key, 0);
+ lockdep_init_map(&kn->dep_map, "kn->active", key, 0);
kn->flags |= KERNFS_LOCKDEP;
}
#endif
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 4bbd0afd91b7..cb3e2c06ed8a 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -12,7 +12,6 @@
struct firmware {
size_t size;
const u8 *data;
- struct page **pages;
/* firmware loader private fields */
void *priv;
diff --git a/lib/test_firmware.c b/lib/test_firmware.c
index 0c7fbcf07ac5..9fee2b93a8d1 100644
--- a/lib/test_firmware.c
+++ b/lib/test_firmware.c
@@ -310,27 +310,13 @@ static int test_dev_config_update_bool(const char *buf, size_t size,
return ret;
}
-static ssize_t
-test_dev_config_show_bool(char *buf,
- bool config)
+static ssize_t test_dev_config_show_bool(char *buf, bool val)
{
- bool val;
-
- mutex_lock(&test_fw_mutex);
- val = config;
- mutex_unlock(&test_fw_mutex);
-
return snprintf(buf, PAGE_SIZE, "%d\n", val);
}
-static ssize_t test_dev_config_show_int(char *buf, int cfg)
+static ssize_t test_dev_config_show_int(char *buf, int val)
{
- int val;
-
- mutex_lock(&test_fw_mutex);
- val = cfg;
- mutex_unlock(&test_fw_mutex);
-
return snprintf(buf, PAGE_SIZE, "%d\n", val);
}
@@ -354,14 +340,8 @@ static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
return size;
}
-static ssize_t test_dev_config_show_u8(char *buf, u8 cfg)
+static ssize_t test_dev_config_show_u8(char *buf, u8 val)
{
- u8 val;
-
- mutex_lock(&test_fw_mutex);
- val = cfg;
- mutex_unlock(&test_fw_mutex);
-
return snprintf(buf, PAGE_SIZE, "%u\n", val);
}