New in v4:
Cleanup and error checking suggested by Sergei Shtylyov.
Use device tree passed by bootloader if present.
New in v3:
More updates to device tree bindings, and perhaps more importantly
descriptions/definitions of the bindings
libfdt building moved to devices/of/libfdt.
Cleanup and style improvements as suggested by Grant Likley.
Omitted all the driver changes, as they are unchanged from the last
set, and at this stage the patches are just an RFC.
New in v2:
Changed many device tree bindings. They should be closer to the
standard naming scheme now.
Editing of the template device tree is done in the flattened form
using libfdt.
Standard platform driver functions used in preference to the
of_platform variety.
v1:
Background: The Octeon family of SOCs has a variety of on-chip
controllers for Ethernet, MDIO, I2C, and several other I/O devices.
These chips are used on boards with a great variety of different
configurations. To date, the configuration and bus topology
information has been hard coded in the drivers and support code.
To facilitate supporting new chips and boards, we would like to make
use use the Device Tree to encode the configuration information.
I would like to get some feedback on the current code I am working
with. The migration approach is as follows:
o Several device tree templates are statically linked into the kernel
image. Based on SOC type and board type one of these is selected in
early boot. Legacy configuration probing code is used to prune and
patch the device tree template.
o New SOCs and boards will directly use a device tree passed by the
bootloader (This patch set doesn't actually implement this, but it
is trivial to add).
1/6 - Infrastructure to allow scripts/dtc/libfdt to be used in the
kernel.
2/6 - OF patch to simplify of_find_node_by_path().
3/6 - Add the statically linked Device Tree templates and bindings
descriptions.
4/6 - Remove unused arch/mips/prom.c code that conflicts with
following patches.
5/6 - irq_create_of_mapping() function.
6/6 - Fix up Device Tree template for current environment.
David Daney (6):
of: Allow scripts/dtc/libfdt to be used from kernel code
of: Make of_find_node_by_path() traverse /aliases for relative paths.
MIPS: Octeon: Add device tree source files.
MIPS: Prune some target specific code out of prom.c
MIPS: Octeon: Add irq_create_of_mapping() and GPIO interrupts.
MIPS: Octeon: Initialize and fixup device tree.
.../devicetree/bindings/mips/cavium/bootbus.txt | 37 ++
.../devicetree/bindings/mips/cavium/ciu.txt | 26 ++
.../devicetree/bindings/mips/cavium/gpio.txt | 48 +++
.../devicetree/bindings/mips/cavium/mdio.txt | 27 ++
.../devicetree/bindings/mips/cavium/mix.txt | 40 ++
.../devicetree/bindings/mips/cavium/pip.txt | 98 +++++
.../devicetree/bindings/mips/cavium/twsi.txt | 34 ++
.../devicetree/bindings/mips/cavium/uart.txt | 19 +
.../devicetree/bindings/mips/cavium/uctl.txt | 47 +++
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/.gitignore | 2 +
arch/mips/cavium-octeon/Makefile | 16 +
arch/mips/cavium-octeon/octeon-irq.c | 183 ++++++++++-
arch/mips/cavium-octeon/octeon-platform.c | 295 +++++++++++++++
arch/mips/cavium-octeon/octeon_3xxx.dts | 375 ++++++++++++++++++++
arch/mips/cavium-octeon/setup.c | 39 ++
arch/mips/kernel/prom.c | 49 ---
drivers/of/Kconfig | 3 +
drivers/of/Makefile | 2 +
drivers/of/base.c | 48 +++-
drivers/of/libfdt/Makefile | 3 +
drivers/of/libfdt/fdt.c | 2 +
drivers/of/libfdt/fdt_ro.c | 2 +
drivers/of/libfdt/fdt_wip.c | 2 +
include/linux/libfdt.h | 8 +
include/linux/libfdt_env.h | 13 +
26 files changed, 1366 insertions(+), 53 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/gpio.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/mdio.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/mix.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/pip.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/twsi.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uart.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
create mode 100644 arch/mips/cavium-octeon/.gitignore
create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
create mode 100644 drivers/of/libfdt/Makefile
create mode 100644 drivers/of/libfdt/fdt.c
create mode 100644 drivers/of/libfdt/fdt_ro.c
create mode 100644 drivers/of/libfdt/fdt_wip.c
create mode 100644 include/linux/libfdt.h
create mode 100644 include/linux/libfdt_env.h
--
1.7.2.3
To use it you need to do this in your Kconfig:
select LIBFDT
And in the Makefile of the code using libfdt something like:
ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
Signed-off-by: David Daney <[email protected]>
---
drivers/of/Kconfig | 3 +++
drivers/of/Makefile | 2 ++
drivers/of/libfdt/Makefile | 3 +++
drivers/of/libfdt/fdt.c | 2 ++
drivers/of/libfdt/fdt_ro.c | 2 ++
drivers/of/libfdt/fdt_wip.c | 2 ++
include/linux/libfdt.h | 8 ++++++++
include/linux/libfdt_env.h | 13 +++++++++++++
8 files changed, 35 insertions(+), 0 deletions(-)
create mode 100644 drivers/of/libfdt/Makefile
create mode 100644 drivers/of/libfdt/fdt.c
create mode 100644 drivers/of/libfdt/fdt_ro.c
create mode 100644 drivers/of/libfdt/fdt_wip.c
create mode 100644 include/linux/libfdt.h
create mode 100644 include/linux/libfdt_env.h
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d06a637..9b0474e 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -4,6 +4,9 @@ config DTC
config OF
bool
+config LIBFDT
+ bool
+
menu "Device Tree and Open Firmware support"
depends on OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index f7861ed..a8dec2f 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_SPI) += of_spi.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
+
+obj-$(CONFIG_LIBFDT) += libfdt/
diff --git a/drivers/of/libfdt/Makefile b/drivers/of/libfdt/Makefile
new file mode 100644
index 0000000..f6bc1c90
--- /dev/null
+++ b/drivers/of/libfdt/Makefile
@@ -0,0 +1,3 @@
+ccflags-y := -I$(src)/../../../scripts/dtc/libfdt
+
+obj-y = fdt.o fdt_wip.o fdt_ro.o
diff --git a/drivers/of/libfdt/fdt.c b/drivers/of/libfdt/fdt.c
new file mode 100644
index 0000000..91495cd
--- /dev/null
+++ b/drivers/of/libfdt/fdt.c
@@ -0,0 +1,2 @@
+#include <linux/libfdt_env.h>
+#include "../../../scripts/dtc/libfdt/fdt.c"
diff --git a/drivers/of/libfdt/fdt_ro.c b/drivers/of/libfdt/fdt_ro.c
new file mode 100644
index 0000000..547e723
--- /dev/null
+++ b/drivers/of/libfdt/fdt_ro.c
@@ -0,0 +1,2 @@
+#include <linux/libfdt_env.h>
+#include "../../../scripts/dtc/libfdt/fdt_ro.c"
diff --git a/drivers/of/libfdt/fdt_wip.c b/drivers/of/libfdt/fdt_wip.c
new file mode 100644
index 0000000..bbe19ec
--- /dev/null
+++ b/drivers/of/libfdt/fdt_wip.c
@@ -0,0 +1,2 @@
+#include <linux/libfdt_env.h>
+#include "../../../scripts/dtc/libfdt/fdt_wip.c"
diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h
new file mode 100644
index 0000000..4c0306c
--- /dev/null
+++ b/include/linux/libfdt.h
@@ -0,0 +1,8 @@
+#ifndef _INCLUDE_LIBFDT_H_
+#define _INCLUDE_LIBFDT_H_
+
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt.h"
+#include "../../scripts/dtc/libfdt/libfdt.h"
+
+#endif /* _INCLUDE_LIBFDT_H_ */
diff --git a/include/linux/libfdt_env.h b/include/linux/libfdt_env.h
new file mode 100644
index 0000000..01508c7
--- /dev/null
+++ b/include/linux/libfdt_env.h
@@ -0,0 +1,13 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <linux/string.h>
+
+#include <asm/byteorder.h>
+
+#define fdt32_to_cpu(x) be32_to_cpu(x)
+#define cpu_to_fdt32(x) cpu_to_be32(x)
+#define fdt64_to_cpu(x) be64_to_cpu(x)
+#define cpu_to_fdt64(x) cpu_to_be64(x)
+
+#endif /* _LIBFDT_ENV_H */
--
1.7.2.3
Currently all paths passed to of_find_node_by_path() must begin with a
'/', indicating a full path to the desired node.
Augment the look-up code so that if a path does *not* begin with '/',
the path is used as the name of an /aliases property. The value of
this alias is then used as the full node path to be found.
Signed-off-by: David Daney <[email protected]>
---
drivers/of/base.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 632ebae..279134b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -340,22 +340,64 @@ EXPORT_SYMBOL(of_get_next_child);
/**
* of_find_node_by_path - Find a node matching a full OF path
- * @path: The full path to match
+ * @path: Either the full path to match, or if the path does not
+ * start with '/', the name of a property of the /aliases
+ * node (an alias). In the case of an alias, the node
+ * matching the alias' value will be returned.
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done.
*/
struct device_node *of_find_node_by_path(const char *path)
{
- struct device_node *np = allnodes;
+ struct device_node *np = NULL;
+ struct device_node *aliases = NULL;
+ char *alias = NULL;
+ char *new_path = NULL;
read_lock(&devtree_lock);
- for (; np; np = np->allnext) {
+
+ if (path[0] != '/') {
+ const char *ps;
+ aliases = of_find_node_by_path("/aliases");
+ if (!aliases)
+ goto out;
+
+ ps = strchr(path, '/');
+ if (ps) {
+ size_t len = ps - path;
+ alias = kstrndup(path, len, GFP_KERNEL);
+ if (!alias)
+ goto out;
+ path = of_get_property(aliases, alias, NULL);
+ if (!path)
+ goto out;
+
+ len = strlen(path) + strlen(ps) + 1;
+ new_path = kmalloc(len, GFP_KERNEL);
+ if (!new_path)
+ goto out;
+ strcpy(new_path, path);
+ strcat(new_path, ps);
+ path = new_path;
+ } else {
+ path = of_get_property(aliases, path, NULL);
+ }
+ if (!path)
+ goto out;
+ }
+
+ for (np = allnodes; np; np = np->allnext) {
if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
&& of_node_get(np))
break;
}
+out:
+ if (aliases)
+ of_node_put(aliases);
read_unlock(&devtree_lock);
+ kfree(alias);
+ kfree(new_path);
return np;
}
EXPORT_SYMBOL(of_find_node_by_path);
--
1.7.2.3
Signed-off-by: David Daney <[email protected]>
---
.../devicetree/bindings/mips/cavium/bootbus.txt | 37 ++
.../devicetree/bindings/mips/cavium/ciu.txt | 26 ++
.../devicetree/bindings/mips/cavium/gpio.txt | 48 +++
.../devicetree/bindings/mips/cavium/mdio.txt | 27 ++
.../devicetree/bindings/mips/cavium/mix.txt | 40 ++
.../devicetree/bindings/mips/cavium/pip.txt | 98 +++++
.../devicetree/bindings/mips/cavium/twsi.txt | 34 ++
.../devicetree/bindings/mips/cavium/uart.txt | 19 +
.../devicetree/bindings/mips/cavium/uctl.txt | 47 +++
arch/mips/cavium-octeon/.gitignore | 2 +
arch/mips/cavium-octeon/Makefile | 13 +
arch/mips/cavium-octeon/octeon_3xxx.dts | 375 ++++++++++++++++++++
12 files changed, 766 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/gpio.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/mdio.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/mix.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/pip.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/twsi.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uart.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
create mode 100644 arch/mips/cavium-octeon/.gitignore
create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
diff --git a/Documentation/devicetree/bindings/mips/cavium/bootbus.txt b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
new file mode 100644
index 0000000..221c118
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
@@ -0,0 +1,37 @@
+* Boot Bus
+
+Properties:
+- compatible: "cavium,octeon-3860-bootbus"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the CIU's register bank.
+
+- #address-cells: Must be <2>. The first cell is the chip select
+ within the bootbus. The second cell is the offset from the chip select.
+
+- #size-cells: Must be <1>.
+
+- ranges: There must be one one triplet of (child-bus-address,
+ parent-bus-address, length) for each active chip select.
+
+Example:
+ bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x1f400000 0x1000000>,
+ <1 0 0x1 0x30000000 0x10000000>,
+ <2 0 0x1 0x40000000 0x10000000>,
+ <3 0 0x1 0x50000000 0x10000000>,
+ <4 0 0x1 0x60000000 0x10000000>,
+ <5 0 0x1 0x70000000 0x10000000>,
+ <6 0 0x1 0x80000000 0x10000000>,
+ <7 0 0x1 0x90000000 0x10000000>;
+ .
+ .
+ .
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/ciu.txt b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
new file mode 100644
index 0000000..c8ff212
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
@@ -0,0 +1,26 @@
+* Central Interrupt Unit
+
+Properties:
+- compatible: "cavium,octeon-3860-ciu"
+
+ Compatibility with all cn3XXX, cn5XXX and cn63XX SOCs.
+
+- interrupt-controller: This is an interrupt controller.
+
+- reg: The base address of the CIU's register bank.
+
+- #interrupt-cells: Must be <2>. The first cell is the bank within
+ the CIU and may have a value of 0 or 1. The second cell is the bit
+ within the bank and may have a value between 0 and 63.
+
+Example:
+ interrupt-controller@1070000000000 {
+ compatible = "cavium,octeon-3860-ciu";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 1)
+ * 2) Bit within the register (0..63)
+ */
+ #interrupt-cells = <2>;
+ reg = <0x10700 0x00000000 0x0 0x7000>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/gpio.txt b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
new file mode 100644
index 0000000..72853d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
@@ -0,0 +1,48 @@
+* General Purpose Input Output (GPIO) bus.
+
+Properties:
+- compatible: "cavium,octeon-3860-gpio"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the GPIO unit's register bank.
+
+- gpio-controller: This is a GPIO controller.
+
+- #gpio-cells: Must be <2>. The first cell is the GPIO pin.
+
+- interrupt-controller: The GPIO controller is also an interrupt
+ controller, any of its pins may be configured as an interrupt
+ source.
+
+- #interrupt-cells: Must be <2>. The first cell is the GPIO pin
+ connected to the interrupt source. The second cell is the interrupt
+ triggering protocol and may have one of four values:
+ 0 - level triggered active high.
+ 1 - level triggered active low
+ 2 - edge triggered on the rising edge.
+ 3 - edge triggered on the falling edge.
+
+- interrupts: Interrupt routing for pin 0. The remaining pins are
+ also routed, but in a manner that can be derived from the pin0
+ routing, so they are not specified.
+
+Example:
+
+ gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (0 - level active high
+ * 1 - level active low
+ * 2 - edge rising
+ * 3 - edge falling
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pin connect to 16 consecutive CUI bits */
+ interrupts = <0 16>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/mdio.txt b/Documentation/devicetree/bindings/mips/cavium/mdio.txt
new file mode 100644
index 0000000..6253c3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/mdio.txt
@@ -0,0 +1,27 @@
+* System Management Interface (SMI) / MDIO
+
+Properties:
+- compatible: "cavium,octeon-3860-mdio"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the MDIO bus controller register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>. MDIO addresses have no size component.
+
+Typically an MDIO bus might have several children.
+
+Example:
+ mdio@1180000001800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001800 0x0 0x40>;
+
+ ethernet-phy@0 {
+ ...
+ reg = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/mix.txt b/Documentation/devicetree/bindings/mips/cavium/mix.txt
new file mode 100644
index 0000000..2a91a33
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/mix.txt
@@ -0,0 +1,40 @@
+* MIX Ethernet controller.
+
+Properties:
+- compatible: "cavium,octeon-5750-mix"
+
+ Compatibility with all cn5XXX and cn6XXX SOCs populated with MIX
+ devices.
+
+- reg: The base addresses of four seperate register banks. The first
+ bank contains the MIX registers. The second bank the corresponding
+ AGL registers. The third bank are the AGL registers shared by all
+ MIX devices present. The fourth bank is the AGL_PRT_CTL shared by
+ all MIX devices present.
+
+- cell-index: A single cell specifying which portion of the shared
+ register banks corresponds to this MIX device.
+
+- interrupts: Two interrupt specifiers. The first is the MIX
+ interrupt routing and the second the routing for the AGL interrupts.
+
+- mac-address: Optional, the MAC address to assign to the device.
+
+- local-mac-address: Optional, the MAC address to assign to the device
+ if mac-address is not specified.
+
+- phy-handle: Optional, a phandle for the PHY device connected to this device.
+
+Example:
+ ethernet@1070000100800 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000800 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <1>;
+ interrupts = <1 18>, < 1 46>;
+ local-mac-address = [ 00 0f b7 10 63 54 ];
+ phy-handle = <&phy1>;
+ };
+
diff --git a/Documentation/devicetree/bindings/mips/cavium/pip.txt b/Documentation/devicetree/bindings/mips/cavium/pip.txt
new file mode 100644
index 0000000..d4c53ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/pip.txt
@@ -0,0 +1,98 @@
+* PIP Ethernet nexus.
+
+The PIP Ethernet nexus can control several data packet input/output
+devices. The devices have a two level grouping scheme. There may be
+several interfaces, and each interface may have several ports. These
+ports might be an individual Ethernet PHY.
+
+
+Properties for the PIP nexus:
+- compatible: "cavium,octeon-3860-pip"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the PIP's register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>.
+
+Properties for PIP interfaces which is a child the PIP nexus:
+- compatible: "cavium,octeon-3860-pip-interface"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The interface number.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>.
+
+Properties for PIP port which is a child the PIP interface:
+- compatible: "cavium,octeon-3860-pip-port"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The port number within the interface group.
+
+- mac-address: Optional, the MAC address to assign to the device.
+
+- local-mac-address: Optional, the MAC address to assign to the device
+ if mac-address is not specified.
+
+- phy-handle: Optional, a phandle for the PHY device connected to this device.
+
+Example:
+
+ pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 60 ];
+ phy-handle = <&phy2>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 61 ];
+ phy-handle = <&phy3>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 62 ];
+ phy-handle = <&phy4>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 63 ];
+ phy-handle = <&phy5>;
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 64 ];
+ phy-handle = <&phy6>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/twsi.txt b/Documentation/devicetree/bindings/mips/cavium/twsi.txt
new file mode 100644
index 0000000..6e57155
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/twsi.txt
@@ -0,0 +1,34 @@
+* Two Wire Serial Interface (TWSI) / I2C
+
+- compatible: "cavium,octeon-3860-twsi"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the TWSI/I2C bus controller register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>. I2C addresses have no size component.
+
+- interrupts: A single interrupt specifier.
+
+- clock-rate: The I2C bus clock rate in Hz.
+
+Example:
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <0 45>;
+ clock-rate = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/uart.txt b/Documentation/devicetree/bindings/mips/cavium/uart.txt
new file mode 100644
index 0000000..87a6c37
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/uart.txt
@@ -0,0 +1,19 @@
+* Universal Asynchronous Receiver/Transmitter (UART)
+
+- compatible: "cavium,octeon-3860-uart"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the UART register bank.
+
+- interrupts: A single interrupt specifier.
+
+- current-speed: Optional, the current bit rate in bits per second.
+
+Example:
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ current-speed = <115200>;
+ interrupts = <0 35>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/uctl.txt b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
new file mode 100644
index 0000000..5dabe02
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
@@ -0,0 +1,47 @@
+* UCTL USB controller glue
+
+Properties:
+- compatible: "cavium,octeon-6335-uctl"
+
+ Compatibility with all cn6XXX SOCs.
+
+- reg: The base address of the UCTL register bank.
+
+- #address-cells: Must be <2>.
+
+- #size-cells: Must be <2>.
+
+- ranges: Empty to signify direct mapping of the children.
+
+- refclk-frequency: A single cell containing the reference clock
+ frequency in Hz.
+
+- refclk-type: A string describing the reference clock connection
+ either "crystal" or "external".
+
+Example:
+ uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <24000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ };
+
diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore
new file mode 100644
index 0000000..39c9686
--- /dev/null
+++ b/arch/mips/cavium-octeon/.gitignore
@@ -0,0 +1,2 @@
+*.dtb.S
+*.dtb
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 19eb043..b8d4f63 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -15,3 +15,16 @@ obj-y += octeon-memcpy.o
obj-y += executive/
obj-$(CONFIG_SMP) += smp.o
+
+DTS_FILES = octeon_3xxx.dts
+DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
+
+obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
+
+$(obj)/%.dtb: $(src)/%.dts
+ $(call cmd,dtc)
+
+# Let's keep the .dtb files around in case we want to look at them.
+.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
+
+clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES))
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
new file mode 100644
index 0000000..2b371dc
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -0,0 +1,375 @@
+/dts-v1/;
+/*
+ * OCTEON 3XXX, 5XXX, 63XX device tree skeleton.
+ *
+ * This device tree is pruned and patched by early boot code before
+ * use. Because of this, it contains a super-set of the available
+ * devices and properties.
+ */
+/ {
+ compatible = "cavium,octeon-3860";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&ciu>;
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges; /* Direct mapping */
+
+ ciu: interrupt-controller@1070000000000 {
+ compatible = "cavium,octeon-3860-ciu";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 1)
+ * 2) Bit within the register (0..63)
+ */
+ #interrupt-cells = <2>;
+ reg = <0x10700 0x00000000 0x0 0x7000>;
+ };
+
+ gpio: gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (0 - level active high
+ * 1 - level active low
+ * 2 - edge rising
+ * 3 - edge falling
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pin connect to 16 consecutive CUI bits */
+ interrupts = <0 16>; /* <0 17> <0 18> <0 19>
+ <0 20> <0 21> <0 22> <0 23>
+ <0 24> <0 25> <0 26> <0 27>
+ <0 28> <0 29> <0 30> <0 31>; */
+ };
+
+ smi0: mdio@1180000001800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001800 0x0 0x40>;
+
+ phy0: ethernet-phy@0 {
+ compatible = "broadcom,bcm5241";
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ compatible = "broadcom,bcm5241";
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <5 1>; /* Pin 5, active low */
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <5 1>; /* Pin 5, active low */
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <5 1>; /* Pin 5, active low */
+ };
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <5 1>; /* Pin 5, active low */
+ };
+
+ phy6: ethernet-phy@6 {
+ reg = <6>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy7: ethernet-phy@7 {
+ reg = <7>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy8: ethernet-phy@8 {
+ reg = <8>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy9: ethernet-phy@9 {
+ reg = <9>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi1: mdio@1180000001900 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001900 0x0 0x40>;
+ };
+
+ mix0: ethernet@1070000100000 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000000 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <0>;
+ interrupts = <0 62>, <1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy0>;
+ };
+
+ mix1: ethernet@1070000100800 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000800 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <1>;
+ interrupts = <1 18>, < 1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy1>;
+ };
+
+ pip: pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy2>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy3>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy4>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy5>;
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy6>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy7>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy8>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy9>;
+ };
+ };
+ };
+
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <0 45>;
+ clock-rate = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
+
+ twsi1: i2c@1180000001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001200 0x0 0x200>;
+ interrupts = <0 59>;
+ clock-rate = <100000>;
+ };
+
+ uart0: serial@1180000000800 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000800 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 34>;
+ };
+
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 35>;
+ };
+
+ uart2: serial@1180000000400 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000400 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <1 16>;
+ };
+
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x1f400000 0x1000000>,
+ <1 0 0x1 0x30000000 0x10000000>,
+ <2 0 0x1 0x40000000 0x10000000>,
+ <3 0 0x1 0x50000000 0x10000000>,
+ <4 0 0x1 0x60000000 0x10000000>,
+ <5 0 0x1 0x70000000 0x10000000>,
+ <6 0 0x1 0x80000000 0x10000000>,
+ <7 0 0x1 0x90000000 0x10000000>;
+
+ flash0: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x400000>;
+ read-only;
+ };
+
+ partition@400000 {
+ label = "data";
+ reg = <0x400000 0x400000>;
+ read-only;
+ };
+ };
+ };
+
+ uctl: uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <24000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ };
+ };
+
+ aliases {
+ mix0 = &mix0;
+ mix1 = &mix1;
+ pip = &pip;
+ smi0 = &smi0;
+ smi1 = &smi1;
+ twsi0 = &twsi0;
+ twsi1 = &twsi1;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uart2 = &uart2;
+ flash0 = &flash0;
+ };
+ };
--
1.7.2.3
This code is not common enough to be in a shared file. It is also not
used by any existing boards, so just remove it.
Signed-off-by: David Daney <[email protected]>
---
arch/mips/kernel/prom.c | 49 -----------------------------------------------
1 files changed, 0 insertions(+), 49 deletions(-)
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index a19811e9..a07b6f1 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -59,52 +59,3 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
initrd_below_start_ok = 1;
}
#endif
-
-/*
- * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
- *
- * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
- * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
- * supported.
- */
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void __init early_init_devtree(void *params)
-{
- /* Setup flat device-tree pointer */
- initial_boot_params = params;
-
- /* Retrieve various informations from the /chosen node of the
- * device-tree, including the platform type, initrd location and
- * size, and more ...
- */
- of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
-
- /* Scan memory nodes */
- of_scan_flat_dt(early_init_dt_scan_root, NULL);
- of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
-}
-
-void __init device_tree_init(void)
-{
- unsigned long base, size;
-
- if (!initial_boot_params)
- return;
-
- base = virt_to_phys((void *)initial_boot_params);
- size = be32_to_cpu(initial_boot_params->totalsize);
-
- /* Before we do anything, lets reserve the dt blob */
- reserve_mem_mach(base, size);
-
- unflatten_device_tree();
-
- /* free the space reserved for the dt blob */
- free_mem_mach(base, size);
-}
--
1.7.2.3
This is needed for Octeon to use the Device Tree.
The GPIO interrupts are configured based on Device Tree properties
Signed-off-by: David Daney <[email protected]>
---
arch/mips/cavium-octeon/octeon-irq.c | 183 +++++++++++++++++++++++++++++++++-
1 files changed, 182 insertions(+), 1 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ffd4ae6..68b711c 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -8,11 +8,14 @@
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/module.h>
#include <linux/percpu.h>
+#include <linux/of_irq.h>
#include <linux/irq.h>
#include <linux/smp.h>
#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-gpio-defs.h>
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
@@ -58,6 +61,90 @@ static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
octeon_irq_ciu_to_irq[line][bit] = irq;
}
+static unsigned int octeon_irq_gpio_mapping(struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize)
+{
+ struct of_irq oirq;
+ int i;
+ unsigned int irq = 0;
+ unsigned int type;
+ unsigned int ciu = 0, bit = 0;
+ unsigned int pin = be32_to_cpup(intspec);
+ unsigned int trigger = be32_to_cpup(intspec + 1);
+ bool set_edge_handler = false;
+
+ if (pin >= 16)
+ goto err;
+ i = of_irq_map_one(controller, 0, &oirq);
+ if (i)
+ goto err;
+ if (oirq.size != 2)
+ goto err_put;
+
+ ciu = oirq.specifier[0];
+ bit = oirq.specifier[1] + pin;
+
+ if (ciu >= 8 || bit >= 64)
+ goto err_put;
+
+ irq = octeon_irq_ciu_to_irq[ciu][bit];
+ if (!irq)
+ goto err_put;
+
+ switch (trigger & 3) {
+ case 0:
+ type = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case 1:
+ type = IRQ_TYPE_LEVEL_LOW;
+ break;
+ case 2:
+ type = IRQ_TYPE_EDGE_RISING;
+ set_edge_handler = true;
+ break;
+ case 3:
+ type = IRQ_TYPE_EDGE_FALLING;
+ set_edge_handler = true;
+ break;
+ }
+
+ irq_set_irq_type(irq, type);
+
+ if (set_edge_handler)
+ __irq_set_handler(irq, handle_edge_irq, 0, NULL);
+
+err_put:
+ of_node_put(oirq.controller);
+err:
+ return irq;
+}
+
+/*
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Octeon irq maps are a pair of indexes. The first selects either
+ * ciu0 or ciu1, the second is the bit within the ciu register.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ unsigned int irq = 0;
+ unsigned int ciu, bit;
+
+ if (of_device_is_compatible(controller, "cavium,octeon-3860-gpio"))
+ return octeon_irq_gpio_mapping(controller, intspec, intsize);
+
+ ciu = be32_to_cpup(intspec);
+ bit = be32_to_cpup(intspec + 1);
+
+ if (ciu < 8 && bit < 64)
+ irq = octeon_irq_ciu_to_irq[ciu][bit];
+
+ return irq;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
static int octeon_coreid_for_cpu(int cpu)
{
#ifdef CONFIG_SMP
@@ -505,6 +592,72 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
}
}
+static void octeon_irq_gpio_setup(struct irq_data *data)
+{
+ union cvmx_gpio_bit_cfgx cfg;
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ u32 t = irqd_get_trigger_type(data);
+
+ cfg.u64 = 0;
+ cfg.s.int_en = 1;
+ cfg.s.int_type = (t & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) != 0;
+ cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0;
+
+ /* 1 uS glitch filter*/
+ cfg.s.fil_cnt = 7;
+ cfg.s.fil_sel = 3;
+
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), cfg.u64);
+}
+
+static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable_v2(data);
+}
+
+static void octeon_irq_ciu_enable_gpio(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable(data);
+}
+
+static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t)
+{
+ u32 current_type = irqd_get_trigger_type(data);
+
+ /* If the type has been set, don't change it */
+ if (current_type && current_type != t)
+ return -EINVAL;
+
+ irqd_set_trigger_type(data, t);
+ return IRQ_SET_MASK_OK;
+}
+
+static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), 0);
+
+ octeon_irq_ciu_disable_all_v2(data);
+}
+
+static void octeon_irq_ciu_disable_gpio(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), 0);
+
+ octeon_irq_ciu_disable_all(data);
+}
+
+static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ u64 mask = 1ull << bit;
+
+ cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
+}
+
#ifdef CONFIG_SMP
static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
@@ -717,6 +870,31 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = {
.flags = IRQCHIP_ONOFFLINE_ENABLED,
};
+static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio_v2,
+ .irq_disable = octeon_irq_ciu_disable_gpio_v2,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_gpio = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio,
+ .irq_disable = octeon_irq_ciu_disable_gpio,
+ .irq_mask = octeon_irq_dummy_mask,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+#endif
+};
+
/*
* Watchdog interrupts are special. They are associated with a single
* core, so we hardwire the affinity to that core.
@@ -890,6 +1068,7 @@ static void __init octeon_irq_init_ciu(void)
struct irq_chip *chip_edge;
struct irq_chip *chip_mbox;
struct irq_chip *chip_wd;
+ struct irq_chip *chip_gpio;
octeon_irq_init_ciu_percpu();
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -904,6 +1083,7 @@ static void __init octeon_irq_init_ciu(void)
chip_edge = &octeon_irq_chip_ciu_edge_v2;
chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
chip_wd = &octeon_irq_chip_ciu_wd_v2;
+ chip_gpio = &octeon_irq_chip_ciu_gpio_v2;
} else {
octeon_irq_ip2 = octeon_irq_ip2_v1;
octeon_irq_ip3 = octeon_irq_ip3_v1;
@@ -911,6 +1091,7 @@ static void __init octeon_irq_init_ciu(void)
chip_edge = &octeon_irq_chip_ciu_edge;
chip_mbox = &octeon_irq_chip_ciu_mbox;
chip_wd = &octeon_irq_chip_ciu_wd;
+ chip_gpio = &octeon_irq_chip_ciu_gpio;
}
octeon_irq_ip4 = octeon_irq_ip4_mask;
@@ -921,7 +1102,7 @@ static void __init octeon_irq_init_ciu(void)
for (i = 0; i < 16; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
--
1.7.2.3
Signed-off-by: David Daney <[email protected]>
---
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/Makefile | 3 +
arch/mips/cavium-octeon/octeon-platform.c | 295 +++++++++++++++++++++++++++++
arch/mips/cavium-octeon/setup.c | 39 ++++
4 files changed, 338 insertions(+), 0 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8dcf4f8..1fbd856 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1410,6 +1410,7 @@ config CPU_CAVIUM_OCTEON
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
+ select LIBFDT
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index b8d4f63..a11b35a 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -9,6 +9,9 @@
# Copyright (C) 2005-2009 Cavium Networks
#
+CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index cd61d72..e595a81 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -13,10 +13,16 @@
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-rnm-defs.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
static struct octeon_cf_data octeon_cf_data;
@@ -440,6 +446,295 @@ device_initcall(octeon_ohci_device_init);
#endif /* CONFIG_USB */
+static struct of_device_id __initdata octeon_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "cavium,octeon-6335-uctl", },
+ { .compatible = "cavium,octeon-3860-bootbus", },
+ {},
+};
+
+static void __init octeon_fdt_set_phy(int eth, int phy_addr)
+{
+ const __be32 *phy_handle;
+ const __be32 *reg;
+ struct fdt_node_header *raw_node;
+ u32 phandle;
+ int phy;
+ int available_len, addr_len, len;
+ char new_address[3];
+ char *cp;
+
+ phy_handle = fdt_getprop(initial_boot_params, eth, "phy-handle", NULL);
+ if (!phy_handle)
+ return;
+
+ phandle = be32_to_cpup(phy_handle);
+ phy = fdt_node_offset_by_phandle(initial_boot_params, phandle);
+ if (phy_addr < 0 || phy < 0) {
+ /* Delete the PHY things */
+ if (phy >= 0)
+ fdt_nop_node(initial_boot_params, phy);
+ fdt_nop_property(initial_boot_params, eth, "phy-handle");
+ return;
+ }
+
+ reg = fdt_getprop(initial_boot_params, phy, "reg", NULL);
+ if (phy_addr == be32_to_cpup(reg))
+ return;
+
+ fdt_setprop_inplace_cell(initial_boot_params, phy, "reg", phy_addr);
+
+ snprintf(new_address, sizeof(new_address), "%x", phy_addr);
+ /*
+ * All PHYs in the template have a name like 'ethernet-phy@0',
+ * that is 14 characters, which allows us to replace the
+ * address portion with up to two characters without
+ * clobbering things past a multiple of 4 boundry.
+ */
+ raw_node = (void *)fdt_offset_ptr(initial_boot_params, phy, 0);
+ cp = strchr(raw_node->name, '@');
+ if (!cp)
+ return;
+
+ available_len = (strlen(raw_node->name) + 4) & ~3;
+ len = cp - raw_node->name + 1;
+ addr_len = strlen(new_address);
+
+ if (len + addr_len + 1 > available_len) {
+ pr_err("ERROR: cannot edit PHY address <%s>\n", raw_node->name);
+ return;
+ }
+
+ cp++;
+ strcpy(cp, new_address);
+}
+
+static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac)
+{
+ u8 new_mac[6];
+ u64 mac = *pmac;
+ int r;
+
+ new_mac[0] = (mac >> 40) & 0xff;
+ new_mac[1] = (mac >> 32) & 0xff;
+ new_mac[2] = (mac >> 24) & 0xff;
+ new_mac[3] = (mac >> 16) & 0xff;
+ new_mac[4] = (mac >> 8) & 0xff;
+ new_mac[5] = mac & 0xff;
+
+ r = fdt_setprop_inplace(initial_boot_params, n, "local-mac-address",
+ new_mac, sizeof(new_mac));
+
+ if (r) {
+ pr_err("Setting \"local-mac-address\" failed %d", r);
+ return;
+ }
+ *pmac = mac + 1;
+}
+
+static void __init octeon_fdt_rm_ethernet(int node)
+{
+ const __be32 *phy_handle;
+
+ phy_handle = fdt_getprop(initial_boot_params, node, "phy-handle", NULL);
+ if (phy_handle) {
+ u32 ph = be32_to_cpup(phy_handle);
+ int p = fdt_node_offset_by_phandle(initial_boot_params, ph);
+ if (p >= 0)
+ fdt_nop_node(initial_boot_params, p);
+ }
+ fdt_nop_node(initial_boot_params, node);
+}
+
+static void __init octeon_fdt_pip_port(int iface, int i, int p, u64 *pmac)
+{
+ char name_buffer[20];
+ int eth;
+ int phy_addr;
+
+ snprintf(name_buffer, sizeof(name_buffer), "ethernet@%d", p);
+ eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer);
+ if (eth < 0)
+ return;
+ if (p >= cvmx_helper_ports_on_interface(i)) {
+ pr_notice("Deleting port %x:%x\n", i, p);
+ octeon_fdt_rm_ethernet(eth);
+ return;
+ }
+
+ phy_addr = cvmx_helper_board_get_mii_address(16 * i + p);
+ octeon_fdt_set_phy(eth, phy_addr);
+ octeon_fdt_set_mac_addr(eth, pmac);
+}
+
+static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
+{
+ char name_buffer[20];
+ int iface;
+ int p;
+
+ cvmx_helper_interface_enumerate(idx);
+ snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
+ iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
+ if (iface < 0)
+ return;
+
+ for (p = 0; p < 4; p++)
+ octeon_fdt_pip_port(iface, idx, p, pmac);
+}
+
+int __init octeon_prune_device_tree(void)
+{
+ int i, max_port, uart_mask;
+ const char *pip_path;
+ char name_buffer[20];
+ int aliases;
+ u64 mac_addr_base;
+
+ if (fdt_check_header(initial_boot_params))
+ panic("Corrupt Device Tree.");
+
+ aliases = fdt_path_offset(initial_boot_params, "/aliases");
+ if (aliases < 0) {
+ pr_err("Error: No /aliases node in device tree.");
+ return -EINVAL;
+ }
+
+
+ mac_addr_base =
+ ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
+ ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
+ ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
+ ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
+ ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
+ (octeon_bootinfo->mac_addr_base[5] & 0xffull);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
+ max_port = 2;
+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 1;
+ else
+ max_port = 0;
+
+ for (i = 0; i < 2; i++) {
+ const char *alias_prop;
+ int mgmt;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "mix%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+ if (alias_prop) {
+ mgmt = fdt_path_offset(initial_boot_params, alias_prop);
+ if (mgmt < 0)
+ continue;
+ if (i >= max_port) {
+ pr_notice("Deleting mix%d\n", i);
+ octeon_fdt_rm_ethernet(mgmt);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ } else {
+ octeon_fdt_set_phy(mgmt, i);
+ octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
+ }
+ }
+ }
+
+ pip_path = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
+ if (pip_path) {
+ int pip = fdt_path_offset(initial_boot_params, pip_path);
+ if (pip >= 0)
+ for (i = 0; i < 4; i++)
+ octeon_fdt_pip_iface(pip, i, &mac_addr_base);
+ }
+
+ /* I2C */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 2;
+ else
+ max_port = 1;
+
+ for (i = 0; i < 2; i++) {
+ const char *alias_prop;
+ int i2c;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "twsi%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ i2c = fdt_path_offset(initial_boot_params, alias_prop);
+ if (i2c < 0)
+ continue;
+ if (i >= max_port) {
+ pr_notice("Deleting twsi%d\n", i);
+ fdt_nop_node(initial_boot_params, i2c);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+ }
+
+ /* Serial */
+ uart_mask = 0;
+
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ /*
+ * If we are configured to run as the second of two kernels,
+ * disable uart0 and enable uart1. Uart0 is owned by the first
+ * kernel
+ */
+ uart_mask |= 2; /* uart1 */
+#else
+ /*
+ * We are configured for the first kernel. We'll enable uart0
+ * if the bootloader told us to use 0, otherwise will enable
+ * uart 1.
+ */
+ if (octeon_get_boot_uart() == 0)
+ uart_mask |= 1; /* uart0 */
+ if (octeon_get_boot_uart() == 1)
+ uart_mask |= 2; /* uart1 */
+
+#ifdef CONFIG_KGDB
+ uart_mask |= 2; /* uart1 */
+#endif
+#endif
+
+ /* Right now CN52XX is the only chip with a third uart */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ uart_mask |= 4; /* uart2 */
+
+ for (i = 0; i < 3; i++) {
+ const char *alias_prop;
+ int uart;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "uart%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ uart = fdt_path_offset(initial_boot_params, alias_prop);
+ if (uart_mask & (1 << i))
+ continue;
+ pr_notice("Deleting uart%d\n", i);
+ fdt_nop_node(initial_boot_params, uart);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+
+ return 0;
+}
+
+static int __init octeon_publish_devices(void)
+{
+ return of_platform_bus_probe(NULL, octeon_ids, NULL);
+}
+device_initcall(octeon_publish_devices);
+
+
MODULE_AUTHOR("David Daney <[email protected]>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 36221b3..15f876e 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -20,6 +20,8 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/initrd.h>
#endif
@@ -797,3 +799,40 @@ void prom_free_prom_memory(void)
}
#endif
}
+
+int octeon_prune_device_tree(void);
+
+extern const char __dtb_octeon_3xxx_begin;
+extern const char __dtb_octeon_3xxx_end;
+void __init device_tree_init(void)
+{
+ int dt_size;
+ struct boot_param_header *fdt;
+ bool do_prune;
+
+ if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
+ fdt = (struct boot_param_header *)PHYS_TO_XKSEG_CACHED(octeon_bootinfo->fdt_addr);
+ if (fdt_check_header(fdt))
+ panic("Corrupt Device Tree passed to kernel.");
+ dt_size = be32_to_cpu(fdt->totalsize);
+ do_prune = false;
+ } else {
+ fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
+ dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ do_prune = true;
+ }
+
+ /* Copy the default tree from init memory. */
+ initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
+ if (initial_boot_params == NULL)
+ panic("Could not allocate initial_boot_params\n");
+ memcpy(initial_boot_params, fdt, dt_size);
+
+ if (do_prune) {
+ octeon_prune_device_tree();
+ pr_info("Using internal Device Tree.\n");
+ } else {
+ pr_info("Using passed Device Tree.\n");
+ }
+ unflatten_device_tree();
+}
--
1.7.2.3
On Fri, May 20, 2011 at 03:25:38PM -0700, David Daney wrote:
> To use it you need to do this in your Kconfig:
>
> select LIBFDT
>
> And in the Makefile of the code using libfdt something like:
>
> ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
>
> Signed-off-by: David Daney <[email protected]>
> ---
> drivers/of/Kconfig | 3 +++
> drivers/of/Makefile | 2 ++
> drivers/of/libfdt/Makefile | 3 +++
> drivers/of/libfdt/fdt.c | 2 ++
> drivers/of/libfdt/fdt_ro.c | 2 ++
> drivers/of/libfdt/fdt_wip.c | 2 ++
No fdt_sw.c or fdt_rw.c?
> include/linux/libfdt.h | 8 ++++++++
> include/linux/libfdt_env.h | 13 +++++++++++++
> 8 files changed, 35 insertions(+), 0 deletions(-)
> create mode 100644 drivers/of/libfdt/Makefile
> create mode 100644 drivers/of/libfdt/fdt.c
> create mode 100644 drivers/of/libfdt/fdt_ro.c
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
On 05/20/2011 11:33 PM, David Gibson wrote:
> On Fri, May 20, 2011 at 03:25:38PM -0700, David Daney wrote:
>> To use it you need to do this in your Kconfig:
>>
>> select LIBFDT
>>
>> And in the Makefile of the code using libfdt something like:
>>
>> ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
>>
>> Signed-off-by: David Daney<[email protected]>
>> ---
>> drivers/of/Kconfig | 3 +++
>> drivers/of/Makefile | 2 ++
>> drivers/of/libfdt/Makefile | 3 +++
>> drivers/of/libfdt/fdt.c | 2 ++
>> drivers/of/libfdt/fdt_ro.c | 2 ++
>> drivers/of/libfdt/fdt_wip.c | 2 ++
>
> No fdt_sw.c or fdt_rw.c?
>
I had no immediate need for them. They could of course be added, but
that would potentially waste space.
Let's see if I can make it into an archive library.
David Daney
>> include/linux/libfdt.h | 8 ++++++++
>> include/linux/libfdt_env.h | 13 +++++++++++++
>> 8 files changed, 35 insertions(+), 0 deletions(-)
>> create mode 100644 drivers/of/libfdt/Makefile
>> create mode 100644 drivers/of/libfdt/fdt.c
>> create mode 100644 drivers/of/libfdt/fdt_ro.c
>
On Fri, May 20, 2011 at 03:25:40PM -0700, David Daney wrote:
> Signed-off-by: David Daney <[email protected]>
> ---
> .../devicetree/bindings/mips/cavium/bootbus.txt | 37 ++
> .../devicetree/bindings/mips/cavium/ciu.txt | 26 ++
> .../devicetree/bindings/mips/cavium/gpio.txt | 48 +++
> .../devicetree/bindings/mips/cavium/mdio.txt | 27 ++
> .../devicetree/bindings/mips/cavium/mix.txt | 40 ++
> .../devicetree/bindings/mips/cavium/pip.txt | 98 +++++
> .../devicetree/bindings/mips/cavium/twsi.txt | 34 ++
> .../devicetree/bindings/mips/cavium/uart.txt | 19 +
> .../devicetree/bindings/mips/cavium/uctl.txt | 47 +++
> arch/mips/cavium-octeon/.gitignore | 2 +
> arch/mips/cavium-octeon/Makefile | 13 +
> arch/mips/cavium-octeon/octeon_3xxx.dts | 375 ++++++++++++++++++++
> 12 files changed, 766 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/gpio.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/mdio.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/mix.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/pip.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/twsi.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/uart.txt
> create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
> create mode 100644 arch/mips/cavium-octeon/.gitignore
> create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
Looks pretty good to me. A few comments below, but I'm okay with this
one being picked up (Ralf, or if you prefer then I can merge it via my
tree) as long as you follow it up with a fixup patch.
g.
>
> diff --git a/Documentation/devicetree/bindings/mips/cavium/bootbus.txt b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
> new file mode 100644
> index 0000000..221c118
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
> @@ -0,0 +1,37 @@
> +* Boot Bus
> +
> +Properties:
> +- compatible: "cavium,octeon-3860-bootbus"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the CIU's register bank.
> +
> +- #address-cells: Must be <2>. The first cell is the chip select
> + within the bootbus. The second cell is the offset from the chip select.
> +
> +- #size-cells: Must be <1>.
> +
> +- ranges: There must be one one triplet of (child-bus-address,
> + parent-bus-address, length) for each active chip select.
> +
> +Example:
> + bootbus@1180000000000 {
> + compatible = "cavium,octeon-3860-bootbus";
> + reg = <0x11800 0x00000000 0x0 0x200>;
> + /* The chip select number and offset */
> + #address-cells = <2>;
> + /* The size of the chip select region */
> + #size-cells = <1>;
> + ranges = <0 0 0x0 0x1f400000 0x1000000>,
> + <1 0 0x1 0x30000000 0x10000000>,
> + <2 0 0x1 0x40000000 0x10000000>,
> + <3 0 0x1 0x50000000 0x10000000>,
> + <4 0 0x1 0x60000000 0x10000000>,
> + <5 0 0x1 0x70000000 0x10000000>,
> + <6 0 0x1 0x80000000 0x10000000>,
> + <7 0 0x1 0x90000000 0x10000000>;
> + .
> + .
> + .
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/ciu.txt b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
> new file mode 100644
> index 0000000..c8ff212
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
> @@ -0,0 +1,26 @@
> +* Central Interrupt Unit
> +
> +Properties:
> +- compatible: "cavium,octeon-3860-ciu"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn63XX SOCs.
> +
> +- interrupt-controller: This is an interrupt controller.
> +
> +- reg: The base address of the CIU's register bank.
> +
> +- #interrupt-cells: Must be <2>. The first cell is the bank within
> + the CIU and may have a value of 0 or 1. The second cell is the bit
> + within the bank and may have a value between 0 and 63.
> +
> +Example:
> + interrupt-controller@1070000000000 {
> + compatible = "cavium,octeon-3860-ciu";
> + interrupt-controller;
> + /* Interrupts are specified by two parts:
> + * 1) Controller register (0 or 1)
> + * 2) Bit within the register (0..63)
> + */
Are there any configuration parameters for these irq inputs? Edge vs.
Level? Active high or active low? If so, then you'll probably want to
have a flags cell.
Also, how are the irqs typically documented in the hardware reference
manual? Are they documented a irqs 0-63 in bank 1 and 0-63 in bank 2?
Or are is a flat 0-127 number range? If it is the later, then you may
want to consider just using a single cell to specify the irq number,
and handle the bank calculation in the irq driver.
> + #interrupt-cells = <2>;
> + reg = <0x10700 0x00000000 0x0 0x7000>;
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/gpio.txt b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
> new file mode 100644
> index 0000000..72853d4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
> @@ -0,0 +1,48 @@
> +* General Purpose Input Output (GPIO) bus.
> +
> +Properties:
> +- compatible: "cavium,octeon-3860-gpio"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the GPIO unit's register bank.
> +
> +- gpio-controller: This is a GPIO controller.
> +
> +- #gpio-cells: Must be <2>. The first cell is the GPIO pin.
> +
> +- interrupt-controller: The GPIO controller is also an interrupt
> + controller, any of its pins may be configured as an interrupt
> + source.
> +
> +- #interrupt-cells: Must be <2>. The first cell is the GPIO pin
> + connected to the interrupt source. The second cell is the interrupt
> + triggering protocol and may have one of four values:
> + 0 - level triggered active high.
> + 1 - level triggered active low
> + 2 - edge triggered on the rising edge.
> + 3 - edge triggered on the falling edge.
Since you're choosing arbitrary values here anyway, it's convenient to
follow the lead of include/linux/irq.h and using 1->edge rising,
2->edge falling, 4->level high, 8->level low. In the past every irq
controller kind of did it's own thing, but that's not very scalable.
> +
> +- interrupts: Interrupt routing for pin 0. The remaining pins are
> + also routed, but in a manner that can be derived from the pin0
> + routing, so they are not specified.
> +
> +Example:
> +
> + gpio-controller@1070000000800 {
> + #gpio-cells = <2>;
> + compatible = "cavium,octeon-3860-gpio";
> + reg = <0x10700 0x00000800 0x0 0x100>;
> + gpio-controller;
> + /* Interrupts are specified by two parts:
> + * 1) GPIO pin number (0..15)
> + * 2) Triggering (0 - level active high
> + * 1 - level active low
> + * 2 - edge rising
> + * 3 - edge falling
> + */
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + /* The GPIO pin connect to 16 consecutive CUI bits */
> + interrupts = <0 16>;
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/mdio.txt b/Documentation/devicetree/bindings/mips/cavium/mdio.txt
> new file mode 100644
> index 0000000..6253c3b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/mdio.txt
> @@ -0,0 +1,27 @@
> +* System Management Interface (SMI) / MDIO
> +
> +Properties:
> +- compatible: "cavium,octeon-3860-mdio"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the MDIO bus controller register bank.
> +
> +- #address-cells: Must be <1>.
> +
> +- #size-cells: Must be <0>. MDIO addresses have no size component.
> +
> +Typically an MDIO bus might have several children.
> +
> +Example:
> + mdio@1180000001800 {
> + compatible = "cavium,octeon-3860-mdio";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x11800 0x00001800 0x0 0x40>;
> +
> + ethernet-phy@0 {
> + ...
> + reg = <0>;
> + };
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/mix.txt b/Documentation/devicetree/bindings/mips/cavium/mix.txt
> new file mode 100644
> index 0000000..2a91a33
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/mix.txt
> @@ -0,0 +1,40 @@
> +* MIX Ethernet controller.
> +
> +Properties:
> +- compatible: "cavium,octeon-5750-mix"
> +
> + Compatibility with all cn5XXX and cn6XXX SOCs populated with MIX
> + devices.
> +
> +- reg: The base addresses of four seperate register banks. The first
> + bank contains the MIX registers. The second bank the corresponding
> + AGL registers. The third bank are the AGL registers shared by all
> + MIX devices present. The fourth bank is the AGL_PRT_CTL shared by
> + all MIX devices present.
> +
> +- cell-index: A single cell specifying which portion of the shared
> + register banks corresponds to this MIX device.
> +
> +- interrupts: Two interrupt specifiers. The first is the MIX
> + interrupt routing and the second the routing for the AGL interrupts.
> +
> +- mac-address: Optional, the MAC address to assign to the device.
> +
> +- local-mac-address: Optional, the MAC address to assign to the device
> + if mac-address is not specified.
> +
> +- phy-handle: Optional, a phandle for the PHY device connected to this device.
> +
> +Example:
> + ethernet@1070000100800 {
> + compatible = "cavium,octeon-5750-mix";
> + reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
> + <0x11800 0xE0000800 0x0 0x300>, /* AGL */
> + <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
> + <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
> + cell-index = <1>;
> + interrupts = <1 18>, < 1 46>;
> + local-mac-address = [ 00 0f b7 10 63 54 ];
> + phy-handle = <&phy1>;
> + };
> +
> diff --git a/Documentation/devicetree/bindings/mips/cavium/pip.txt b/Documentation/devicetree/bindings/mips/cavium/pip.txt
> new file mode 100644
> index 0000000..d4c53ba
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/pip.txt
> @@ -0,0 +1,98 @@
> +* PIP Ethernet nexus.
> +
> +The PIP Ethernet nexus can control several data packet input/output
> +devices. The devices have a two level grouping scheme. There may be
> +several interfaces, and each interface may have several ports. These
> +ports might be an individual Ethernet PHY.
> +
> +
> +Properties for the PIP nexus:
> +- compatible: "cavium,octeon-3860-pip"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the PIP's register bank.
> +
> +- #address-cells: Must be <1>.
> +
> +- #size-cells: Must be <0>.
> +
> +Properties for PIP interfaces which is a child the PIP nexus:
> +- compatible: "cavium,octeon-3860-pip-interface"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The interface number.
> +
> +- #address-cells: Must be <1>.
> +
> +- #size-cells: Must be <0>.
> +
> +Properties for PIP port which is a child the PIP interface:
> +- compatible: "cavium,octeon-3860-pip-port"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The port number within the interface group.
> +
> +- mac-address: Optional, the MAC address to assign to the device.
> +
> +- local-mac-address: Optional, the MAC address to assign to the device
> + if mac-address is not specified.
> +
> +- phy-handle: Optional, a phandle for the PHY device connected to this device.
> +
> +Example:
> +
> + pip@11800a0000000 {
> + compatible = "cavium,octeon-3860-pip";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x11800 0xa0000000 0x0 0x2000>;
> +
> + interface@0 {
> + compatible = "cavium,octeon-3860-pip-interface";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>; /* interface */
> +
> + ethernet@0 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x0>; /* Port */
> + local-mac-address = [ 00 0f b7 10 63 60 ];
> + phy-handle = <&phy2>;
> + };
> + ethernet@1 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x1>; /* Port */
> + local-mac-address = [ 00 0f b7 10 63 61 ];
> + phy-handle = <&phy3>;
> + };
> + ethernet@2 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x2>; /* Port */
> + local-mac-address = [ 00 0f b7 10 63 62 ];
> + phy-handle = <&phy4>;
> + };
> + ethernet@3 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x3>; /* Port */
> + local-mac-address = [ 00 0f b7 10 63 63 ];
> + phy-handle = <&phy5>;
> + };
> + };
> +
> + interface@1 {
> + compatible = "cavium,octeon-3860-pip-interface";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>; /* interface */
> +
> + ethernet@0 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x0>; /* Port */
> + local-mac-address = [ 00 0f b7 10 63 64 ];
> + phy-handle = <&phy6>;
> + };
> + };
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/twsi.txt b/Documentation/devicetree/bindings/mips/cavium/twsi.txt
> new file mode 100644
> index 0000000..6e57155
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/twsi.txt
> @@ -0,0 +1,34 @@
> +* Two Wire Serial Interface (TWSI) / I2C
> +
> +- compatible: "cavium,octeon-3860-twsi"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the TWSI/I2C bus controller register bank.
> +
> +- #address-cells: Must be <1>.
> +
> +- #size-cells: Must be <0>. I2C addresses have no size component.
> +
> +- interrupts: A single interrupt specifier.
> +
> +- clock-rate: The I2C bus clock rate in Hz.
> +
> +Example:
> + twsi0: i2c@1180000001000 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "cavium,octeon-3860-twsi";
> + reg = <0x11800 0x00001000 0x0 0x200>;
> + interrupts = <0 45>;
> + clock-rate = <100000>;
> +
> + rtc@68 {
> + compatible = "dallas,ds1337";
> + reg = <0x68>;
> + };
> + tmp@4c {
> + compatible = "ti,tmp421";
> + reg = <0x4c>;
> + };
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/uart.txt b/Documentation/devicetree/bindings/mips/cavium/uart.txt
> new file mode 100644
> index 0000000..87a6c37
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/uart.txt
> @@ -0,0 +1,19 @@
> +* Universal Asynchronous Receiver/Transmitter (UART)
> +
> +- compatible: "cavium,octeon-3860-uart"
> +
> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
> +
> +- reg: The base address of the UART register bank.
> +
> +- interrupts: A single interrupt specifier.
> +
> +- current-speed: Optional, the current bit rate in bits per second.
> +
> +Example:
> + uart1: serial@1180000000c00 {
> + compatible = "cavium,octeon-3860-uart","ns16550";
> + reg = <0x11800 0x00000c00 0x0 0x400>;
> + current-speed = <115200>;
> + interrupts = <0 35>;
> + };
> diff --git a/Documentation/devicetree/bindings/mips/cavium/uctl.txt b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
> new file mode 100644
> index 0000000..5dabe02
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
> @@ -0,0 +1,47 @@
> +* UCTL USB controller glue
> +
> +Properties:
> +- compatible: "cavium,octeon-6335-uctl"
> +
> + Compatibility with all cn6XXX SOCs.
> +
> +- reg: The base address of the UCTL register bank.
> +
> +- #address-cells: Must be <2>.
> +
> +- #size-cells: Must be <2>.
> +
> +- ranges: Empty to signify direct mapping of the children.
> +
> +- refclk-frequency: A single cell containing the reference clock
> + frequency in Hz.
> +
> +- refclk-type: A string describing the reference clock connection
> + either "crystal" or "external".
> +
> +Example:
> + uctl@118006f000000 {
> + compatible = "cavium,octeon-6335-uctl";
> + reg = <0x11800 0x6f000000 0x0 0x100>;
> + ranges; /* Direct mapping */
> + #address-cells = <2>;
> + #size-cells = <2>;
> + /* 12MHz, 24MHz and 48MHz allowed */
> + refclk-frequency = <24000000>;
> + /* Either "crystal" or "external" */
> + refclk-type = "crystal";
> +
> + ehci@16f0000000000 {
> + compatible = "cavium,octeon-6335-ehci","usb-ehci";
> + reg = <0x16f00 0x00000000 0x0 0x100>;
> + interrupts = <0 56>;
> + big-endian-regs;
> + };
> + ohci@16f0000000400 {
> + compatible = "cavium,octeon-6335-ohci","usb-ohci";
> + reg = <0x16f00 0x00000400 0x0 0x100>;
> + interrupts = <0 56>;
> + big-endian-regs;
> + };
> + };
> +
> diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore
> new file mode 100644
> index 0000000..39c9686
> --- /dev/null
> +++ b/arch/mips/cavium-octeon/.gitignore
> @@ -0,0 +1,2 @@
> +*.dtb.S
> +*.dtb
> diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
> index 19eb043..b8d4f63 100644
> --- a/arch/mips/cavium-octeon/Makefile
> +++ b/arch/mips/cavium-octeon/Makefile
> @@ -15,3 +15,16 @@ obj-y += octeon-memcpy.o
> obj-y += executive/
>
> obj-$(CONFIG_SMP) += smp.o
> +
> +DTS_FILES = octeon_3xxx.dts
> +DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
> +
> +obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
> +
> +$(obj)/%.dtb: $(src)/%.dts
> + $(call cmd,dtc)
> +
> +# Let's keep the .dtb files around in case we want to look at them.
> +.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
> +
> +clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES))
> diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
> new file mode 100644
> index 0000000..2b371dc
> --- /dev/null
> +++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
> @@ -0,0 +1,375 @@
> +/dts-v1/;
> +/*
> + * OCTEON 3XXX, 5XXX, 63XX device tree skeleton.
> + *
> + * This device tree is pruned and patched by early boot code before
> + * use. Because of this, it contains a super-set of the available
> + * devices and properties.
> + */
> +/ {
> + compatible = "cavium,octeon-3860";
> + #address-cells = <2>;
> + #size-cells = <2>;
> + interrupt-parent = <&ciu>;
> +
> + soc@0 {
> + compatible = "simple-bus";
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges; /* Direct mapping */
> +
> + ciu: interrupt-controller@1070000000000 {
> + compatible = "cavium,octeon-3860-ciu";
> + interrupt-controller;
> + /* Interrupts are specified by two parts:
> + * 1) Controller register (0 or 1)
> + * 2) Bit within the register (0..63)
> + */
> + #interrupt-cells = <2>;
> + reg = <0x10700 0x00000000 0x0 0x7000>;
> + };
> +
> + gpio: gpio-controller@1070000000800 {
> + #gpio-cells = <2>;
> + compatible = "cavium,octeon-3860-gpio";
> + reg = <0x10700 0x00000800 0x0 0x100>;
> + gpio-controller;
> + /* Interrupts are specified by two parts:
> + * 1) GPIO pin number (0..15)
> + * 2) Triggering (0 - level active high
> + * 1 - level active low
> + * 2 - edge rising
> + * 3 - edge falling
> + */
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + /* The GPIO pin connect to 16 consecutive CUI bits */
> + interrupts = <0 16>; /* <0 17> <0 18> <0 19>
> + <0 20> <0 21> <0 22> <0 23>
> + <0 24> <0 25> <0 26> <0 27>
> + <0 28> <0 29> <0 30> <0 31>; */
> + };
> +
> + smi0: mdio@1180000001800 {
> + compatible = "cavium,octeon-3860-mdio";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x11800 0x00001800 0x0 0x40>;
> +
> + phy0: ethernet-phy@0 {
> + compatible = "broadcom,bcm5241";
> + reg = <0>;
> + };
> +
> + phy1: ethernet-phy@1 {
> + compatible = "broadcom,bcm5241";
> + reg = <1>;
> + };
> +
> + phy2: ethernet-phy@2 {
> + reg = <2>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + interrupt-parent = <&gpio>;
> + interrupts = <5 1>; /* Pin 5, active low */
> + };
> + phy3: ethernet-phy@3 {
> + reg = <3>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + interrupt-parent = <&gpio>;
> + interrupts = <5 1>; /* Pin 5, active low */
> + };
> + phy4: ethernet-phy@4 {
> + reg = <4>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + interrupt-parent = <&gpio>;
> + interrupts = <5 1>; /* Pin 5, active low */
> + };
> + phy5: ethernet-phy@5 {
> + reg = <5>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + interrupt-parent = <&gpio>;
> + interrupts = <5 1>; /* Pin 5, active low */
> + };
> +
> + phy6: ethernet-phy@6 {
> + reg = <6>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + };
> + phy7: ethernet-phy@7 {
> + reg = <7>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + };
> + phy8: ethernet-phy@8 {
> + reg = <8>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + };
> + phy9: ethernet-phy@9 {
> + reg = <9>;
> + compatible = "marvell,88e1149r";
> + marvell,reg-init = <3 0x10 0 0x5777>,
> + <3 0x11 0 0x00aa>,
> + <3 0x12 0 0x4105>,
> + <3 0x13 0 0x0a60>;
> + };
> + };
> +
> + smi1: mdio@1180000001900 {
> + compatible = "cavium,octeon-3860-mdio";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x11800 0x00001900 0x0 0x40>;
> + };
> +
> + mix0: ethernet@1070000100000 {
> + compatible = "cavium,octeon-5750-mix";
> + reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
> + <0x11800 0xE0000000 0x0 0x300>, /* AGL */
> + <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
> + <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
> + cell-index = <0>;
> + interrupts = <0 62>, <1 46>;
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy0>;
> + };
> +
> + mix1: ethernet@1070000100800 {
> + compatible = "cavium,octeon-5750-mix";
> + reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
> + <0x11800 0xE0000800 0x0 0x300>, /* AGL */
> + <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
> + <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
> + cell-index = <1>;
> + interrupts = <1 18>, < 1 46>;
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy1>;
> + };
> +
> + pip: pip@11800a0000000 {
> + compatible = "cavium,octeon-3860-pip";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0x11800 0xa0000000 0x0 0x2000>;
> +
> + interface@0 {
> + compatible = "cavium,octeon-3860-pip-interface";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>; /* interface */
> +
> + ethernet@0 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x0>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy2>;
> + };
> + ethernet@1 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x1>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy3>;
> + };
> + ethernet@2 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x2>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy4>;
> + };
> + ethernet@3 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x3>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy5>;
> + };
> + };
> +
> + interface@1 {
> + compatible = "cavium,octeon-3860-pip-interface";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>; /* interface */
> +
> + ethernet@0 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x0>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy6>;
> + };
> + ethernet@1 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x1>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy7>;
> + };
> + ethernet@2 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x2>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy8>;
> + };
> + ethernet@3 {
> + compatible = "cavium,octeon-3860-pip-port";
> + reg = <0x3>; /* Port */
> + local-mac-address = [ 00 00 00 00 00 00 ];
> + phy-handle = <&phy9>;
> + };
> + };
> + };
> +
> + twsi0: i2c@1180000001000 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "cavium,octeon-3860-twsi";
> + reg = <0x11800 0x00001000 0x0 0x200>;
> + interrupts = <0 45>;
> + clock-rate = <100000>;
> +
> + rtc@68 {
> + compatible = "dallas,ds1337";
> + reg = <0x68>;
> + };
> + tmp@4c {
> + compatible = "ti,tmp421";
> + reg = <0x4c>;
> + };
> + };
> +
> + twsi1: i2c@1180000001200 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "cavium,octeon-3860-twsi";
> + reg = <0x11800 0x00001200 0x0 0x200>;
> + interrupts = <0 59>;
> + clock-rate = <100000>;
> + };
> +
> + uart0: serial@1180000000800 {
> + compatible = "cavium,octeon-3860-uart","ns16550";
> + reg = <0x11800 0x00000800 0x0 0x400>;
> + clock-frequency = <0>;
> + current-speed = <115200>;
> + reg-shift = <3>;
> + interrupts = <0 34>;
> + };
> +
> + uart1: serial@1180000000c00 {
> + compatible = "cavium,octeon-3860-uart","ns16550";
> + reg = <0x11800 0x00000c00 0x0 0x400>;
> + clock-frequency = <0>;
> + current-speed = <115200>;
> + reg-shift = <3>;
> + interrupts = <0 35>;
> + };
> +
> + uart2: serial@1180000000400 {
> + compatible = "cavium,octeon-3860-uart","ns16550";
> + reg = <0x11800 0x00000400 0x0 0x400>;
> + clock-frequency = <0>;
> + current-speed = <115200>;
> + reg-shift = <3>;
> + interrupts = <1 16>;
> + };
> +
> + bootbus: bootbus@1180000000000 {
> + compatible = "cavium,octeon-3860-bootbus";
> + reg = <0x11800 0x00000000 0x0 0x200>;
> + /* The chip select number and offset */
> + #address-cells = <2>;
> + /* The size of the chip select region */
> + #size-cells = <1>;
> + ranges = <0 0 0x0 0x1f400000 0x1000000>,
> + <1 0 0x1 0x30000000 0x10000000>,
> + <2 0 0x1 0x40000000 0x10000000>,
> + <3 0 0x1 0x50000000 0x10000000>,
> + <4 0 0x1 0x60000000 0x10000000>,
> + <5 0 0x1 0x70000000 0x10000000>,
> + <6 0 0x1 0x80000000 0x10000000>,
> + <7 0 0x1 0x90000000 0x10000000>;
> +
> + flash0: nor@0,0 {
> + compatible = "cfi-flash";
> + reg = <0 0 0x800000>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + partition@0 {
> + label = "firmware";
> + reg = <0x0 0x400000>;
> + read-only;
> + };
> +
> + partition@400000 {
> + label = "data";
> + reg = <0x400000 0x400000>;
> + read-only;
> + };
> + };
> + };
> +
> + uctl: uctl@118006f000000 {
> + compatible = "cavium,octeon-6335-uctl";
> + reg = <0x11800 0x6f000000 0x0 0x100>;
> + ranges; /* Direct mapping */
> + #address-cells = <2>;
> + #size-cells = <2>;
> + /* 12MHz, 24MHz and 48MHz allowed */
> + refclk-frequency = <24000000>;
> + /* Either "crystal" or "external" */
> + refclk-type = "crystal";
> +
> + ehci@16f0000000000 {
> + compatible = "cavium,octeon-6335-ehci","usb-ehci";
> + reg = <0x16f00 0x00000000 0x0 0x100>;
> + interrupts = <0 56>;
> + big-endian-regs;
> + };
> + ohci@16f0000000400 {
> + compatible = "cavium,octeon-6335-ohci","usb-ohci";
> + reg = <0x16f00 0x00000400 0x0 0x100>;
> + interrupts = <0 56>;
> + big-endian-regs;
> + };
> + };
> + };
> +
> + aliases {
> + mix0 = &mix0;
> + mix1 = &mix1;
> + pip = &pip;
> + smi0 = &smi0;
> + smi1 = &smi1;
> + twsi0 = &twsi0;
> + twsi1 = &twsi1;
> + uart0 = &uart0;
> + uart1 = &uart1;
> + uart2 = &uart2;
> + flash0 = &flash0;
> + };
> + };
> --
> 1.7.2.3
>
On Fri, May 20, 2011 at 03:25:41PM -0700, David Daney wrote:
> This code is not common enough to be in a shared file. It is also not
> used by any existing boards, so just remove it.
>
> Signed-off-by: David Daney <[email protected]>
> ---
> arch/mips/kernel/prom.c | 49 -----------------------------------------------
> 1 files changed, 0 insertions(+), 49 deletions(-)
>
> diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
> index a19811e9..a07b6f1 100644
> --- a/arch/mips/kernel/prom.c
> +++ b/arch/mips/kernel/prom.c
> @@ -59,52 +59,3 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
> initrd_below_start_ok = 1;
> }
> #endif
> -
> -/*
> - * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
> - *
> - * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
> - * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
> - * supported.
> - */
> -unsigned int irq_create_of_mapping(struct device_node *controller,
> - const u32 *intspec, unsigned int intsize)
> -{
> - return intspec[0];
> -}
> -EXPORT_SYMBOL_GPL(irq_create_of_mapping);
In $NEXT_KERNEL+1 irq_create_of_mapping will be replaced by common
infrastructure code after irq_domain is merged, so this will become
irrelevant anyway.
> -
> -void __init early_init_devtree(void *params)
> -{
> - /* Setup flat device-tree pointer */
> - initial_boot_params = params;
> -
> - /* Retrieve various informations from the /chosen node of the
> - * device-tree, including the platform type, initrd location and
> - * size, and more ...
> - */
> - of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
> -
> - /* Scan memory nodes */
> - of_scan_flat_dt(early_init_dt_scan_root, NULL);
> - of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
> -}
> -
> -void __init device_tree_init(void)
> -{
> - unsigned long base, size;
> -
> - if (!initial_boot_params)
> - return;
> -
> - base = virt_to_phys((void *)initial_boot_params);
> - size = be32_to_cpu(initial_boot_params->totalsize);
> -
> - /* Before we do anything, lets reserve the dt blob */
> - reserve_mem_mach(base, size);
> -
> - unflatten_device_tree();
> -
> - /* free the space reserved for the dt blob */
> - free_mem_mach(base, size);
> -}
I'm a little concerned that the MIPS platforms are not sharing the
same DT init code. This isn't really something that should need to be
customized per-platform.
g.
On Fri, May 20, 2011 at 03:25:39PM -0700, David Daney wrote:
> Currently all paths passed to of_find_node_by_path() must begin with a
> '/', indicating a full path to the desired node.
>
> Augment the look-up code so that if a path does *not* begin with '/',
> the path is used as the name of an /aliases property. The value of
> this alias is then used as the full node path to be found.
>
> Signed-off-by: David Daney <[email protected]>
> ---
> drivers/of/base.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 632ebae..279134b 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -340,22 +340,64 @@ EXPORT_SYMBOL(of_get_next_child);
>
> /**
> * of_find_node_by_path - Find a node matching a full OF path
> - * @path: The full path to match
> + * @path: Either the full path to match, or if the path does not
> + * start with '/', the name of a property of the /aliases
> + * node (an alias). In the case of an alias, the node
> + * matching the alias' value will be returned.
> *
> * Returns a node pointer with refcount incremented, use
> * of_node_put() on it when done.
> */
> struct device_node *of_find_node_by_path(const char *path)
> {
> - struct device_node *np = allnodes;
> + struct device_node *np = NULL;
> + struct device_node *aliases = NULL;
> + char *alias = NULL;
> + char *new_path = NULL;
>
> read_lock(&devtree_lock);
> - for (; np; np = np->allnext) {
> +
> + if (path[0] != '/') {
> + const char *ps;
> + aliases = of_find_node_by_path("/aliases");
> + if (!aliases)
> + goto out;
Hmmm, we should probably cache the pointer to this node.
> +
> + ps = strchr(path, '/');
> + if (ps) {
> + size_t len = ps - path;
> + alias = kstrndup(path, len, GFP_KERNEL);
> + if (!alias)
> + goto out;
> + path = of_get_property(aliases, alias, NULL);
> + if (!path)
> + goto out;
> +
> + len = strlen(path) + strlen(ps) + 1;
> + new_path = kmalloc(len, GFP_KERNEL);
> + if (!new_path)
> + goto out;
> + strcpy(new_path, path);
> + strcat(new_path, ps);
> + path = new_path;
> + } else {
> + path = of_get_property(aliases, path, NULL);
> + }
> + if (!path)
> + goto out;
> + }
Looks about right, but I think it can be a bit more elegant and I think it
should be better documented. Perhaps something like this?
/*
* The following code has three possibilities:
* 1) '/' at start of string; path == ps; (based at root)
* 2) '/' at offset in string; path < ps; (relative to alias)
* 3) '/' not found; ps == NULL; (alias only)
*
* If ps != path, then it is either a pure alias (ps == NULL), or an
* alias with a relative path (path < ps). Either way, look up the path
* pointed to by the alias.
*/
ps = strchr(path, '/');
if (path != ps) {
aliases = of_find_node_by_path("/aliases");
if (!aliases)
goto out;
/* Duplicate the alias part of the string so it can be NULL terminated */
alias = kstrndup(path, ps ? (ps - path) : strlen(path), GFP_KERNEL);
if (!alias)
goto out;
path = of_get_property(aliases, alias, NULL);
if (!path || path[0] != '/')
goto out;
/* If ps is not NULL, then there is a relative path to append */
if (ps) {
path = new_path = kzalloc(strlen(path) + strlen(ps) + 1, GFP_KERNEL);
if (!path)
goto out;
sprintf(new_path, "%s%s", path, ps);
}
}
/*
* At this point, path now points to the full unaliased path to a node,
* regardless of whether or not it started with an alias
*/
What do you think?
g.
> +
> + for (np = allnodes; np; np = np->allnext) {
> if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
> && of_node_get(np))
> break;
> }
> +out:
> + if (aliases)
> + of_node_put(aliases);
> read_unlock(&devtree_lock);
> + kfree(alias);
> + kfree(new_path);
> return np;
> }
> EXPORT_SYMBOL(of_find_node_by_path);
> --
> 1.7.2.3
>
On Mon, May 23, 2011 at 09:47:56AM -0700, David Daney wrote:
> On 05/20/2011 11:33 PM, David Gibson wrote:
> >On Fri, May 20, 2011 at 03:25:38PM -0700, David Daney wrote:
> >>To use it you need to do this in your Kconfig:
> >>
> >> select LIBFDT
> >>
> >>And in the Makefile of the code using libfdt something like:
> >>
> >>ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
> >>
> >>Signed-off-by: David Daney<[email protected]>
> >>---
> >> drivers/of/Kconfig | 3 +++
> >> drivers/of/Makefile | 2 ++
> >> drivers/of/libfdt/Makefile | 3 +++
> >> drivers/of/libfdt/fdt.c | 2 ++
> >> drivers/of/libfdt/fdt_ro.c | 2 ++
> >> drivers/of/libfdt/fdt_wip.c | 2 ++
> >
> >No fdt_sw.c or fdt_rw.c?
> >
>
> I had no immediate need for them. They could of course be added,
> but that would potentially waste space.
>
> Let's see if I can make it into an archive library.
That would be preferable. It's more or less designed to work that way
so that everything is available without using unnecessary space in the
binary.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
On 05/26/2011 08:24 PM, David Gibson wrote:
> On Mon, May 23, 2011 at 09:47:56AM -0700, David Daney wrote:
>> On 05/20/2011 11:33 PM, David Gibson wrote:
>>> On Fri, May 20, 2011 at 03:25:38PM -0700, David Daney wrote:
>>>> To use it you need to do this in your Kconfig:
>>>>
>>>> select LIBFDT
>>>>
>>>> And in the Makefile of the code using libfdt something like:
>>>>
>>>> ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
>>>>
>>>> Signed-off-by: David Daney<[email protected]>
>>>> ---
>>>> drivers/of/Kconfig | 3 +++
>>>> drivers/of/Makefile | 2 ++
>>>> drivers/of/libfdt/Makefile | 3 +++
>>>> drivers/of/libfdt/fdt.c | 2 ++
>>>> drivers/of/libfdt/fdt_ro.c | 2 ++
>>>> drivers/of/libfdt/fdt_wip.c | 2 ++
>>>
>>> No fdt_sw.c or fdt_rw.c?
>>>
>>
>> I had no immediate need for them. They could of course be added,
>> but that would potentially waste space.
>>
>> Let's see if I can make it into an archive library.
>
> That would be preferable. It's more or less designed to work that way
> so that everything is available without using unnecessary space in the
> binary.
>
Well, I was looking at this some more:
Grant specifically requested that this go in drivers/of/libfdt, however
I am fairly sure that building archive libraries there will require
changes to the upper level Makefile infrastructure.
If I go back to lib/libfdt, like my first version, I can easily achieve
archive library behavior, but then it is separated from from drivers/of.
Personally I am starting to like the lib/libfdt home more than
drivers/of. If Grant doesn't object, I think I will move it back there.
What do you think?
David Daney
On 05/26/2011 06:56 PM, Grant Likely wrote:
> On Fri, May 20, 2011 at 03:25:40PM -0700, David Daney wrote:
>> Signed-off-by: David Daney<[email protected]>
>> ---
>> .../devicetree/bindings/mips/cavium/bootbus.txt | 37 ++
>> .../devicetree/bindings/mips/cavium/ciu.txt | 26 ++
>> .../devicetree/bindings/mips/cavium/gpio.txt | 48 +++
>> .../devicetree/bindings/mips/cavium/mdio.txt | 27 ++
>> .../devicetree/bindings/mips/cavium/mix.txt | 40 ++
>> .../devicetree/bindings/mips/cavium/pip.txt | 98 +++++
>> .../devicetree/bindings/mips/cavium/twsi.txt | 34 ++
>> .../devicetree/bindings/mips/cavium/uart.txt | 19 +
>> .../devicetree/bindings/mips/cavium/uctl.txt | 47 +++
>> arch/mips/cavium-octeon/.gitignore | 2 +
>> arch/mips/cavium-octeon/Makefile | 13 +
>> arch/mips/cavium-octeon/octeon_3xxx.dts | 375 ++++++++++++++++++++
>> 12 files changed, 766 insertions(+), 0 deletions(-)
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/gpio.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/mdio.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/mix.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/pip.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/twsi.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/uart.txt
>> create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
>> create mode 100644 arch/mips/cavium-octeon/.gitignore
>> create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
>
> Looks pretty good to me. A few comments below, but I'm okay with this
> one being picked up (Ralf, or if you prefer then I can merge it via my
> tree) as long as you follow it up with a fixup patch.
This was only an RFC. The whole patch set needs at least one more
revision to synchronize it with my boards' u-boot changes.
I will post another set soon, and perhaps that can go via Ralf's tree.
[...]
>> +++ b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
>> @@ -0,0 +1,26 @@
>> +* Central Interrupt Unit
>> +
>> +Properties:
>> +- compatible: "cavium,octeon-3860-ciu"
>> +
>> + Compatibility with all cn3XXX, cn5XXX and cn63XX SOCs.
>> +
>> +- interrupt-controller: This is an interrupt controller.
>> +
>> +- reg: The base address of the CIU's register bank.
>> +
>> +- #interrupt-cells: Must be<2>. The first cell is the bank within
>> + the CIU and may have a value of 0 or 1. The second cell is the bit
>> + within the bank and may have a value between 0 and 63.
>> +
>> +Example:
>> + interrupt-controller@1070000000000 {
>> + compatible = "cavium,octeon-3860-ciu";
>> + interrupt-controller;
>> + /* Interrupts are specified by two parts:
>> + * 1) Controller register (0 or 1)
>> + * 2) Bit within the register (0..63)
>> + */
>
> Are there any configuration parameters for these irq inputs? Edge vs.
> Level? Active high or active low? If so, then you'll probably want to
> have a flags cell.
No. They are all internal to the SOC and cannot be changed. The chip
IRQ code knows how to deal with them.
>
> Also, how are the irqs typically documented in the hardware reference
> manual? Are they documented a irqs 0-63 in bank 1 and 0-63 in bank 2?
Yes, they are clearly documented as two banks.
> Or are is a flat 0-127 number range? If it is the later, then you may
> want to consider just using a single cell to specify the irq number,
> and handle the bank calculation in the irq driver.
>
>> + #interrupt-cells =<2>;
>> + reg =<0x10700 0x00000000 0x0 0x7000>;
>> + };
>> diff --git a/Documentation/devicetree/bindings/mips/cavium/gpio.txt b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
>> new file mode 100644
>> index 0000000..72853d4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mips/cavium/gpio.txt
>> @@ -0,0 +1,48 @@
>> +* General Purpose Input Output (GPIO) bus.
>> +
>> +Properties:
>> +- compatible: "cavium,octeon-3860-gpio"
>> +
>> + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
>> +
>> +- reg: The base address of the GPIO unit's register bank.
>> +
>> +- gpio-controller: This is a GPIO controller.
>> +
>> +- #gpio-cells: Must be<2>. The first cell is the GPIO pin.
>> +
>> +- interrupt-controller: The GPIO controller is also an interrupt
>> + controller, any of its pins may be configured as an interrupt
>> + source.
>> +
>> +- #interrupt-cells: Must be<2>. The first cell is the GPIO pin
>> + connected to the interrupt source. The second cell is the interrupt
>> + triggering protocol and may have one of four values:
>> + 0 - level triggered active high.
>> + 1 - level triggered active low
>> + 2 - edge triggered on the rising edge.
>> + 3 - edge triggered on the falling edge.
>
> Since you're choosing arbitrary values here anyway, it's convenient to
> follow the lead of include/linux/irq.h and using 1->edge rising,
> 2->edge falling, 4->level high, 8->level low. In the past every irq
> controller kind of did it's own thing, but that's not very scalable.
>
OK. I will use those still somewhat arbitrary values instead.
[...]
Thanks,
David Daney
On 05/26/2011 06:58 PM, Grant Likely wrote:
> On Fri, May 20, 2011 at 03:25:41PM -0700, David Daney wrote:
>> This code is not common enough to be in a shared file. It is also not
>> used by any existing boards, so just remove it.
>>
>> Signed-off-by: David Daney<[email protected]>
>> ---
>> arch/mips/kernel/prom.c | 49 -----------------------------------------------
>> 1 files changed, 0 insertions(+), 49 deletions(-)
>>
>> diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
>> index a19811e9..a07b6f1 100644
>> --- a/arch/mips/kernel/prom.c
>> +++ b/arch/mips/kernel/prom.c
>> @@ -59,52 +59,3 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
>> initrd_below_start_ok = 1;
>> }
>> #endif
>> -
>> -/*
>> - * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
>> - *
>> - * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
>> - * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
>> - * supported.
>> - */
>> -unsigned int irq_create_of_mapping(struct device_node *controller,
>> - const u32 *intspec, unsigned int intsize)
>> -{
>> - return intspec[0];
>> -}
>> -EXPORT_SYMBOL_GPL(irq_create_of_mapping);
>
> In $NEXT_KERNEL+1 irq_create_of_mapping will be replaced by common
> infrastructure code after irq_domain is merged, so this will become
> irrelevant anyway.
Yes, I saw your patch. I will be tracking that as it gets merged.
>
>> -
>> -void __init early_init_devtree(void *params)
>> -{
>> - /* Setup flat device-tree pointer */
>> - initial_boot_params = params;
>> -
>> - /* Retrieve various informations from the /chosen node of the
>> - * device-tree, including the platform type, initrd location and
>> - * size, and more ...
>> - */
>> - of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
>> -
>> - /* Scan memory nodes */
>> - of_scan_flat_dt(early_init_dt_scan_root, NULL);
>> - of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
>> -}
>> -
>> -void __init device_tree_init(void)
>> -{
>> - unsigned long base, size;
>> -
>> - if (!initial_boot_params)
>> - return;
>> -
>> - base = virt_to_phys((void *)initial_boot_params);
>> - size = be32_to_cpu(initial_boot_params->totalsize);
>> -
>> - /* Before we do anything, lets reserve the dt blob */
>> - reserve_mem_mach(base, size);
>> -
>> - unflatten_device_tree();
>> -
>> - /* free the space reserved for the dt blob */
>> - free_mem_mach(base, size);
>> -}
>
> I'm a little concerned that the MIPS platforms are not sharing the
> same DT init code. This isn't really something that should need to be
> customized per-platform.
>
For better or worse, the Octeon kernel is booted with a protocol
completely different than any other MIPS board. So there has to be some
custom code to find and initialize the device tree.
For boards that boot with the u-boot 'bootm' protocol, I think we need
to pass the device tree in the environment like other architectures do.
The bootm code could, I think, be made common to all MIPS ports.
David Daney
On Fri, May 27, 2011 at 09:49:38AM -0700, David Daney wrote:
> On 05/26/2011 08:24 PM, David Gibson wrote:
> >On Mon, May 23, 2011 at 09:47:56AM -0700, David Daney wrote:
> >>On 05/20/2011 11:33 PM, David Gibson wrote:
> >>>On Fri, May 20, 2011 at 03:25:38PM -0700, David Daney wrote:
> >>>>To use it you need to do this in your Kconfig:
> >>>>
> >>>> select LIBFDT
> >>>>
> >>>>And in the Makefile of the code using libfdt something like:
> >>>>
> >>>>ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
> >>>>
> >>>>Signed-off-by: David Daney<[email protected]>
> >>>>---
> >>>> drivers/of/Kconfig | 3 +++
> >>>> drivers/of/Makefile | 2 ++
> >>>> drivers/of/libfdt/Makefile | 3 +++
> >>>> drivers/of/libfdt/fdt.c | 2 ++
> >>>> drivers/of/libfdt/fdt_ro.c | 2 ++
> >>>> drivers/of/libfdt/fdt_wip.c | 2 ++
> >>>
> >>>No fdt_sw.c or fdt_rw.c?
> >>>
> >>
> >>I had no immediate need for them. They could of course be added,
> >>but that would potentially waste space.
> >>
> >>Let's see if I can make it into an archive library.
> >
> >That would be preferable. It's more or less designed to work that way
> >so that everything is available without using unnecessary space in the
> >binary.
> >
>
> Well, I was looking at this some more:
>
> Grant specifically requested that this go in drivers/of/libfdt,
> however I am fairly sure that building archive libraries there will
> require changes to the upper level Makefile infrastructure.
>
> If I go back to lib/libfdt, like my first version, I can easily
> achieve archive library behavior, but then it is separated from from
> drivers/of.
>
> Personally I am starting to like the lib/libfdt home more than
> drivers/of. If Grant doesn't object, I think I will move it back
> there.
okay.
g.
On Fri, May 27, 2011 at 10:00:02AM -0700, David Daney wrote:
> On 05/26/2011 06:56 PM, Grant Likely wrote:
> >>+- #interrupt-cells: Must be<2>. The first cell is the GPIO pin
> >>+ connected to the interrupt source. The second cell is the interrupt
> >>+ triggering protocol and may have one of four values:
> >>+ 0 - level triggered active high.
> >>+ 1 - level triggered active low
> >>+ 2 - edge triggered on the rising edge.
> >>+ 3 - edge triggered on the falling edge.
> >
> >Since you're choosing arbitrary values here anyway, it's convenient to
> >follow the lead of include/linux/irq.h and using 1->edge rising,
> >2->edge falling, 4->level high, 8->level low. In the past every irq
> >controller kind of did it's own thing, but that's not very scalable.
> >
>
> OK. I will use those still somewhat arbitrary values instead.
Indeed, they are still completely arbitrary, but at least they are the
same completely arbitrary values. :-)
g.