Commit 5339f9d4 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull DeviceTree updates from Rob Herring:

 - Rework and export the changeset API to make it available to users
   other than DT overlays

 - ARM secure devices binding

 - OCTEON USB binding

 - Clean-up of various SRAM binding docs

 - Various other binding doc updates

* tag 'devicetree-for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (21 commits)
  drivers/of: Export OF changeset functions
  Fix documentation for adp1653 DT
  ARM: psci: Fix indentation in DT bindings
  of/platform: export of_default_bus_match_table
  of/unittest: Show broken behaviour in the platform bus
  of: fix declaration of of_io_request_and_map
  of/address: replace printk(KERN_ERR ...) with pr_err(...)
  of/irq: optimize device node matching loop in of_irq_init()
  dt-bindings: tda998x: Document the required 'port' node.
  net/macb: bindings doc: Merge cdns-emac to macb
  dt-bindings: Misc fix for the ATH79 DDR controllers
  dt-bindings: Misc fix for the ATH79 MISC interrupt controllers
  Documentation: dt: Add bindings for Secure-only devices
  dt-bindings: ARM: add arm,cortex-a72 compatible string
  ASoC: Atmel: ClassD: add GCK's parent clock in DT binding
  DT: add Olimex to vendor prefixes
  Documentation: fsl-quadspi: Add fsl,ls1021-qspi compatible string
  Documentation/devicetree: document OCTEON USB bindings
  usb: misc: usb3503: Describe better how to bind clock to the hub
  dt-bindings: Consolidate SRAM bindings from all vendors
  ...
parents cf8d7e38 18322377
...@@ -63,7 +63,7 @@ Required properties: ...@@ -63,7 +63,7 @@ Required properties:
- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno - compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno
The rest of the properties should follow the generic mmio-sram description The rest of the properties should follow the generic mmio-sram description
found in ../../misc/sysram.txt found in ../../sram/sram.txt
Each sub-node represents the reserved area for SCPI. Each sub-node represents the reserved area for SCPI.
......
...@@ -157,6 +157,7 @@ nodes to be present and contain the properties described below. ...@@ -157,6 +157,7 @@ nodes to be present and contain the properties described below.
"arm,cortex-a17" "arm,cortex-a17"
"arm,cortex-a53" "arm,cortex-a53"
"arm,cortex-a57" "arm,cortex-a57"
"arm,cortex-a72"
"arm,cortex-m0" "arm,cortex-m0"
"arm,cortex-m0+" "arm,cortex-m0+"
"arm,cortex-m1" "arm,cortex-m1"
......
...@@ -23,17 +23,20 @@ Main node required properties: ...@@ -23,17 +23,20 @@ Main node required properties:
- compatible : should contain at least one of: - compatible : should contain at least one of:
* "arm,psci" : for implementations complying to PSCI versions prior to * "arm,psci" : For implementations complying to PSCI versions prior
0.2. For these cases function IDs must be provided. to 0.2.
For these cases function IDs must be provided.
* "arm,psci-0.2" : for implementations complying to PSCI 0.2. Function
IDs are not required and should be ignored by an OS with PSCI 0.2 * "arm,psci-0.2" : For implementations complying to PSCI 0.2.
support, but are permitted to be present for compatibility with Function IDs are not required and should be ignored by
existing software when "arm,psci" is later in the compatible list. an OS with PSCI 0.2 support, but are permitted to be
present for compatibility with existing software when
* "arm,psci-1.0" : for implementations complying to PSCI 1.0. PSCI 1.0 is "arm,psci" is later in the compatible list.
backward compatible with PSCI 0.2 with minor specification updates,
as defined in the PSCI specification[2]. * "arm,psci-1.0" : For implementations complying to PSCI 1.0.
PSCI 1.0 is backward compatible with PSCI 0.2 with
minor specification updates, as defined in the PSCI
specification[2].
- method : The method of calling the PSCI firmware. Permitted - method : The method of calling the PSCI firmware. Permitted
values are: values are:
......
* ARM Secure world bindings
ARM CPUs with TrustZone support have two distinct address spaces,
"Normal" and "Secure". Most devicetree consumers (including the Linux
kernel) are not TrustZone aware and run entirely in either the Normal
world or the Secure world. However some devicetree consumers are
TrustZone aware and need to be able to determine whether devices are
visible only in the Secure address space, only in the Normal address
space, or visible in both. (One example of that situation would be a
virtual machine which boots Secure firmware and wants to tell the
firmware about the layout of the machine via devicetree.)
The general principle of the naming scheme for Secure world bindings
is that any property that needs a different value in the Secure world
can be supported by prefixing the property name with "secure-". So for
instance "secure-foo" would override "foo". For property names with
a vendor prefix, the Secure variant of "vendor,foo" would be
"vendor,secure-foo". If there is no "secure-" property then the Secure
world value is the same as specified for the Normal world by the
non-prefixed property. However, only the properties listed below may
validly have "secure-" versions; this list will be enlarged on a
case-by-case basis.
Defining the bindings in this way means that a device tree which has
been annotated to indicate the presence of Secure-only devices can
still be processed unmodified by existing Non-secure software (and in
particular by the kernel).
Note that it is still valid for bindings intended for purely Secure
world consumers (like kernels that run entirely in Secure) to simply
describe the view of Secure world using the standard bindings. These
secure- bindings only need to be used where both the Secure and Normal
world views need to be described in a single device tree.
Valid Secure world properties:
- secure-status : specifies whether the device is present and usable
in the secure world. The combination of this with "status" allows
the various possible combinations of device visibility to be
specified. If "secure-status" is not specified it defaults to the
same value as "status"; if "status" is not specified either then
both default to "okay". This means the following combinations are
possible:
/* Neither specified: default to visible in both S and NS */
secure-status = "okay"; /* visible in both */
status = "okay"; /* visible in both */
status = "okay"; secure-status = "okay"; /* visible in both */
secure-status = "disabled"; /* NS-only */
status = "okay"; secure-status = "disabled"; /* NS-only */
status = "disabled"; secure-status = "okay"; /* S-only */
status = "disabled"; /* disabled in both */
status = "disabled"; secure-status = "disabled"; /* disabled in both */
...@@ -5,6 +5,10 @@ Required properties; ...@@ -5,6 +5,10 @@ Required properties;
- reg: I2C address - reg: I2C address
Required node:
- port: Input port node with endpoint definition, as described
in Documentation/devicetree/bindings/graph.txt
Optional properties: Optional properties:
- interrupts: interrupt number and trigger type - interrupts: interrupt number and trigger type
default: polling default: polling
......
...@@ -22,7 +22,7 @@ Interrupt Controllers bindings used by client devices. ...@@ -22,7 +22,7 @@ Interrupt Controllers bindings used by client devices.
Example: Example:
interrupt-controller@18060010 { interrupt-controller@18060010 {
compatible = "qca,ar9132-misc-intc", qca,ar7100-misc-intc"; compatible = "qca,ar9132-misc-intc", "qca,ar7100-misc-intc";
reg = <0x18060010 0x4>; reg = <0x18060010 0x4>;
interrupt-parent = <&cpuintc>; interrupt-parent = <&cpuintc>;
......
...@@ -12,12 +12,13 @@ There are two LED outputs available - flash and indicator. One LED is ...@@ -12,12 +12,13 @@ There are two LED outputs available - flash and indicator. One LED is
represented by one child node, nodes need to be named "flash" and "indicator". represented by one child node, nodes need to be named "flash" and "indicator".
Required properties of the LED child node: Required properties of the LED child node:
- max-microamp : see Documentation/devicetree/bindings/leds/common.txt - led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
Required properties of the flash LED child node: Required properties of the flash LED child node:
- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt - flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
- flash-timeout-us : see Documentation/devicetree/bindings/leds/common.txt - flash-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
Example: Example:
...@@ -29,9 +30,9 @@ Example: ...@@ -29,9 +30,9 @@ Example:
flash { flash {
flash-timeout-us = <500000>; flash-timeout-us = <500000>;
flash-max-microamp = <320000>; flash-max-microamp = <320000>;
max-microamp = <50000>; led-max-microamp = <50000>;
}; };
indicator { indicator {
max-microamp = <17500>; led-max-microamp = <17500>;
}; };
}; };
Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller Binding for Qualcomm Atheros AR7xxx/AR9xxx DDR controller
The DDR controller of the ARxxx and AR9xxx families provides an interface The DDR controller of the AR7xxx and AR9xxx families provides an interface
to flush the FIFO between various devices and the DDR. This is mainly used to flush the FIFO between various devices and the DDR. This is mainly used
by the IRQ controller to flush the FIFO before running the interrupt handler by the IRQ controller to flush the FIFO before running the interrupt handler
of such devices. of such devices.
...@@ -11,9 +11,9 @@ Required properties: ...@@ -11,9 +11,9 @@ Required properties:
"qca,[ar7100|ar7240]-ddr-controller" as fallback. "qca,[ar7100|ar7240]-ddr-controller" as fallback.
On SoC with PCI support "qca,ar7100-ddr-controller" should be used as On SoC with PCI support "qca,ar7100-ddr-controller" should be used as
fallback, otherwise "qca,ar7240-ddr-controller" should be used. fallback, otherwise "qca,ar7240-ddr-controller" should be used.
- reg: Base address and size of the controllers memory area - reg: Base address and size of the controller's memory area
- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer - #qca,ddr-wb-channel-cells: Specifies the number of cells needed to encode
channel the write buffer channel index, should be 1.
Example: Example:
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
Required properties: Required properties:
- compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi", - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi",
"fsl,imx7d-qspi", "fsl,imx6ul-qspi" "fsl,imx7d-qspi", "fsl,imx6ul-qspi",
"fsl,ls1021-qspi"
- reg : the first contains the register location and length, - reg : the first contains the register location and length,
the second contains the memory mapping address and length the second contains the memory mapping address and length
- reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory" - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"
......
* Cadence EMAC Ethernet controller
Required properties:
- compatible: Should be "cdns,[<chip>-]{emac}"
Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
Or the generic form: "cdns,emac".
- reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt
- phy-mode: see ethernet.txt file in the same directory.
Examples:
macb0: ethernet@fffc4000 {
compatible = "cdns,at91rm9200-emac";
reg = <0xfffc4000 0x4000>;
interrupts = <21>;
phy-mode = "rmii";
local-mac-address = [3a 0e 03 04 05 06];
};
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
Required properties: Required properties:
- compatible: Should be "cdns,[<chip>-]{macb|gem}" - compatible: Should be "cdns,[<chip>-]{macb|gem}"
Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs or the 10/100Mbit IP Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs or the 10/100Mbit IP
available on sama5d3 SoCs. available on sama5d3 SoCs.
Use "cdns,np4-macb" for NP4 SoC devices. Use "cdns,np4-macb" for NP4 SoC devices.
...@@ -11,7 +12,9 @@ Required properties: ...@@ -11,7 +12,9 @@ Required properties:
Use "atmel,sama5d2-gem" for the GEM IP (10/100) available on Atmel sama5d2 SoCs. Use "atmel,sama5d2-gem" for the GEM IP (10/100) available on Atmel sama5d2 SoCs.
Use "atmel,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs. Use "atmel,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs.
Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs. Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs.
Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC. Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC.
Or the generic form: "cdns,emac".
- reg: Address and length of the register set for the device - reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt - interrupts: Should contain macb interrupt
- phy-mode: See ethernet.txt file in the same directory. - phy-mode: See ethernet.txt file in the same directory.
......
...@@ -16,6 +16,10 @@ Required properties: ...@@ -16,6 +16,10 @@ Required properties:
Required elements: "pclk", "gclk" and "aclk". Required elements: "pclk", "gclk" and "aclk".
- clocks - clocks
Please refer to clock-bindings.txt. Please refer to clock-bindings.txt.
- assigned-clocks
Should be <&classd_gclk>.
- assigned-clock-parents
Should be <&audio_pll_pmc>.
Optional properties: Optional properties:
- pinctrl-names, pinctrl-0 - pinctrl-names, pinctrl-0
...@@ -43,6 +47,8 @@ classd: classd@fc048000 { ...@@ -43,6 +47,8 @@ classd: classd@fc048000 {
dma-names = "tx"; dma-names = "tx";
clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>;
clock-names = "pclk", "gclk", "aclk"; clock-names = "pclk", "gclk", "aclk";
assigned-clocks = <&classd_gclk>;
assigned-clock-parents = <&audio_pll_pmc>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_classd_default>; pinctrl-0 = <&pinctrl_classd_default>;
......
...@@ -12,7 +12,7 @@ Required sub-node properties: ...@@ -12,7 +12,7 @@ Required sub-node properties:
- compatible : should be "rockchip,rk3066-smp-sram" - compatible : should be "rockchip,rk3066-smp-sram"
The rest of the properties should follow the generic mmio-sram discription The rest of the properties should follow the generic mmio-sram discription
found in ../../misc/sram.txt found in Documentation/devicetree/bindings/sram/sram.txt
Example: Example:
......
...@@ -15,7 +15,7 @@ Required sub-node properties: ...@@ -15,7 +15,7 @@ Required sub-node properties:
"samsung,exynos4210-sysram-ns" : for Non-secure SYSRAM "samsung,exynos4210-sysram-ns" : for Non-secure SYSRAM
The rest of the properties should follow the generic mmio-sram discription The rest of the properties should follow the generic mmio-sram discription
found in ../../misc/sysram.txt found in Documentation/devicetree/bindings/sram/sram.txt
Example: Example:
......
...@@ -16,7 +16,7 @@ SRAM nodes ...@@ -16,7 +16,7 @@ SRAM nodes
---------- ----------
Each SRAM is described using the mmio-sram bindings documented in Each SRAM is described using the mmio-sram bindings documented in
Documentation/devicetree/bindings/misc/sram.txt Documentation/devicetree/bindings/sram/sram.txt
Each SRAM will have SRAM sections that are going to be handled by the Each SRAM will have SRAM sections that are going to be handled by the
SRAM controller as subnodes. These sections are represented following SRAM controller as subnodes. These sections are represented following
......
OCTEON/OCTEON+ USB BLOCK
1) Main node
Required properties:
- compatible: must be "cavium,octeon-5750-usbn"
- reg: specifies the physical base address of the USBN block and
the length of the memory mapped region.
- #address-cells: specifies the number of cells needed to encode an
address. The value must be 2.
- #size-cells: specifies the number of cells used to represent the size
of an address. The value must be 2.
- ranges: specifies the translation between child address space and parent
address space.
- clock-frequency: speed of the USB reference clock. Allowed values are
12000000, 24000000 or 48000000.
- cavium,refclk-type: type of the USB reference clock. Allowed values are
"crystal" or "external".
- refclk-frequency: deprecated, use "clock-frequency".
- refclk-type: deprecated, use "cavium,refclk-type".
2) Child node
The main node must have one child node which describes the built-in
USB controller.
Required properties:
- compatible: must be "cavium,octeon-5750-usbc"
- reg: specifies the physical base address of the USBC block and
the length of the memory mapped region.
- interrupts: specifies the interrupt number for the USB controller.
3) Example:
usbn: usbn@1180068000000 {
compatible = "cavium,octeon-5750-usbn";
reg = <0x11800 0x68000000 0x0 0x1000>;
ranges; /* Direct mapping */
#address-cells = <2>;
#size-cells = <2>;
clock-frequency = <12000000>;
cavium,refclk-type = "crystal";
usbc@16f0010000000 {
compatible = "cavium,octeon-5750-usbc";
reg = <0x16f00 0x10000000 0x0 0x80000>;
interrupts = <0 56>;
};
};
...@@ -18,7 +18,8 @@ Optional properties: ...@@ -18,7 +18,8 @@ Optional properties:
- refclk: Clock used for driving REFCLK signal (optional, if not provided - refclk: Clock used for driving REFCLK signal (optional, if not provided
the driver assumes that clock signal is always available, its the driver assumes that clock signal is always available, its
rate is specified by REF_SEL pins and a value from the primary rate is specified by REF_SEL pins and a value from the primary
reference clock frequencies table is used) reference clock frequencies table is used). Use clocks and
clock-names in order to assign it
- refclk-frequency: Frequency of the REFCLK signal as defined by REF_SEL - refclk-frequency: Frequency of the REFCLK signal as defined by REF_SEL
pins (optional, if not provided, driver will not set rate of the pins (optional, if not provided, driver will not set rate of the
REFCLK signal and assume that a value from the primary reference REFCLK signal and assume that a value from the primary reference
...@@ -33,4 +34,6 @@ Examples: ...@@ -33,4 +34,6 @@ Examples:
intn-gpios = <&gpx3 4 1>; intn-gpios = <&gpx3 4 1>;
reset-gpios = <&gpx3 5 1>; reset-gpios = <&gpx3 5 1>;
initial-mode = <1>; initial-mode = <1>;
clocks = <&clks 80>;
clock-names = "refclk";
}; };
...@@ -161,6 +161,7 @@ nuvoton Nuvoton Technology Corporation ...@@ -161,6 +161,7 @@ nuvoton Nuvoton Technology Corporation
nvidia NVIDIA nvidia NVIDIA
nxp NXP Semiconductors nxp NXP Semiconductors
okaya Okaya Electric America, Inc. okaya Okaya Electric America, Inc.
olimex OLIMEX Ltd.
onnn ON Semiconductor Corp. onnn ON Semiconductor Corp.
opencores OpenCores.org opencores OpenCores.org
option Option NV option Option NV
......
...@@ -597,7 +597,7 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -597,7 +597,7 @@ static u64 __of_translate_address(struct device_node *dev,
pbus = of_match_bus(parent); pbus = of_match_bus(parent);
pbus->count_cells(dev, &pna, &pns); pbus->count_cells(dev, &pna, &pns);
if (!OF_CHECK_COUNTS(pna, pns)) { if (!OF_CHECK_COUNTS(pna, pns)) {
printk(KERN_ERR "prom_parse: Bad cell count for %s\n", pr_err("prom_parse: Bad cell count for %s\n",
of_node_full_name(dev)); of_node_full_name(dev));
break; break;
} }
......
...@@ -646,6 +646,7 @@ void of_changeset_init(struct of_changeset *ocs) ...@@ -646,6 +646,7 @@ void of_changeset_init(struct of_changeset *ocs)
memset(ocs, 0, sizeof(*ocs)); memset(ocs, 0, sizeof(*ocs));
INIT_LIST_HEAD(&ocs->entries); INIT_LIST_HEAD(&ocs->entries);
} }
EXPORT_SYMBOL_GPL(of_changeset_init);
/** /**
* of_changeset_destroy - Destroy a changeset * of_changeset_destroy - Destroy a changeset
...@@ -662,20 +663,9 @@ void of_changeset_destroy(struct of_changeset *ocs) ...@@ -662,20 +663,9 @@ void of_changeset_destroy(struct of_changeset *ocs)
list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node) list_for_each_entry_safe_reverse(ce, cen, &ocs->entries, node)
__of_changeset_entry_destroy(ce); __of_changeset_entry_destroy(ce);
} }
EXPORT_SYMBOL_GPL(of_changeset_destroy);
/** int __of_changeset_apply(struct of_changeset *ocs)
* of_changeset_apply - Applies a changeset
*
* @ocs: changeset pointer
*
* Applies a changeset to the live tree.
* Any side-effects of live tree state changes are applied here on
* sucess, like creation/destruction of devices and side-effects
* like creation of sysfs properties and directories.
* Returns 0 on success, a negative error value in case of an error.
* On error the partially applied effects are reverted.
*/
int of_changeset_apply(struct of_changeset *ocs)
{ {
struct of_changeset_entry *ce; struct of_changeset_entry *ce;
int ret; int ret;
...@@ -704,17 +694,30 @@ int of_changeset_apply(struct of_changeset *ocs) ...@@ -704,17 +694,30 @@ int of_changeset_apply(struct of_changeset *ocs)
} }
/** /**
* of_changeset_revert - Reverts an applied changeset * of_changeset_apply - Applies a changeset
* *
* @ocs: changeset pointer * @ocs: changeset pointer
* *
* Reverts a changeset returning the state of the tree to what it * Applies a changeset to the live tree.
* was before the application. * Any side-effects of live tree state changes are applied here on
* Any side-effects like creation/destruction of devices and * success, like creation/destruction of devices and side-effects
* removal of sysfs properties and directories are applied. * like creation of sysfs properties and directories.
* Returns 0 on success, a negative error value in case of an error. * Returns 0 on success, a negative error value in case of an error.
* On error the partially applied effects are reverted.
*/ */
int of_changeset_revert(struct of_changeset *ocs) int of_changeset_apply(struct of_changeset *ocs)
{
int ret;
mutex_lock(&of_mutex);
ret = __of_changeset_apply(ocs);
mutex_unlock(&of_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(of_changeset_apply);
int __of_changeset_revert(struct of_changeset *ocs)
{ {
struct of_changeset_entry *ce; struct of_changeset_entry *ce;
int ret; int ret;
...@@ -741,6 +744,29 @@ int of_changeset_revert(struct of_changeset *ocs) ...@@ -741,6 +744,29 @@ int of_changeset_revert(struct of_changeset *ocs)
return 0; return 0;
} }
/**
* of_changeset_revert - Reverts an applied changeset
*
* @ocs: changeset pointer
*
* Reverts a changeset returning the state of the tree to what it
* was before the application.
* Any side-effects like creation/destruction of devices and
* removal of sysfs properties and directories are applied.
* Returns 0 on success, a negative error value in case of an error.
*/
int of_changeset_revert(struct of_changeset *ocs)
{
int ret;
mutex_lock(&of_mutex);
ret = __of_changeset_revert(ocs);
mutex_unlock(&of_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(of_changeset_revert);
/** /**
* of_changeset_action - Perform a changeset action * of_changeset_action - Perform a changeset action
* *
...@@ -779,3 +805,4 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, ...@@ -779,3 +805,4 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action,
list_add_tail(&ce->node, &ocs->entries); list_add_tail(&ce->node, &ocs->entries);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(of_changeset_action);
...@@ -473,6 +473,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource_table); ...@@ -473,6 +473,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
struct of_intc_desc { struct of_intc_desc {
struct list_head list; struct list_head list;
of_irq_init_cb_t irq_init_cb;
struct device_node *dev; struct device_node *dev;
struct device_node *interrupt_parent; struct device_node *interrupt_parent;
}; };
...@@ -486,6 +487,7 @@ struct of_intc_desc { ...@@ -486,6 +487,7 @@ struct of_intc_desc {
*/ */
void __init of_irq_init(const struct of_device_id *matches) void __init of_irq_init(const struct of_device_id *matches)
{ {
const struct of_device_id *match;
struct device_node *np, *parent = NULL; struct device_node *np, *parent = NULL;
struct of_intc_desc *desc, *temp_desc; struct of_intc_desc *desc, *temp_desc;
struct list_head intc_desc_list, intc_parent_list; struct list_head intc_desc_list, intc_parent_list;
...@@ -493,10 +495,15 @@ void __init of_irq_init(const struct of_device_id *matches) ...@@ -493,10 +495,15 @@ void __init of_irq_init(const struct of_device_id *matches)
INIT_LIST_HEAD(&intc_desc_list); INIT_LIST_HEAD(&intc_desc_list);
INIT_LIST_HEAD(&intc_parent_list); INIT_LIST_HEAD(&intc_parent_list);
for_each_matching_node(np, matches) { for_each_matching_node_and_match(np, matches, &match) {
if (!of_find_property(np, "interrupt-controller", NULL) || if (!of_find_property(np, "interrupt-controller", NULL) ||
!of_device_is_available(np)) !of_device_is_available(np))
continue; continue;
if (WARN(!match->data, "of_irq_init: no init function for %s\n",
match->compatible))
continue;
/* /*
* Here, we allocate and populate an of_intc_desc with the node * Here, we allocate and populate an of_intc_desc with the node
* pointer, interrupt-parent device_node etc. * pointer, interrupt-parent device_node etc.
...@@ -507,6 +514,7 @@ void __init of_irq_init(const struct of_device_id *matches) ...@@ -507,6 +514,7 @@ void __init of_irq_init(const struct of_device_id *matches)
goto err; goto err;
} }
desc->irq_init_cb = match->data;
desc->dev = of_node_get(np); desc->dev = of_node_get(np);
desc->interrupt_parent = of_irq_find_parent(np); desc->interrupt_parent = of_irq_find_parent(np);
if (desc->interrupt_parent == np) if (desc->interrupt_parent == np)
...@@ -526,27 +534,18 @@ void __init of_irq_init(const struct of_device_id *matches) ...@@ -526,27 +534,18 @@ void __init of_irq_init(const struct of_device_id *matches)
* The assumption is that NULL parent means a root controller. * The assumption is that NULL parent means a root controller.
*/ */
list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
const struct of_device_id *match;
int ret; int ret;
of_irq_init_cb_t irq_init_cb;
if (desc->interrupt_parent != parent) if (desc->interrupt_parent != parent)
continue; continue;
list_del(&desc->list); list_del(&desc->list);
match = of_match_node(matches, desc->dev);
if (WARN(!match->data,
"of_irq_init: no init function for %s\n",
match->compatible)) {
kfree(desc);
continue;
}
pr_debug("of_irq_init: init %s @ %p, parent %p\n", pr_debug("of_irq_init: init %s (%p), parent %p\n",
match->compatible, desc->dev->full_name,
desc->dev, desc->interrupt_parent); desc->dev, desc->interrupt_parent);
irq_init_cb = (of_irq_init_cb_t)match->data; ret = desc->irq_init_cb(desc->dev,
ret = irq_init_cb(desc->dev, desc->interrupt_parent); desc->interrupt_parent);
if (ret) { if (ret) {
kfree(desc); kfree(desc);
continue; continue;
......
...@@ -45,6 +45,8 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj) ...@@ -45,6 +45,8 @@ static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
extern int of_property_notify(int action, struct device_node *np, extern int of_property_notify(int action, struct device_node *np,
struct property *prop, struct property *old_prop); struct property *prop, struct property *old_prop);
extern void of_node_release(struct kobject *kobj); extern void of_node_release(struct kobject *kobj);
extern int __of_changeset_apply(struct of_changeset *ocs);
extern int __of_changeset_revert(struct of_changeset *ocs);
#else /* CONFIG_OF_DYNAMIC */ #else /* CONFIG_OF_DYNAMIC */
static inline int of_property_notify(int action, struct device_node *np, static inline int of_property_notify(int action, struct device_node *np,
struct property *prop, struct property *old_prop) struct property *prop, struct property *old_prop)
......
...@@ -379,9 +379,9 @@ int of_overlay_create(struct device_node *tree) ...@@ -379,9 +379,9 @@ int of_overlay_create(struct device_node *tree)
} }
/* apply the changeset */ /* apply the changeset */
err = of_changeset_apply(&ov->cset); err = __of_changeset_apply(&ov->cset);
if (err) { if (err) {
pr_err("%s: of_changeset_apply() failed for tree@%s\n", pr_err("%s: __of_changeset_apply() failed for tree@%s\n",
__func__, tree->full_name); __func__, tree->full_name);
goto err_revert_overlay; goto err_revert_overlay;
} }
...@@ -511,7 +511,7 @@ int of_overlay_destroy(int id) ...@@ -511,7 +511,7 @@ int of_overlay_destroy(int id)
list_del(&ov->node); list_del(&ov->node);
of_changeset_revert(&ov->cset); __of_changeset_revert(&ov->cset);
of_free_overlay_info(ov); of_free_overlay_info(ov);
idr_remove(&ov_idr, id); idr_remove(&ov_idr, id);
of_changeset_destroy(&ov->cset); of_changeset_destroy(&ov->cset);
...@@ -542,7 +542,7 @@ int of_overlay_destroy_all(void) ...@@ -542,7 +542,7 @@ int of_overlay_destroy_all(void)
/* the tail of list is guaranteed to be safe to remove */ /* the tail of list is guaranteed to be safe to remove */
list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) { list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) {
list_del(&ov->node); list_del(&ov->node);
of_changeset_revert(&ov->cset); __of_changeset_revert(&ov->cset);
of_free_overlay_info(ov); of_free_overlay_info(ov);
idr_remove(&ov_idr, ov->id); idr_remove(&ov_idr, ov->id);
kfree(ov); kfree(ov);
......
...@@ -31,6 +31,7 @@ const struct of_device_id of_default_bus_match_table[] = { ...@@ -31,6 +31,7 @@ const struct of_device_id of_default_bus_match_table[] = {
#endif /* CONFIG_ARM_AMBA */ #endif /* CONFIG_ARM_AMBA */
{} /* Empty terminated list */ {} /* Empty terminated list */
}; };
EXPORT_SYMBOL(of_default_bus_match_table);
static int of_dev_node_match(struct device *dev, void *data) static int of_dev_node_match(struct device *dev, void *data)
{ {
......
...@@ -530,18 +530,14 @@ static void __init of_unittest_changeset(void) ...@@ -530,18 +530,14 @@ static void __init of_unittest_changeset(void)
unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n"); unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop\n");
unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n"); unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n");
unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n"); unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n");
mutex_lock(&of_mutex);
unittest(!of_changeset_apply(&chgset), "apply failed\n"); unittest(!of_changeset_apply(&chgset), "apply failed\n");
mutex_unlock(&of_mutex);
/* Make sure node names are constructed correctly */ /* Make sure node names are constructed correctly */
unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")),
"'%s' not added\n", n21->full_name); "'%s' not added\n", n21->full_name);
of_node_put(np); of_node_put(np);
mutex_lock(&of_mutex);
unittest(!of_changeset_revert(&chgset), "revert failed\n"); unittest(!of_changeset_revert(&chgset), "revert failed\n");
mutex_unlock(&of_mutex);
of_changeset_destroy(&chgset); of_changeset_destroy(&chgset);
#endif #endif
...@@ -757,6 +753,11 @@ static void __init of_unittest_match_node(void) ...@@ -757,6 +753,11 @@ static void __init of_unittest_match_node(void)
} }
} }
static struct resource test_bus_res = {
.start = 0xfffffff8,
.end = 0xfffffff9,
.flags = IORESOURCE_MEM,
};
static const struct platform_device_info test_bus_info = { static const struct platform_device_info test_bus_info = {
.name = "unittest-bus", .name = "unittest-bus",
}; };
...@@ -800,6 +801,15 @@ static void __init of_unittest_platform_populate(void) ...@@ -800,6 +801,15 @@ static void __init of_unittest_platform_populate(void)
return; return;
test_bus->dev.of_node = np; test_bus->dev.of_node = np;
/*
* Add a dummy resource to the test bus node after it is
* registered to catch problems with un-inserted resources. The
* DT code doesn't insert the resources, and it has caused the
* kernel to oops in the past. This makes sure the same bug
* doesn't crop up again.
*/
platform_device_add_resources(test_bus, &test_bus_res, 1);
of_platform_populate(np, match, NULL, &test_bus->dev); of_platform_populate(np, match, NULL, &test_bus->dev);
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
for_each_child_of_node(child, grandchild) for_each_child_of_node(child, grandchild)
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/io.h>
struct of_pci_range_parser { struct of_pci_range_parser {
struct device_node *node; struct device_node *node;
...@@ -36,6 +37,8 @@ extern struct device_node *of_find_matching_node_by_address( ...@@ -36,6 +37,8 @@ extern struct device_node *of_find_matching_node_by_address(
const struct of_device_id *matches, const struct of_device_id *matches,
u64 base_address); u64 base_address);
extern void __iomem *of_iomap(struct device_node *device, int index); extern void __iomem *of_iomap(struct device_node *device, int index);
void __iomem *of_io_request_and_map(struct device_node *device,
int index, const char *name);
/* Extract an address from a device, returns the region size and /* Extract an address from a device, returns the region size and
* the address space flags too. The PCI version uses a BAR number * the address space flags too. The PCI version uses a BAR number
...@@ -57,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr, ...@@ -57,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
u64 *paddr, u64 *size); u64 *paddr, u64 *size);
extern bool of_dma_is_coherent(struct device_node *np); extern bool of_dma_is_coherent(struct device_node *np);
#else /* CONFIG_OF_ADDRESS */ #else /* CONFIG_OF_ADDRESS */
static inline void __iomem *of_io_request_and_map(struct device_node *device,
int index, const char *name)
{
return IOMEM_ERR_PTR(-EINVAL);
}
static inline u64 of_translate_address(struct device_node *np, static inline u64 of_translate_address(struct device_node *np,
const __be32 *addr) const __be32 *addr)
...@@ -112,12 +120,7 @@ static inline bool of_dma_is_coherent(struct device_node *np) ...@@ -112,12 +120,7 @@ static inline bool of_dma_is_coherent(struct device_node *np)
extern int of_address_to_resource(struct device_node *dev, int index, extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r); struct resource *r);
void __iomem *of_iomap(struct device_node *node, int index); void __iomem *of_iomap(struct device_node *node, int index);
void __iomem *of_io_request_and_map(struct device_node *device,
int index, const char *name);
#else #else
#include <linux/io.h>
static inline int of_address_to_resource(struct device_node *dev, int index, static inline int of_address_to_resource(struct device_node *dev, int index,
struct resource *r) struct resource *r)
{ {
...@@ -128,12 +131,6 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) ...@@ -128,12 +131,6 @@ static inline void __iomem *of_iomap(struct device_node *device, int index)
{ {
return NULL; return NULL;
} }
static inline void __iomem *of_io_request_and_map(struct device_node *device,
int index, const char *name)
{
return IOMEM_ERR_PTR(-EINVAL);
}
#endif #endif
#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)
......
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