Commit 1a4ab084 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull driver core updates from Greg KH:
 "Just a few patches this time around for the 4.6-rc1 merge window.
  Largest is a new firmware driver, but there are some other updates to
  the driver core in here as well, the shortlog has the details.

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

* tag 'driver-core-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  Revert "driver-core: platform: probe of-devices only using list of compatibles"
  firmware: qemu config needs I/O ports
  firmware: qemu_fw_cfg.c: fix typo FW_CFG_DATA_OFF
  driver-core: platform: probe of-devices only using list of compatibles
  driver-core: platform: fix typo in documentation for multi-driver helper
  component: remove impossible condition
  drivers: dma-coherent: simplify dma_init_coherent_memory return value
  devicetree: update documentation for fw_cfg ARM bindings
  firmware: create directory hierarchy for sysfs fw_cfg entries
  firmware: introduce sysfs driver for QEMU's fw_cfg device
  kobject: export kset_find_obj() for module use
  driver core: bus: use to_subsys_private and to_device_private_bus
  driver core: bus: use list_for_each_entry*
  debugfs: Add stub function for debugfs_create_automount().
  kernfs: make kernfs_walk_ns() use kernfs_pr_cont_buf[]
parents 45cb5230 112d125a
What: /sys/firmware/qemu_fw_cfg/
Date: August 2015
Contact: Gabriel Somlo <somlo@cmu.edu>
Description:
Several different architectures supported by QEMU (x86, arm,
sun4*, ppc/mac) are provisioned with a firmware configuration
(fw_cfg) device, originally intended as a way for the host to
provide configuration data to the guest firmware. Starting
with QEMU v2.4, arbitrary fw_cfg file entries may be specified
by the user on the command line, which makes fw_cfg additionally
useful as an out-of-band, asynchronous mechanism for providing
configuration data to the guest userspace.
The authoritative guest-side hardware interface documentation
to the fw_cfg device can be found in "docs/specs/fw_cfg.txt"
in the QEMU source tree.
=== SysFS fw_cfg Interface ===
The fw_cfg sysfs interface described in this document is only
intended to display discoverable blobs (i.e., those registered
with the file directory), as there is no way to determine the
presence or size of "legacy" blobs (with selector keys between
0x0002 and 0x0018) programmatically.
All fw_cfg information is shown under:
/sys/firmware/qemu_fw_cfg/
The only legacy blob displayed is the fw_cfg device revision:
/sys/firmware/qemu_fw_cfg/rev
--- Discoverable fw_cfg blobs by selector key ---
All discoverable blobs listed in the fw_cfg file directory are
displayed as entries named after their unique selector key
value, e.g.:
/sys/firmware/qemu_fw_cfg/by_key/32
/sys/firmware/qemu_fw_cfg/by_key/33
/sys/firmware/qemu_fw_cfg/by_key/34
...
Each such fw_cfg sysfs entry has the following values exported
as attributes:
name : The 56-byte nul-terminated ASCII string used as the
blob's 'file name' in the fw_cfg directory.
size : The length of the blob, as given in the fw_cfg
directory.
key : The value of the blob's selector key as given in the
fw_cfg directory. This value is the same as used in
the parent directory name.
raw : The raw bytes of the blob, obtained by selecting the
entry via the control register, and reading a number
of bytes equal to the blob size from the data
register.
--- Listing fw_cfg blobs by file name ---
While the fw_cfg device does not impose any specific naming
convention on the blobs registered in the file directory,
QEMU developers have traditionally used path name semantics
to give each blob a descriptive name. For example:
"bootorder"
"genroms/kvmvapic.bin"
"etc/e820"
"etc/boot-fail-wait"
"etc/system-states"
"etc/table-loader"
"etc/acpi/rsdp"
"etc/acpi/tables"
"etc/smbios/smbios-tables"
"etc/smbios/smbios-anchor"
...
In addition to the listing by unique selector key described
above, the fw_cfg sysfs driver also attempts to build a tree
of directories matching the path name components of fw_cfg
blob names, ending in symlinks to the by_key entry for each
"basename", as illustrated below (assume current directory is
/sys/firmware):
qemu_fw_cfg/by_name/bootorder -> ../by_key/38
qemu_fw_cfg/by_name/etc/e820 -> ../../by_key/35
qemu_fw_cfg/by_name/etc/acpi/rsdp -> ../../../by_key/41
...
Construction of the directory tree and symlinks is done on a
"best-effort" basis, as there is no guarantee that components
of fw_cfg blob names are always "well behaved". I.e., there is
the possibility that a symlink (basename) will conflict with
a dirname component of another fw_cfg blob, in which case the
creation of the offending /sys/firmware/qemu_fw_cfg/by_name
entry will be skipped.
The authoritative list of entries will continue to be found
under the /sys/firmware/qemu_fw_cfg/by_key directory.
...@@ -11,43 +11,9 @@ QEMU exposes the control and data register to ARM guests as memory mapped ...@@ -11,43 +11,9 @@ QEMU exposes the control and data register to ARM guests as memory mapped
registers; their location is communicated to the guest's UEFI firmware in the registers; their location is communicated to the guest's UEFI firmware in the
DTB that QEMU places at the bottom of the guest's DRAM. DTB that QEMU places at the bottom of the guest's DRAM.
The guest writes a selector value (a key) to the selector register, and then The authoritative guest-side hardware interface documentation to the fw_cfg
can read the corresponding data (produced by QEMU) via the data register. If device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree.
the selected entry is writable, the guest can rewrite it through the data
register.
The selector register takes keys in big endian byte order.
The data register allows accesses with 8, 16, 32 and 64-bit width (only at
offset 0 of the register). Accesses larger than a byte are interpreted as
arrays, bundled together only for better performance. The bytes constituting
such a word, in increasing address order, correspond to the bytes that would
have been transferred by byte-wide accesses in chronological order.
The interface allows guest firmware to download various parameters and blobs
that affect how the firmware works and what tables it installs for the guest
OS. For example, boot order of devices, ACPI tables, SMBIOS tables, kernel and
initrd images for direct kernel booting, virtual machine UUID, SMP information,
virtual NUMA topology, and so on.
The authoritative registry of the valid selector values and their meanings is
the QEMU source code; the structure of the data blobs corresponding to the
individual key values is also defined in the QEMU source code.
The presence of the registers can be verified by selecting the "signature" blob
with key 0x0000, and reading four bytes from the data register. The returned
signature is "QEMU".
The outermost protocol (involving the write / read sequences of the control and
data registers) is expected to be versioned, and/or described by feature bits.
The interface revision / feature bitmap can be retrieved with key 0x0001. The
blob to be read from the data register has size 4, and it is to be interpreted
as a uint32_t value in little endian byte order. The current value
(corresponding to the above outer protocol) is zero.
The guest kernel is not expected to use these registers (although it is
certainly allowed to); the device tree bindings are documented here because
this is where device tree bindings reside in general.
Required properties: Required properties:
......
...@@ -75,7 +75,7 @@ If one of the drivers fails to register, all drivers registered up to that ...@@ -75,7 +75,7 @@ If one of the drivers fails to register, all drivers registered up to that
point will be unregistered in reverse order. Note that there is a convenience point will be unregistered in reverse order. Note that there is a convenience
macro that passes THIS_MODULE as owner parameter: macro that passes THIS_MODULE as owner parameter:
#define platform_register_driver(drivers, count) #define platform_register_drivers(drivers, count)
Device Enumeration Device Enumeration
......
...@@ -149,8 +149,7 @@ EXPORT_SYMBOL_GPL(bus_remove_file); ...@@ -149,8 +149,7 @@ EXPORT_SYMBOL_GPL(bus_remove_file);
static void bus_release(struct kobject *kobj) static void bus_release(struct kobject *kobj)
{ {
struct subsys_private *priv = struct subsys_private *priv = to_subsys_private(kobj);
container_of(kobj, typeof(*priv), subsys.kobj);
struct bus_type *bus = priv->bus; struct bus_type *bus = priv->bus;
kfree(priv); kfree(priv);
...@@ -1019,13 +1018,11 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list ...@@ -1019,13 +1018,11 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
int (*compare)(const struct device *a, int (*compare)(const struct device *a,
const struct device *b)) const struct device *b))
{ {
struct list_head *pos;
struct klist_node *n; struct klist_node *n;
struct device_private *dev_prv; struct device_private *dev_prv;
struct device *b; struct device *b;
list_for_each(pos, list) { list_for_each_entry(n, list, n_node) {
n = container_of(pos, struct klist_node, n_node);
dev_prv = to_device_private_bus(n); dev_prv = to_device_private_bus(n);
b = dev_prv->device; b = dev_prv->device;
if (compare(a, b) <= 0) { if (compare(a, b) <= 0) {
...@@ -1042,8 +1039,7 @@ void bus_sort_breadthfirst(struct bus_type *bus, ...@@ -1042,8 +1039,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
const struct device *b)) const struct device *b))
{ {
LIST_HEAD(sorted_devices); LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp; struct klist_node *n, *tmp;
struct klist_node *n;
struct device_private *dev_prv; struct device_private *dev_prv;
struct device *dev; struct device *dev;
struct klist *device_klist; struct klist *device_klist;
...@@ -1051,8 +1047,7 @@ void bus_sort_breadthfirst(struct bus_type *bus, ...@@ -1051,8 +1047,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
device_klist = bus_get_device_klist(bus); device_klist = bus_get_device_klist(bus);
spin_lock(&device_klist->k_lock); spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) { list_for_each_entry_safe(n, tmp, &device_klist->k_list, n_node) {
n = container_of(pos, struct klist_node, n_node);
dev_prv = to_device_private_bus(n); dev_prv = to_device_private_bus(n);
dev = dev_prv->device; dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare); device_insertion_sort_klist(dev, &sorted_devices, compare);
...@@ -1107,7 +1102,7 @@ struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter) ...@@ -1107,7 +1102,7 @@ struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter)
knode = klist_next(&iter->ki); knode = klist_next(&iter->ki);
if (!knode) if (!knode)
return NULL; return NULL;
dev = container_of(knode, struct device_private, knode_bus)->device; dev = to_device_private_bus(knode)->device;
if (!iter->type || iter->type == dev->type) if (!iter->type || iter->type == dev->type)
return dev; return dev;
} }
......
...@@ -267,7 +267,7 @@ void component_match_add_release(struct device *master, ...@@ -267,7 +267,7 @@ void component_match_add_release(struct device *master,
} }
if (match->num == match->alloc) { if (match->num == match->alloc) {
size_t new_size = match ? match->alloc + 16 : 15; size_t new_size = match->alloc + 16;
int ret; int ret;
ret = component_match_realloc(master, match, new_size); ret = component_match_realloc(master, match, new_size);
......
...@@ -17,8 +17,8 @@ struct dma_coherent_mem { ...@@ -17,8 +17,8 @@ struct dma_coherent_mem {
spinlock_t spinlock; spinlock_t spinlock;
}; };
static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr, static bool dma_init_coherent_memory(
size_t size, int flags, phys_addr_t phys_addr, dma_addr_t device_addr, size_t size, int flags,
struct dma_coherent_mem **mem) struct dma_coherent_mem **mem)
{ {
struct dma_coherent_mem *dma_mem = NULL; struct dma_coherent_mem *dma_mem = NULL;
...@@ -50,17 +50,13 @@ static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_add ...@@ -50,17 +50,13 @@ static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_add
spin_lock_init(&dma_mem->spinlock); spin_lock_init(&dma_mem->spinlock);
*mem = dma_mem; *mem = dma_mem;
return true;
if (flags & DMA_MEMORY_MAP)
return DMA_MEMORY_MAP;
return DMA_MEMORY_IO;
out: out:
kfree(dma_mem); kfree(dma_mem);
if (mem_base) if (mem_base)
iounmap(mem_base); iounmap(mem_base);
return 0; return false;
} }
static void dma_release_coherent_memory(struct dma_coherent_mem *mem) static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
...@@ -88,15 +84,13 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, ...@@ -88,15 +84,13 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size, int flags) dma_addr_t device_addr, size_t size, int flags)
{ {
struct dma_coherent_mem *mem; struct dma_coherent_mem *mem;
int ret;
ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags, if (!dma_init_coherent_memory(phys_addr, device_addr, size, flags,
&mem); &mem))
if (ret == 0)
return 0; return 0;
if (dma_assign_coherent_memory(dev, mem) == 0) if (dma_assign_coherent_memory(dev, mem) == 0)
return ret; return flags & DMA_MEMORY_MAP ? DMA_MEMORY_MAP : DMA_MEMORY_IO;
dma_release_coherent_memory(mem); dma_release_coherent_memory(mem);
return 0; return 0;
...@@ -281,9 +275,9 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) ...@@ -281,9 +275,9 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
struct dma_coherent_mem *mem = rmem->priv; struct dma_coherent_mem *mem = rmem->priv;
if (!mem && if (!mem &&
dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, !dma_init_coherent_memory(rmem->base, rmem->base, rmem->size,
DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE,
&mem) != DMA_MEMORY_MAP) { &mem)) {
pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n",
&rmem->base, (unsigned long)rmem->size / SZ_1M); &rmem->base, (unsigned long)rmem->size / SZ_1M);
return -ENODEV; return -ENODEV;
......
...@@ -161,6 +161,26 @@ config RASPBERRYPI_FIRMWARE ...@@ -161,6 +161,26 @@ config RASPBERRYPI_FIRMWARE
This option enables support for communicating with the firmware on the This option enables support for communicating with the firmware on the
Raspberry Pi. Raspberry Pi.
config FW_CFG_SYSFS
tristate "QEMU fw_cfg device support in sysfs"
depends on SYSFS && (ARM || ARM64 || PPC_PMAC || SPARC || X86)
depends on HAS_IOPORT_MAP
default n
help
Say Y or M here to enable the exporting of the QEMU firmware
configuration (fw_cfg) file entries via sysfs. Entries are
found under /sys/firmware/fw_cfg when this option is enabled
and loaded.
config FW_CFG_SYSFS_CMDLINE
bool "QEMU fw_cfg device parameter parsing"
depends on FW_CFG_SYSFS
help
Allow the qemu_fw_cfg device to be initialized via the kernel
command line or using a module parameter.
WARNING: Using incorrect parameters (base address in particular)
may crash your system.
config QCOM_SCM config QCOM_SCM
bool bool
depends on ARM || ARM64 depends on ARM || ARM64
......
...@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o ...@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
obj-$(CONFIG_QCOM_SCM) += qcom_scm.o obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o
obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o
......
This diff is collapsed.
...@@ -691,15 +691,22 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent, ...@@ -691,15 +691,22 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
const unsigned char *path, const unsigned char *path,
const void *ns) const void *ns)
{ {
static char path_buf[PATH_MAX]; /* protected by kernfs_mutex */ size_t len;
size_t len = strlcpy(path_buf, path, PATH_MAX); char *p, *name;
char *p = path_buf;
char *name;
lockdep_assert_held(&kernfs_mutex); lockdep_assert_held(&kernfs_mutex);
if (len >= PATH_MAX) /* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */
spin_lock_irq(&kernfs_rename_lock);
len = strlcpy(kernfs_pr_cont_buf, path, sizeof(kernfs_pr_cont_buf));
if (len >= sizeof(kernfs_pr_cont_buf)) {
spin_unlock_irq(&kernfs_rename_lock);
return NULL; return NULL;
}
p = kernfs_pr_cont_buf;
while ((name = strsep(&p, "/")) && parent) { while ((name = strsep(&p, "/")) && parent) {
if (*name == '\0') if (*name == '\0')
...@@ -707,6 +714,8 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent, ...@@ -707,6 +714,8 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
parent = kernfs_find_ns(parent, name, ns); parent = kernfs_find_ns(parent, name, ns);
} }
spin_unlock_irq(&kernfs_rename_lock);
return parent; return parent;
} }
......
...@@ -162,6 +162,14 @@ static inline struct dentry *debugfs_create_symlink(const char *name, ...@@ -162,6 +162,14 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline struct dentry *debugfs_create_automount(const char *name,
struct dentry *parent,
struct vfsmount *(*f)(void *),
void *data)
{
return ERR_PTR(-ENODEV);
}
static inline void debugfs_remove(struct dentry *dentry) static inline void debugfs_remove(struct dentry *dentry)
{ } { }
......
...@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name) ...@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name)
spin_unlock(&kset->list_lock); spin_unlock(&kset->list_lock);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(kset_find_obj);
static void kset_release(struct kobject *kobj) static void kset_release(struct kobject *kobj)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment