Commit 7ef58b32 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'devicetree-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux

Pull devicetree changes from Grant Likely:
 "Lots of activity in the devicetree code for v3.18.  Most of it is
  related to getting all of the overlay support code in place, but there
  are other important things in there.

  Highlights:

   - OF_RECONFIG notifiers for SPI, I2C and Platform devices.  Those
     subsystems can now respond to live changes to the device tree.

   - CONFIG_OF_OVERLAY method for applying live changes to the device
     tree

   - Removal of the of_allnodes list.  This used to be used to iterate
     over all the nodes in the device tree, but it is unnecessary
     because the same thing can be done by iterating over the list of
     child pointers.  Getting rid of of_allnodes saves some memory and
     avoids the possibility of of_allnodes being sorted differently from
     the child lists.

   - Support for retrieving original DTB blob via sysfs.  Needed by
     kexec.

   - More unittests

   - Documentation and minor bug fixes"

* tag 'devicetree-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux: (42 commits)
  of: Delete unnecessary check before calling "of_node_put()"
  of: Drop ->next pointer from struct device_node
  spi: Check for spi_of_notifier when CONFIG_OF_DYNAMIC=y
  of: support passing console options with stdout-path
  of: add optional options parameter to of_find_node_by_path()
  of: Add bindings for chosen node, stdout-path
  of: Remove unneeded and incorrect MODULE_DEVICE_TABLE
  ARM: dt: fix up PL011 device tree bindings
  of: base, fix of_property_read_string_helper kernel-doc
  of: remove select of non-existant OF_DEVICE config symbol
  spi/of: Add OF notifier handler
  spi/of: Create new device registration method and accessors
  i2c/of: Add OF_RECONFIG notifier handler
  i2c/of: Factor out Devicetree registration code
  of/overlay: Add overlay unittests
  of/overlay: Introduce DT overlay support
  of/reconfig: Add OF_DYNAMIC notifier for platform_bus_type
  of/reconfig: Always use the same structure for notifiers
  of/reconfig: Add debug output for OF_RECONFIG notifiers
  of/reconfig: Add empty stubs for the of_reconfig methods
  ...
parents 413fd0e3 c46ca3c8
The chosen node
---------------
The chosen node does not represent a real device, but serves as a place
for passing data between firmware and the operating system, like boot
arguments. Data in the chosen node does not represent the hardware.
stdout-path property
--------------------
Device trees may specify the device to be used for boot console output
with a stdout-path property under /chosen, as described in ePAPR, e.g.
/ {
chosen {
stdout-path = "/serial@f00:115200";
};
serial@f00 {
compatible = "vendor,some-uart";
reg = <0xf00 0x10>;
};
};
If the character ":" is present in the value, this terminates the path.
The meaning of any characters following the ":" is device-specific, and
must be specified in the relevant binding documentation.
For UART devices, the preferred binding is a string in the form:
<baud>{<parity>{<bits>{<flow>}}}
where
baud - baud rate in decimal
parity - 'n' (none), 'o', (odd) or 'e' (even)
bits - number of data bits
flow - 'r' (rts)
For example: 115200n8r
Implementation note: Linux will look for the property "linux,stdout-path" or
on PowerPC "stdout" if "stdout-path" is not found. However, the
"linux,stdout-path" and "stdout" properties are deprecated. New platforms
should only use the "stdout-path" property.
......@@ -6,12 +6,34 @@ Required properties:
- interrupts: exactly one interrupt specifier
Optional properties:
- pinctrl: When present, must have one state named "sleep"
and one state named "default"
- clocks: When present, must refer to exactly one clock named
- pinctrl: When present, must have one state named "default",
and may contain a second name named "sleep". The former
state sets up pins for ordinary operation whereas
the latter state will put the associated pins to sleep
when the UART is unused
- clocks: When present, the first clock listed must correspond to
the clock named UARTCLK on the IP block, i.e. the clock
to the external serial line, whereas the second clock
must correspond to the PCLK clocking the internal logic
of the block. Just listing one clock (the first one) is
deprecated.
- clocks-names: When present, the first clock listed must be named
"uartclk" and the second clock listed must be named
"apb_pclk"
- dmas: When present, may have one or two dma channels.
The first one must be named "rx", the second one
must be named "tx".
See also bindings/arm/primecell.txt
Example:
uart@80120000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x80120000 0x1000>;
interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma 13 0 0x2>, <&dma 13 0 0x0>;
dma-names = "rx", "tx";
clocks = <&foo_clk>, <&bar_clk>;
clock-names = "uartclk", "apb_pclk";
};
* OF selftest platform device
** selftest
Required properties:
- compatible: must be "selftest"
All other properties are optional.
Example:
selftest {
compatible = "selftest";
status = "okay";
};
......@@ -63,7 +63,6 @@ struct device_node {
struct device_node *parent;
struct device_node *child;
struct device_node *sibling;
struct device_node *allnext; /* next in list of all nodes */
...
};
......@@ -99,12 +98,6 @@ child11 -> sibling12 -> sibling13 -> sibling14 -> null
Figure 1: Generic structure of un-flattened device tree
*allnext: it is used to link all the nodes of DT into a list. So, for the
above tree the list would be as follows:
root->child1->child11->sibling12->sibling13->child131->sibling14->sibling2->
child21->sibling22->sibling23->sibling3->child31->sibling32->sibling4->null
Before executing OF selftest, it is required to attach the test data to
machine's device tree (if present). So, when selftest_data_add() is called,
at first it reads the flattened device tree data linked into the kernel image
......@@ -131,11 +124,6 @@ root ('/')
test-child01 null null null
allnext list:
root->testcase-data->test-child0->test-child01->test-sibling1->test-sibling2
->test-sibling3->null
Figure 2: Example test data tree to be attached to live tree.
According to the scenario above, the live tree is already present so it isn't
......@@ -204,8 +192,6 @@ detached and then moving up the parent nodes are removed, and eventually the
whole tree). selftest_data_remove() calls detach_node_and_children() that uses
of_detach_node() to detach the nodes from the live device tree.
To detach a node, of_detach_node() first updates all_next linked list, by
attaching the previous node's allnext to current node's allnext pointer. And
then, it either updates the child pointer of given node's parent to its
sibling or attaches the previous sibling to the given node's sibling, as
appropriate. That is it :)
To detach a node, of_detach_node() either updates the child pointer of given
node's parent to its sibling or attaches the previous sibling to the given
node's sibling, as appropriate. That is it :)
Device Tree Overlay Notes
-------------------------
This document describes the implementation of the in-kernel
device tree overlay functionality residing in drivers/of/overlay.c and is a
companion document to Documentation/devicetree/dt-object-internal.txt[1] &
Documentation/devicetree/dynamic-resolution-notes.txt[2]
How overlays work
-----------------
A Device Tree's overlay purpose is to modify the kernel's live tree, and
have the modification affecting the state of the the kernel in a way that
is reflecting the changes.
Since the kernel mainly deals with devices, any new device node that result
in an active device should have it created while if the device node is either
disabled or removed all together, the affected device should be deregistered.
Lets take an example where we have a foo board with the following base tree
which is taken from [1].
---- foo.dts -----------------------------------------------------------------
/* FOO platform */
/ {
compatible = "corp,foo";
/* shared resources */
res: res {
};
/* On chip peripherals */
ocp: ocp {
/* peripherals that are always instantiated */
peripheral1 { ... };
}
};
---- foo.dts -----------------------------------------------------------------
The overlay bar.dts, when loaded (and resolved as described in [2]) should
---- bar.dts -----------------------------------------------------------------
/plugin/; /* allow undefined label references and record them */
/ {
.... /* various properties for loader use; i.e. part id etc. */
fragment@0 {
target = <&ocp>;
__overlay__ {
/* bar peripheral */
bar {
compatible = "corp,bar";
... /* various properties and child nodes */
}
};
};
};
---- bar.dts -----------------------------------------------------------------
result in foo+bar.dts
---- foo+bar.dts -------------------------------------------------------------
/* FOO platform + bar peripheral */
/ {
compatible = "corp,foo";
/* shared resources */
res: res {
};
/* On chip peripherals */
ocp: ocp {
/* peripherals that are always instantiated */
peripheral1 { ... };
/* bar peripheral */
bar {
compatible = "corp,bar";
... /* various properties and child nodes */
}
}
};
---- foo+bar.dts -------------------------------------------------------------
As a result of the the overlay, a new device node (bar) has been created
so a bar platform device will be registered and if a matching device driver
is loaded the device will be created as expected.
Overlay in-kernel API
--------------------------------
The API is quite easy to use.
1. Call of_overlay_create() to create and apply an overlay. The return value
is a cookie identifying this overlay.
2. Call of_overlay_destroy() to remove and cleanup the overlay previously
created via the call to of_overlay_create(). Removal of an overlay that
is stacked by another will not be permitted.
Finally, if you need to remove all overlays in one-go, just call
of_overlay_destroy_all() which will remove every single one in the correct
order.
Overlay DTS Format
------------------
The DTS of an overlay should have the following format:
{
/* ignored properties by the overlay */
fragment@0 { /* first child node */
target=<phandle>; /* phandle target of the overlay */
or
target-path="/path"; /* target path of the overlay */
__overlay__ {
property-a; /* add property-a to the target */
node-a { /* add to an existing, or create a node-a */
...
};
};
}
fragment@1 { /* second child node */
...
};
/* more fragments follow */
}
Using the non-phandle based target method allows one to use a base DT which does
not contain a __symbols__ node, i.e. it was not compiled with the -@ option.
The __symbols__ node is only required for the target=<phandle> method, since it
contains the information required to map from a phandle to a tree location.
......@@ -2,7 +2,6 @@ Todo list for devicetree:
=== General structure ===
- Switch from custom lists to (h)list_head for nodes and properties structure
- Remove of_allnodes list and iterate using list of child nodes alone
=== CONFIG_OF_DYNAMIC ===
- Switch to RCU for tree updates and get rid of global spinlock
......
......@@ -1711,12 +1711,11 @@ static void stage_topology_update(int core_id)
static int dt_update_callback(struct notifier_block *nb,
unsigned long action, void *data)
{
struct of_prop_reconfig *update;
struct of_reconfig_data *update = data;
int rc = NOTIFY_DONE;
switch (action) {
case OF_RECONFIG_UPDATE_PROPERTY:
update = (struct of_prop_reconfig *)data;
if (!of_prop_cmp(update->dn->type, "cpu") &&
!of_prop_cmp(update->prop->name, "ibm,associativity")) {
u32 core_id;
......
......@@ -340,16 +340,17 @@ static void pseries_remove_processor(struct device_node *np)
}
static int pseries_smp_notifier(struct notifier_block *nb,
unsigned long action, void *node)
unsigned long action, void *data)
{
struct of_reconfig_data *rd = data;
int err = 0;
switch (action) {
case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_processor(node);
err = pseries_add_processor(rd->dn);
break;
case OF_RECONFIG_DETACH_NODE:
pseries_remove_processor(node);
pseries_remove_processor(rd->dn);
break;
}
return notifier_from_errno(err);
......
......@@ -183,7 +183,7 @@ static int pseries_add_mem_node(struct device_node *np)
return (ret < 0) ? -EINVAL : 0;
}
static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
{
struct of_drconf_cell *new_drmem, *old_drmem;
unsigned long memblock_size;
......@@ -232,22 +232,21 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
}
static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *node)
unsigned long action, void *data)
{
struct of_prop_reconfig *pr;
struct of_reconfig_data *rd = data;
int err = 0;
switch (action) {
case OF_RECONFIG_ATTACH_NODE:
err = pseries_add_mem_node(node);
err = pseries_add_mem_node(rd->dn);
break;
case OF_RECONFIG_DETACH_NODE:
err = pseries_remove_mem_node(node);
err = pseries_remove_mem_node(rd->dn);
break;
case OF_RECONFIG_UPDATE_PROPERTY:
pr = (struct of_prop_reconfig *)node;
if (!strcmp(pr->prop->name, "ibm,dynamic-memory"))
err = pseries_update_drconf_memory(pr);
if (!strcmp(rd->prop->name, "ibm,dynamic-memory"))
err = pseries_update_drconf_memory(rd);
break;
}
return notifier_from_errno(err);
......
......@@ -1251,10 +1251,11 @@ static struct notifier_block iommu_mem_nb = {
.notifier_call = iommu_mem_notifier,
};
static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data)
{
int err = NOTIFY_OK;
struct device_node *np = node;
struct of_reconfig_data *rd = data;
struct device_node *np = rd->dn;
struct pci_dn *pci = PCI_DN(np);
struct direct_window *window;
......
......@@ -251,9 +251,10 @@ static void __init pseries_discover_pic(void)
" interrupt-controller\n");
}
static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data)
{
struct device_node *np = node;
struct of_reconfig_data *rd = data;
struct device_node *np = rd->dn;
struct pci_dn *pci = NULL;
int err = NOTIFY_OK;
......
......@@ -1006,6 +1006,7 @@ int __init platform_bus_init(void)
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
of_platform_register_reconfig_notifier();
return error;
}
......
......@@ -1009,9 +1009,9 @@ error_out:
* notifier_to_errno() to decode this value
*/
static int nx842_OF_notifier(struct notifier_block *np, unsigned long action,
void *update)
void *data)
{
struct of_prop_reconfig *upd = update;
struct of_reconfig_data *upd = data;
struct nx842_devdata *local_devdata;
struct device_node *node = NULL;
......
......@@ -49,6 +49,7 @@
#include <linux/acpi.h>
#include <linux/jump_label.h>
#include <asm/uaccess.h>
#include <linux/err.h>
#include "i2c-core.h"
......@@ -1369,63 +1370,69 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
/* OF support code */
#if IS_ENABLED(CONFIG_OF)
static void of_i2c_register_devices(struct i2c_adapter *adap)
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
struct device_node *node)
{
void *result;
struct device_node *node;
struct i2c_client *result;
struct i2c_board_info info = {};
struct dev_archdata dev_ad = {};
const __be32 *addr;
int len;
/* Only register child devices if the adapter has a node pointer set */
if (!adap->dev.of_node)
return;
dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
node->full_name);
return ERR_PTR(-EINVAL);
}
for_each_available_child_of_node(adap->dev.of_node, node) {
struct i2c_board_info info = {};
struct dev_archdata dev_ad = {};
const __be32 *addr;
int len;
addr = of_get_property(node, "reg", &len);
if (!addr || (len < sizeof(int))) {
dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
node->full_name);
return ERR_PTR(-EINVAL);
}
dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
info.addr = be32_to_cpup(addr);
if (info.addr > (1 << 10) - 1) {
dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
info.addr, node->full_name);
return ERR_PTR(-EINVAL);
}
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
node->full_name);
continue;
}
info.irq = irq_of_parse_and_map(node, 0);
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
addr = of_get_property(node, "reg", &len);
if (!addr || (len < sizeof(int))) {
dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
node->full_name);
continue;
}
if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE;
info.addr = be32_to_cpup(addr);
if (info.addr > (1 << 10) - 1) {
dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
info.addr, node->full_name);
continue;
}
request_module("%s%s", I2C_MODULE_PREFIX, info.type);
result = i2c_new_device(adap, &info);
if (result == NULL) {
dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
node->full_name);
of_node_put(node);
irq_dispose_mapping(info.irq);
return ERR_PTR(-EINVAL);
}
return result;
}
info.irq = irq_of_parse_and_map(node, 0);
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
static void of_i2c_register_devices(struct i2c_adapter *adap)
{
struct device_node *node;
if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE;
/* Only register child devices if the adapter has a node pointer set */
if (!adap->dev.of_node)
return;
request_module("%s%s", I2C_MODULE_PREFIX, info.type);
dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
result = i2c_new_device(adap, &info);
if (result == NULL) {
dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
node->full_name);
of_node_put(node);
irq_dispose_mapping(info.irq);
continue;
}
}
for_each_available_child_of_node(adap->dev.of_node, node)
of_i2c_register_device(adap, node);
}
static int of_dev_node_match(struct device *dev, void *data)
......@@ -1945,6 +1952,52 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
}
EXPORT_SYMBOL(i2c_clients_command);
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
void *arg)
{
struct of_reconfig_data *rd = arg;
struct i2c_adapter *adap;
struct i2c_client *client;
switch (of_reconfig_get_state_change(action, rd)) {
case OF_RECONFIG_CHANGE_ADD:
adap = of_find_i2c_adapter_by_node(rd->dn->parent);
if (adap == NULL)
return NOTIFY_OK; /* not for us */
client = of_i2c_register_device(adap, rd->dn);
put_device(&adap->dev);
if (IS_ERR(client)) {
pr_err("%s: failed to create for '%s'\n",
__func__, rd->dn->full_name);
return notifier_from_errno(PTR_ERR(client));
}
break;
case OF_RECONFIG_CHANGE_REMOVE:
/* find our device by node */
client = of_find_i2c_device_by_node(rd->dn);
if (client == NULL)
return NOTIFY_OK; /* no? not meant for us */
/* unregister takes one ref away */
i2c_unregister_device(client);
/* and put the reference of the find */
put_device(&client->dev);
break;
}
return NOTIFY_OK;
}
static struct notifier_block i2c_of_notifier = {
.notifier_call = of_i2c_notify,
};
#else
extern struct notifier_block i2c_of_notifier;
#endif /* CONFIG_OF_DYNAMIC */
static int __init i2c_init(void)
{
int retval;
......@@ -1962,6 +2015,10 @@ static int __init i2c_init(void)
retval = i2c_add_driver(&dummy_driver);
if (retval)
goto class_err;
if (IS_ENABLED(CONFIG_OF_DYNAMIC))
WARN_ON(of_reconfig_notifier_register(&i2c_of_notifier));
return 0;
class_err:
......@@ -1975,6 +2032,8 @@ bus_err:
static void __exit i2c_exit(void)
{
if (IS_ENABLED(CONFIG_OF_DYNAMIC))
WARN_ON(of_reconfig_notifier_unregister(&i2c_of_notifier));
i2c_del_driver(&dummy_driver);
#ifdef CONFIG_I2C_COMPAT
class_compat_unregister(i2c_adapter_compat_class);
......