Skip to content

Commit

Permalink
Merge tag 'driver-core-5.19-rc1' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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
  ...
  • Loading branch information
torvalds committed Jun 3, 2022
2 parents 6f9b5ed + b232b02 commit 500a434
Show file tree
Hide file tree
Showing 62 changed files with 2,732 additions and 851 deletions.
77 changes: 77 additions & 0 deletions Documentation/ABI/testing/sysfs-class-firmware
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
What: /sys/class/firmware/.../data
Date: July 2022
KernelVersion: 5.19
Contact: Russ Weight <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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.
42 changes: 42 additions & 0 deletions Documentation/ABI/testing/sysfs-devices-physical_location
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
What: /sys/devices/.../physical_location
Date: March 2022
Contact: Won Chung <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
Description:
"Yes" if the device connection point resides on the lid of
laptop system. "No" otherwise.
11 changes: 8 additions & 3 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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>]
Expand Down
126 changes: 126 additions & 0 deletions Documentation/driver-api/firmware/fw_upload.rst
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions Documentation/driver-api/firmware/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Linux Firmware API
core
efi/index
request_firmware
fw_upload
other_interfaces

.. only:: subproject and html
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7727,6 +7727,7 @@ F: include/linux/arm_ffa.h

FIRMWARE LOADER (request_firmware)
M: Luis Chamberlain <[email protected]>
M: Russ Weight <[email protected]>
L: [email protected]
S: Maintained
F: Documentation/firmware_class/
Expand Down
28 changes: 4 additions & 24 deletions drivers/amba/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/

Expand Down
5 changes: 5 additions & 0 deletions drivers/base/arch_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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() */
Expand Down
Loading

0 comments on commit 500a434

Please sign in to comment.