summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/sysfs.txt5
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c3
-rw-r--r--arch/tile/kernel/sysfs.c11
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c5
-rw-r--r--drivers/base/base.h3
-rw-r--r--drivers/base/core.c49
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/dd.c8
-rw-r--r--drivers/base/devres.c4
-rw-r--r--drivers/base/firmware_class.c2
-rw-r--r--drivers/cpufreq/cpufreq.c8
-rw-r--r--drivers/net/rionet.c4
-rw-r--r--include/linux/device.h2
-rw-r--r--kernel/cpu.c16
-rwxr-xr-xtools/testing/selftests/firmware/fw_filesystem.sh25
-rwxr-xr-xtools/testing/selftests/firmware/fw_userhelper.sh12
16 files changed, 118 insertions, 41 deletions
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index b35a64b82f9e8..9494afb9476a4 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -212,7 +212,10 @@ Other notes:
- show() methods should return the number of bytes printed into the
buffer. This is the return value of scnprintf().
-- show() should always use scnprintf().
+- show() must not use snprintf() when formatting the value to be
+ returned to user space. If you can guarantee that an overflow
+ will never happen you can use sprintf() otherwise you must use
+ scnprintf().
- store() should return the number of bytes used from the buffer. If the
entire buffer has been used, just return the count argument.
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index 0a47bd3e7bee1..4ca78ed71ad2c 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -355,13 +355,12 @@ static int sq_dev_add(struct device *dev, struct subsys_interface *sif)
return error;
}
-static int sq_dev_remove(struct device *dev, struct subsys_interface *sif)
+static void sq_dev_remove(struct device *dev, struct subsys_interface *sif)
{
unsigned int cpu = dev->id;
struct kobject *kobj = sq_kobject[cpu];
kobject_put(kobj);
- return 0;
}
static struct subsys_interface sq_interface = {
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index a3ed12f8f83bf..825867c538530 100644
--- a/arch/tile/kernel/sysfs.c
+++ b/arch/tile/kernel/sysfs.c
@@ -198,16 +198,13 @@ static int hv_stats_device_add(struct device *dev, struct subsys_interface *sif)
return err;
}
-static int hv_stats_device_remove(struct device *dev,
- struct subsys_interface *sif)
+static void hv_stats_device_remove(struct device *dev,
+ struct subsys_interface *sif)
{
int cpu = dev->id;
- if (!cpu_online(cpu))
- return 0;
-
- sysfs_remove_file(&dev->kobj, &dev_attr_hv_stats.attr);
- return 0;
+ if (cpu_online(cpu))
+ sysfs_remove_file(&dev->kobj, &dev_attr_hv_stats.attr);
}
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 6236a54a63f44..3c986390058a5 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -377,17 +377,16 @@ static int mc_device_add(struct device *dev, struct subsys_interface *sif)
return err;
}
-static int mc_device_remove(struct device *dev, struct subsys_interface *sif)
+static void mc_device_remove(struct device *dev, struct subsys_interface *sif)
{
int cpu = dev->id;
if (!cpu_online(cpu))
- return 0;
+ return;
pr_debug("CPU%d removed\n", cpu);
microcode_fini_cpu(cpu);
sysfs_remove_group(&dev->kobj, &mc_attr_group);
- return 0;
}
static struct subsys_interface mc_cpu_interface = {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index fd3347d9f1535..1782f3aa386e6 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -63,7 +63,7 @@ struct driver_private {
* binding of drivers which were unable to get all the resources needed by
* the device; typically because it depends on another driver getting
* probed first.
- * @device - pointer back to the struct class that this structure is
+ * @device - pointer back to the struct device that this structure is
* associated with.
*
* Nothing outside of the driver core should ever touch these fields.
@@ -134,6 +134,7 @@ extern int devres_release_all(struct device *dev);
/* /sys/devices directory */
extern struct kset *devices_kset;
+extern void devices_kset_move_last(struct device *dev);
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
extern void module_add_driver(struct module *mod, struct device_driver *drv);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index dafae6d2f7ace..fc5a558f62f97 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -534,6 +534,52 @@ static DEVICE_ATTR_RO(dev);
struct kset *devices_kset;
/**
+ * devices_kset_move_before - Move device in the devices_kset's list.
+ * @deva: Device to move.
+ * @devb: Device @deva should come before.
+ */
+static void devices_kset_move_before(struct device *deva, struct device *devb)
+{
+ if (!devices_kset)
+ return;
+ pr_debug("devices_kset: Moving %s before %s\n",
+ dev_name(deva), dev_name(devb));
+ spin_lock(&devices_kset->list_lock);
+ list_move_tail(&deva->kobj.entry, &devb->kobj.entry);
+ spin_unlock(&devices_kset->list_lock);
+}
+
+/**
+ * devices_kset_move_after - Move device in the devices_kset's list.
+ * @deva: Device to move
+ * @devb: Device @deva should come after.
+ */
+static void devices_kset_move_after(struct device *deva, struct device *devb)
+{
+ if (!devices_kset)
+ return;
+ pr_debug("devices_kset: Moving %s after %s\n",
+ dev_name(deva), dev_name(devb));
+ spin_lock(&devices_kset->list_lock);
+ list_move(&deva->kobj.entry, &devb->kobj.entry);
+ spin_unlock(&devices_kset->list_lock);
+}
+
+/**
+ * devices_kset_move_last - move the device to the end of devices_kset's list.
+ * @dev: device to move
+ */
+void devices_kset_move_last(struct device *dev)
+{
+ if (!devices_kset)
+ return;
+ pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev));
+ spin_lock(&devices_kset->list_lock);
+ list_move_tail(&dev->kobj.entry, &devices_kset->list);
+ spin_unlock(&devices_kset->list_lock);
+}
+
+/**
* device_create_file - create sysfs attribute file for device.
* @dev: device.
* @attr: device attribute descriptor.
@@ -1923,12 +1969,15 @@ int device_move(struct device *dev, struct device *new_parent,
break;
case DPM_ORDER_DEV_AFTER_PARENT:
device_pm_move_after(dev, new_parent);
+ devices_kset_move_after(dev, new_parent);
break;
case DPM_ORDER_PARENT_BEFORE_DEV:
device_pm_move_before(new_parent, dev);
+ devices_kset_move_before(new_parent, dev);
break;
case DPM_ORDER_DEV_LAST:
device_pm_move_last(dev);
+ devices_kset_move_last(dev);
break;
}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 78720e7061763..91bbb1959d8d0 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -41,7 +41,7 @@ static void change_cpu_under_node(struct cpu *cpu,
cpu->node_id = to_nid;
}
-static int __ref cpu_subsys_online(struct device *dev)
+static int cpu_subsys_online(struct device *dev)
{
struct cpu *cpu = container_of(dev, struct cpu, dev);
int cpuid = dev->id;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a638bbb1a27a5..cc2b1d4801fd5 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -304,6 +304,14 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto probe_failed;
}
+ /*
+ * Ensure devices are listed in devices_kset in correct order
+ * It's important to move Dev to the end of devices_kset before
+ * calling .probe, because it could be recursive and parent Dev
+ * should always go first
+ */
+ devices_kset_move_last(dev);
+
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index c8a53d1e019fb..8754646901174 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -297,10 +297,10 @@ void * devres_get(struct device *dev, void *new_res,
if (!dr) {
add_dr(dev, &new_dr->node);
dr = new_dr;
- new_dr = NULL;
+ new_res = NULL;
}
spin_unlock_irqrestore(&dev->devres_lock, flags);
- devres_free(new_dr);
+ devres_free(new_res);
return dr->data;
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 894bda114224d..8524450e75bd1 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -443,7 +443,7 @@ static int fw_add_devm_name(struct device *dev, const char *name)
return -ENOMEM;
fwn->name = kstrdup_const(name, GFP_KERNEL);
if (!fwn->name) {
- kfree(fwn);
+ devres_free(fwn);
return -ENOMEM;
}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7a3c30c4336f3..9bb09ce98d047 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1521,13 +1521,13 @@ static int __cpufreq_remove_dev_finish(struct device *dev)
*
* Removes the cpufreq interface for a CPU device.
*/
-static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
+static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
{
unsigned int cpu = dev->id;
struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
if (!policy)
- return 0;
+ return;
if (cpu_online(cpu)) {
__cpufreq_remove_dev_prepare(dev);
@@ -1538,7 +1538,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
if (cpumask_empty(policy->real_cpus)) {
cpufreq_policy_free(policy, true);
- return 0;
+ return;
}
if (cpu != policy->kobj_cpu) {
@@ -1557,8 +1557,6 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
policy->kobj_cpu = new_cpu;
WARN_ON(kobject_move(&policy->kobj, &new_dev->kobj));
}
-
- return 0;
}
static void handle_update(struct work_struct *work)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index dac7a0d9bb46e..01f08a7751f7a 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -396,7 +396,7 @@ static int rionet_close(struct net_device *ndev)
return 0;
}
-static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
+static void rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
{
struct rio_dev *rdev = to_rio_dev(dev);
unsigned char netid = rdev->net->hport->id;
@@ -416,8 +416,6 @@ static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
}
}
}
-
- return 0;
}
static void rionet_get_drvinfo(struct net_device *ndev,
diff --git a/include/linux/device.h b/include/linux/device.h
index a2b4ea70a9467..1225f98e92402 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -341,7 +341,7 @@ struct subsys_interface {
struct bus_type *subsys;
struct list_head node;
int (*add_dev)(struct device *dev, struct subsys_interface *sif);
- int (*remove_dev)(struct device *dev, struct subsys_interface *sif);
+ void (*remove_dev)(struct device *dev, struct subsys_interface *sif);
};
int subsys_interface_register(struct subsys_interface *sif);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 718ea76b78ba1..964b4efadf413 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -206,7 +206,7 @@ EXPORT_SYMBOL_GPL(cpu_hotplug_enable);
#endif /* CONFIG_HOTPLUG_CPU */
/* Need to know about CPUs going up/down? */
-int __ref register_cpu_notifier(struct notifier_block *nb)
+int register_cpu_notifier(struct notifier_block *nb)
{
int ret;
cpu_maps_update_begin();
@@ -215,7 +215,7 @@ int __ref register_cpu_notifier(struct notifier_block *nb)
return ret;
}
-int __ref __register_cpu_notifier(struct notifier_block *nb)
+int __register_cpu_notifier(struct notifier_block *nb)
{
return raw_notifier_chain_register(&cpu_chain, nb);
}
@@ -245,7 +245,7 @@ static void cpu_notify_nofail(unsigned long val, void *v)
EXPORT_SYMBOL(register_cpu_notifier);
EXPORT_SYMBOL(__register_cpu_notifier);
-void __ref unregister_cpu_notifier(struct notifier_block *nb)
+void unregister_cpu_notifier(struct notifier_block *nb)
{
cpu_maps_update_begin();
raw_notifier_chain_unregister(&cpu_chain, nb);
@@ -253,7 +253,7 @@ void __ref unregister_cpu_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL(unregister_cpu_notifier);
-void __ref __unregister_cpu_notifier(struct notifier_block *nb)
+void __unregister_cpu_notifier(struct notifier_block *nb)
{
raw_notifier_chain_unregister(&cpu_chain, nb);
}
@@ -330,7 +330,7 @@ struct take_cpu_down_param {
};
/* Take this CPU down. */
-static int __ref take_cpu_down(void *_param)
+static int take_cpu_down(void *_param)
{
struct take_cpu_down_param *param = _param;
int err;
@@ -349,7 +349,7 @@ static int __ref take_cpu_down(void *_param)
}
/* Requires cpu_add_remove_lock to be held */
-static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
+static int _cpu_down(unsigned int cpu, int tasks_frozen)
{
int err, nr_calls = 0;
void *hcpu = (void *)(long)cpu;
@@ -443,7 +443,7 @@ out_release:
return err;
}
-int __ref cpu_down(unsigned int cpu)
+int cpu_down(unsigned int cpu)
{
int err;
@@ -633,7 +633,7 @@ void __weak arch_enable_nonboot_cpus_end(void)
{
}
-void __ref enable_nonboot_cpus(void)
+void enable_nonboot_cpus(void)
{
int cpu, error;
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
index 3fc6c10c2479c..c4366dc74e014 100755
--- a/tools/testing/selftests/firmware/fw_filesystem.sh
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -9,7 +9,15 @@ modprobe test_firmware
DIR=/sys/devices/virtual/misc/test_firmware
-OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
+# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
+# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
+# as an indicator for CONFIG_FW_LOADER_USER_HELPER.
+HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
+
+if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
+ OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
+fi
+
OLD_FWPATH=$(cat /sys/module/firmware_class/parameters/path)
FWPATH=$(mktemp -d)
@@ -17,7 +25,9 @@ FW="$FWPATH/test-firmware.bin"
test_finish()
{
- echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
+ if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
+ echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
+ fi
echo -n "$OLD_PATH" >/sys/module/firmware_class/parameters/path
rm -f "$FW"
rmdir "$FWPATH"
@@ -25,8 +35,11 @@ test_finish()
trap "test_finish" EXIT
-# Turn down the timeout so failures don't take so long.
-echo 1 >/sys/class/firmware/timeout
+if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
+ # Turn down the timeout so failures don't take so long.
+ echo 1 >/sys/class/firmware/timeout
+fi
+
# Set the kernel search path.
echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
@@ -41,7 +54,9 @@ if diff -q "$FW" /dev/test_firmware >/dev/null ; then
echo "$0: firmware was not expected to match" >&2
exit 1
else
- echo "$0: timeout works"
+ if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
+ echo "$0: timeout works"
+ fi
fi
# This should succeed via kernel load or will fail after 1 second after
diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh
index 6efbade121394..b9983f8e09f68 100755
--- a/tools/testing/selftests/firmware/fw_userhelper.sh
+++ b/tools/testing/selftests/firmware/fw_userhelper.sh
@@ -9,7 +9,17 @@ modprobe test_firmware
DIR=/sys/devices/virtual/misc/test_firmware
-OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
+# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
+# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
+# as an indicator for CONFIG_FW_LOADER_USER_HELPER.
+HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
+
+if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
+ OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
+else
+ echo "usermode helper disabled so ignoring test"
+ exit 0
+fi
FWPATH=$(mktemp -d)
FW="$FWPATH/test-firmware.bin"