summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-06-03 11:48:47 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-06-03 11:48:47 -0700
commit500a434fc593f1fdb274c0e6fe09a0b9c0711a4b (patch)
treee05efb88b90b6fa631bc22f2794233529b6c1de3
parent6f9b5ed8caddfbc94af8307c557ed57a8ec5c65c (diff)
parentb232b02bf3c205b13a26dcec08e53baddd8e59ed (diff)
downloadlinux-500a434fc593f1fdb274c0e6fe09a0b9c0711a4b.tar.gz
linux-500a434fc593f1fdb274c0e6fe09a0b9c0711a4b.tar.bz2
linux-500a434fc593f1fdb274c0e6fe09a0b9c0711a4b.zip
Merge tag 'driver-core-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here is the set of driver core changes for 5.19-rc1. Lots of tiny driver core changes and cleanups happened this cycle, but the two major things are: - firmware_loader reorganization and additions including the ability to have XZ compressed firmware images and the ability for userspace to initiate the firmware load when it needs to, instead of being always initiated by the kernel. FPGA devices specifically want this ability to have their firmware changed over the lifetime of the system boot, and this allows them to work without having to come up with yet-another-custom-uapi interface for loading firmware for them. - physical location support added to sysfs so that devices that know this information, can tell userspace where they are located in a common way. Some ACPI devices already support this today, and more bus types should support this in the future. Smaller changes include: - driver_override api cleanups and fixes - error path cleanups and fixes - get_abi script fixes - deferred probe timeout changes. It's that last change that I'm the most worried about. It has been reported to cause boot problems for a number of systems, and I have a tested patch series that resolves this issue. But I didn't get it merged into my tree before 5.18-final came out, so it has not gotten any linux-next testing. I'll send the fixup patches (there are 2) as a follow-on series to this pull request. All have been tested in linux-next for weeks, with no reported issues other than the above-mentioned boot time-outs" * tag 'driver-core-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (55 commits) driver core: fix deadlock in __device_attach kernfs: Separate kernfs_pr_cont_buf and rename_lock. topology: Remove unused cpu_cluster_mask() driver core: Extend deferred probe timeout on driver registration MAINTAINERS: add Russ Weight as a firmware loader maintainer driver: base: fix UAF when driver_attach failed test_firmware: fix end of loop test in upload_read_show() driver core: location: Add "back" as a possible output for panel driver core: location: Free struct acpi_pld_info *pld driver core: Add "*" wildcard support to driver_async_probe cmdline param driver core: location: Check for allocations failure arch_topology: Trace the update thermal pressure kernfs: Rename kernfs_put_open_node to kernfs_unlink_open_file. export: fix string handling of namespace in EXPORT_SYMBOL_NS rpmsg: use local 'dev' variable rpmsg: Fix calling device_lock() on non-initialized device firmware_loader: describe 'module' parameter of firmware_upload_register() firmware_loader: Move definitions from sysfs_upload.h to sysfs.h firmware_loader: Fix configs for sysfs split selftests: firmware: Add firmware upload selftests ...
-rw-r--r--Documentation/ABI/testing/sysfs-class-firmware77
-rw-r--r--Documentation/ABI/testing/sysfs-devices-physical_location42
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt11
-rw-r--r--Documentation/driver-api/firmware/fw_upload.rst126
-rw-r--r--Documentation/driver-api/firmware/index.rst1
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/amba/bus.c28
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/arch_topology.c5
-rw-r--r--drivers/base/base.h1
-rw-r--r--drivers/base/bus.c4
-rw-r--r--drivers/base/core.c15
-rw-r--r--drivers/base/dd.c44
-rw-r--r--drivers/base/driver.c70
-rw-r--r--drivers/base/firmware_loader/Kconfig42
-rw-r--r--drivers/base/firmware_loader/Makefile2
-rw-r--r--drivers/base/firmware_loader/fallback.c430
-rw-r--r--drivers/base/firmware_loader/fallback.h46
-rw-r--r--drivers/base/firmware_loader/firmware.h16
-rw-r--r--drivers/base/firmware_loader/main.c94
-rw-r--r--drivers/base/firmware_loader/sysfs.c422
-rw-r--r--drivers/base/firmware_loader/sysfs.h117
-rw-r--r--drivers/base/firmware_loader/sysfs_upload.c397
-rw-r--r--drivers/base/firmware_loader/sysfs_upload.h41
-rw-r--r--drivers/base/physical_location.c143
-rw-r--r--drivers/base/physical_location.h16
-rw-r--r--drivers/base/platform.c34
-rw-r--r--drivers/bus/fsl-mc/fsl-mc-bus.c25
-rw-r--r--drivers/clk/imx/clk-scu.c7
-rw-r--r--drivers/hv/vmbus_drv.c28
-rw-r--r--drivers/pci/pci-sysfs.c28
-rw-r--r--drivers/rpmsg/rpmsg_core.c42
-rw-r--r--drivers/rpmsg/rpmsg_internal.h5
-rw-r--r--drivers/rpmsg/rpmsg_ns.c4
-rw-r--r--drivers/s390/cio/cio.h6
-rw-r--r--drivers/s390/cio/css.c28
-rw-r--r--drivers/slimbus/qcom-ngd-ctrl.c13
-rw-r--r--drivers/spi/spi.c26
-rw-r--r--drivers/vdpa/vdpa.c29
-rw-r--r--fs/kernfs/dir.c31
-rw-r--r--fs/kernfs/file.c47
-rw-r--r--include/linux/amba/bus.h6
-rw-r--r--include/linux/device.h73
-rw-r--r--include/linux/device/driver.h2
-rw-r--r--include/linux/export.h7
-rw-r--r--include/linux/firmware.h82
-rw-r--r--include/linux/fsl/mc.h6
-rw-r--r--include/linux/hyperv.h6
-rw-r--r--include/linux/pci.h6
-rw-r--r--include/linux/platform_device.h6
-rw-r--r--include/linux/rpmsg.h14
-rw-r--r--include/linux/spi/spi.h2
-rw-r--r--include/linux/vdpa.h4
-rw-r--r--include/trace/events/thermal_pressure.h29
-rw-r--r--lib/test_firmware.c381
-rwxr-xr-xscripts/get_abi.pl4
-rw-r--r--tools/testing/selftests/firmware/Makefile2
-rw-r--r--tools/testing/selftests/firmware/config1
-rwxr-xr-xtools/testing/selftests/firmware/fw_filesystem.sh170
-rwxr-xr-xtools/testing/selftests/firmware/fw_lib.sh19
-rwxr-xr-xtools/testing/selftests/firmware/fw_run_tests.sh4
-rwxr-xr-xtools/testing/selftests/firmware/fw_upload.sh214
62 files changed, 2732 insertions, 851 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-firmware b/Documentation/ABI/testing/sysfs-class-firmware
new file mode 100644
index 000000000000..978d3d500400
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-firmware
@@ -0,0 +1,77 @@
+What: /sys/class/firmware/.../data
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: The data sysfs file is used for firmware-fallback and for
+ firmware uploads. Cat a firmware image to this sysfs file
+ after you echo 1 to the loading sysfs file. When the firmware
+ image write is complete, echo 0 to the loading sysfs file. This
+ sequence will signal the completion of the firmware write and
+ signal the lower-level driver that the firmware data is
+ available.
+
+What: /sys/class/firmware/.../cancel
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: Write-only. For firmware uploads, write a "1" to this file to
+ request that the transfer of firmware data to the lower-level
+ device be canceled. This request will be rejected (EBUSY) if
+ the update cannot be canceled (e.g. a FLASH write is in
+ progress) or (ENODEV) if there is no firmware update in progress.
+
+What: /sys/class/firmware/.../error
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: Read-only. Returns a string describing a failed firmware
+ upload. This string will be in the form of <STATUS>:<ERROR>,
+ where <STATUS> will be one of the status strings described
+ for the status sysfs file and <ERROR> will be one of the
+ following: "hw-error", "timeout", "user-abort", "device-busy",
+ "invalid-file-size", "read-write-error", "flash-wearout". The
+ error sysfs file is only meaningful when the current firmware
+ upload status is "idle". If this file is read while a firmware
+ transfer is in progress, then the read will fail with EBUSY.
+
+What: /sys/class/firmware/.../loading
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: The loading sysfs file is used for both firmware-fallback and
+ for firmware uploads. Echo 1 onto the loading file to indicate
+ you are writing a firmware file to the data sysfs node. Echo
+ -1 onto this file to abort the data write or echo 0 onto this
+ file to indicate that the write is complete. For firmware
+ uploads, the zero value also triggers the transfer of the
+ firmware data to the lower-level device driver.
+
+What: /sys/class/firmware/.../remaining_size
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: Read-only. For firmware upload, this file contains the size
+ of the firmware data that remains to be transferred to the
+ lower-level device driver. The size value is initialized to
+ the full size of the firmware image that was previously
+ written to the data sysfs file. This value is periodically
+ updated during the "transferring" phase of the firmware
+ upload.
+ Format: "%u".
+
+What: /sys/class/firmware/.../status
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: Read-only. Returns a string describing the current status of
+ a firmware upload. The string will be one of the following:
+ idle, "receiving", "preparing", "transferring", "programming".
+
+What: /sys/class/firmware/.../timeout
+Date: July 2022
+KernelVersion: 5.19
+Contact: Russ Weight <russell.h.weight@intel.com>
+Description: This file supports the timeout mechanism for firmware
+ fallback. This file has no affect on firmware uploads. For
+ more information on timeouts please see the documentation
+ for firmware fallback.
diff --git a/Documentation/ABI/testing/sysfs-devices-physical_location b/Documentation/ABI/testing/sysfs-devices-physical_location
new file mode 100644
index 000000000000..202324b87083
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-physical_location
@@ -0,0 +1,42 @@
+What: /sys/devices/.../physical_location
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ This directory contains information on physical location of
+ the device connection point with respect to the system's
+ housing.
+
+What: /sys/devices/.../physical_location/panel
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ Describes which panel surface of the system’s housing the
+ device connection point resides on.
+
+What: /sys/devices/.../physical_location/vertical_position
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ Describes vertical position of the device connection point on
+ the panel surface.
+
+What: /sys/devices/.../physical_location/horizontal_position
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ Describes horizontal position of the device connection point on
+ the panel surface.
+
+What: /sys/devices/.../physical_location/dock
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ "Yes" if the device connection point resides in a docking
+ station or a port replicator. "No" otherwise.
+
+What: /sys/devices/.../physical_location/lid
+Date: March 2022
+Contact: Won Chung <wonchung@google.com>
+Description:
+ "Yes" if the device connection point resides on the lid of
+ laptop system. "No" otherwise.
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 710b52d87bdd..8090130b544b 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -979,8 +979,10 @@
[KNL] Debugging option to set a timeout in seconds for
deferred probe to give up waiting on dependencies to
probe. Only specific dependencies (subsystems or
- drivers) that have opted in will be ignored. A timeout of 0
- will timeout at the end of initcalls. This option will also
+ drivers) that have opted in will be ignored. A timeout
+ of 0 will timeout at the end of initcalls. If the time
+ out hasn't expired, it'll be restarted by each
+ successful driver registration. This option will also
dump out devices still on the deferred probe list after
retrying.
@@ -1101,7 +1103,10 @@
driver later using sysfs.
driver_async_probe= [KNL]
- List of driver names to be probed asynchronously.
+ List of driver names to be probed asynchronously. *
+ matches with all driver names. If * is specified, the
+ rest of the listed driver names are those that will NOT
+ match the *.
Format: <driver_name1>,<driver_name2>...
drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
diff --git a/Documentation/driver-api/firmware/fw_upload.rst b/Documentation/driver-api/firmware/fw_upload.rst
new file mode 100644
index 000000000000..76922591e446
--- /dev/null
+++ b/Documentation/driver-api/firmware/fw_upload.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================
+Firmware Upload API
+===================
+
+A device driver that registers with the firmware loader will expose
+persistent sysfs nodes to enable users to initiate firmware updates for
+that device. It is the responsibility of the device driver and/or the
+device itself to perform any validation on the data received. Firmware
+upload uses the same *loading* and *data* sysfs files described in the
+documentation for firmware fallback. It also adds additional sysfs files
+to provide status on the transfer of the firmware image to the device.
+
+Register for firmware upload
+============================
+
+A device driver registers for firmware upload by calling
+firmware_upload_register(). Among the parameter list is a name to
+identify the device under /sys/class/firmware. A user may initiate a
+firmware upload by echoing a 1 to the *loading* sysfs file for the target
+device. Next, the user writes the firmware image to the *data* sysfs
+file. After writing the firmware data, the user echos 0 to the *loading*
+sysfs file to signal completion. Echoing 0 to *loading* also triggers the
+transfer of the firmware to the lower-lever device driver in the context
+of a kernel worker thread.
+
+To use the firmware upload API, write a driver that implements a set of
+ops. The probe function calls firmware_upload_register() and the remove
+function calls firmware_upload_unregister() such as::
+
+ static const struct fw_upload_ops m10bmc_ops = {
+ .prepare = m10bmc_sec_prepare,
+ .write = m10bmc_sec_write,
+ .poll_complete = m10bmc_sec_poll_complete,
+ .cancel = m10bmc_sec_cancel,
+ .cleanup = m10bmc_sec_cleanup,
+ };
+
+ static int m10bmc_sec_probe(struct platform_device *pdev)
+ {
+ const char *fw_name, *truncate;
+ struct m10bmc_sec *sec;
+ struct fw_upload *fwl;
+ unsigned int len;
+
+ sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
+ if (!sec)
+ return -ENOMEM;
+
+ sec->dev = &pdev->dev;
+ sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
+ dev_set_drvdata(&pdev->dev, sec);
+
+ fw_name = dev_name(sec->dev);
+ truncate = strstr(fw_name, ".auto");
+ len = (truncate) ? truncate - fw_name : strlen(fw_name);
+ sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
+
+ fwl = firmware_upload_register(sec->dev, sec->fw_name, &m10bmc_ops, sec);
+ if (IS_ERR(fwl)) {
+ dev_err(sec->dev, "Firmware Upload driver failed to start\n");
+ kfree(sec->fw_name);
+ return PTR_ERR(fwl);
+ }
+
+ sec->fwl = fwl;
+ return 0;
+ }
+
+ static int m10bmc_sec_remove(struct platform_device *pdev)
+ {
+ struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
+
+ firmware_upload_unregister(sec->fwl);
+ kfree(sec->fw_name);
+ return 0;
+ }
+
+firmware_upload_register
+------------------------
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
+ :identifiers: firmware_upload_register
+
+firmware_upload_unregister
+--------------------------
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
+ :identifiers: firmware_upload_unregister
+
+Firmware Upload Ops
+-------------------
+.. kernel-doc:: include/linux/firmware.h
+ :identifiers: fw_upload_ops
+
+Firmware Upload Progress Codes
+------------------------------
+The following progress codes are used internally by the firmware loader.
+Corresponding strings are reported through the status sysfs node that
+is described below and are documented in the ABI documentation.
+
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
+ :identifiers: fw_upload_prog
+
+Firmware Upload Error Codes
+---------------------------
+The following error codes may be returned by the driver ops in case of
+failure:
+
+.. kernel-doc:: include/linux/firmware.h
+ :identifiers: fw_upload_err
+
+Sysfs Attributes
+================
+
+In addition to the *loading* and *data* sysfs files, there are additional
+sysfs files to monitor the status of the data transfer to the target
+device and to determine the final pass/fail status of the transfer.
+Depending on the device and the size of the firmware image, a firmware
+update could take milliseconds or minutes.
+
+The additional sysfs files are:
+
+* status - provides an indication of the progress of a firmware update
+* error - provides error information for a failed firmware update
+* remaining_size - tracks the data transfer portion of an update
+* cancel - echo 1 to this file to cancel the update
diff --git a/Documentation/driver-api/firmware/index.rst b/Documentation/driver-api/firmware/index.rst
index 57415d657173..9d2c19dc8e36 100644
--- a/Documentation/driver-api/firmware/index.rst
+++ b/Documentation/driver-api/firmware/index.rst
@@ -8,6 +8,7 @@ Linux Firmware API
core
efi/index
request_firmware
+ fw_upload
other_interfaces
.. only:: subproject and html
diff --git a/MAINTAINERS b/MAINTAINERS
index f7e4b8f21ca8..9516861da194 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7727,6 +7727,7 @@ F: include/linux/arm_ffa.h
FIRMWARE LOADER (request_firmware)
M: Luis Chamberlain <mcgrof@kernel.org>
+M: Russ Weight <russell.h.weight@intel.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/firmware_class/
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3a2adeaef5ce..0e3ed5eb367b 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -98,31 +98,11 @@ static ssize_t driver_override_store(struct device *_dev,
const char *buf, size_t count)
{
struct amba_device *dev = to_amba_device(_dev);
- char *driver_override, *old, *cp;
-
- /* We need to keep extra room for a newline */
- if (count >= (PAGE_SIZE - 1))
- return -EINVAL;
-
- driver_override = kstrndup(buf, count, GFP_KERNEL);
- if (!driver_override)
- return -ENOMEM;
-
- cp = strchr(driver_override, '\n');
- if (cp)
- *cp = '\0';
-
- device_lock(_dev);
- old = dev->driver_override;
- if (strlen(driver_override)) {
- dev->driver_override = driver_override;
- } else {
- kfree(driver_override);
- dev->driver_override = NULL;
- }
- device_unlock(_dev);
+ int ret;
- kfree(old);
+ ret = driver_set_override(_dev, &dev->driver_override, buf, count);
+ if (ret)
+ return ret;
return count;
}
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 02f7f1358e86..83217d243c25 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o
obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o
obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o
+obj-$(CONFIG_ACPI) += physical_location.o
obj-y += test/
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index f73b836047cf..579c851a2bd7 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -19,6 +19,9 @@
#include <linux/rcupdate.h>
#include <linux/sched.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/thermal_pressure.h>
+
static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
static struct cpumask scale_freq_counters_mask;
static bool scale_freq_invariant;
@@ -195,6 +198,8 @@ void topology_update_thermal_pressure(const struct cpumask *cpus,
th_pressure = max_capacity - capacity;
+ trace_thermal_pressure_update(cpu, th_pressure);
+
for_each_cpu(cpu, cpus)
WRITE_ONCE(per_cpu(thermal_pressure, cpu), th_pressure);
}
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 2882af26392a..ab71403d102f 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -159,6 +159,7 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
extern int devres_release_all(struct device *dev);
extern void device_block_probing(void);
extern void device_unblock_probing(void);
+extern void deferred_probe_extend_timeout(void);
/* /sys/devices directory */
extern struct kset *devices_kset;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 97936ec49bde..7ca47e5b3c1f 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -617,7 +617,7 @@ int bus_add_driver(struct device_driver *drv)
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
- goto out_unregister;
+ goto out_del_list;
}
module_add_driver(drv->owner, drv);
@@ -644,6 +644,8 @@ int bus_add_driver(struct device_driver *drv)
return 0;
+out_del_list:
+ klist_del(&priv->knode_bus);
out_unregister:
kobject_put(&priv->kobj);
/* drv->p is freed in driver_release() */
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 2eede2ec3d64..7cd789c4985d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -32,6 +32,7 @@
#include <linux/dma-map-ops.h> /* for dma_default_coherent */
#include "base.h"
+#include "physical_location.h"
#include "power/power.h"
#ifdef CONFIG_SYSFS_DEPRECATED
@@ -2649,8 +2650,17 @@ static int device_add_attrs(struct device *dev)
goto err_remove_dev_waiting_for_supplier;
}
+ if (dev_add_physical_location(dev)) {
+ error = device_add_group(dev,
+ &dev_attr_physical_location_group);
+ if (error)
+ goto err_remove_dev_removable;
+ }
+
return 0;
+ err_remove_dev_removable:
+ device_remove_file(dev, &dev_attr_removable);
err_remove_dev_waiting_for_supplier:
device_remove_file(dev, &dev_attr_waiting_for_supplier);
err_remove_dev_online:
@@ -2672,6 +2682,11 @@ static void device_remove_attrs(struct device *dev)
struct class *class = dev->class;
const struct device_type *type = dev->type;
+ if (dev->physical_location) {
+ device_remove_group(dev, &dev_attr_physical_location_group);
+ kfree(dev->physical_location);
+ }
+
device_remove_file(dev, &dev_attr_removable);
device_remove_file(dev, &dev_attr_waiting_for_supplier);
device_remove_file(dev, &dev_attr_online);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 94b7ac9bf459..5443b09eef8b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -60,6 +60,7 @@ static bool initcalls_done;
/* Save the async probe drivers' name from kernel cmdline */
#define ASYN