* [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-06 10:56 ` Michal Marek
2011-05-05 17:02 ` [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths David Daney
` (5 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
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 <ddaney@caviumnetworks.com>
---
drivers/of/Kconfig | 3 +++
drivers/of/Makefile | 2 ++
drivers/of/libfdt/Makefile | 8 ++++++++
include/linux/libfdt.h | 8 ++++++++
include/linux/libfdt_env.h | 13 +++++++++++++
5 files changed, 34 insertions(+), 0 deletions(-)
create mode 100644 drivers/of/libfdt/Makefile
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..bda11fe
--- /dev/null
+++ b/drivers/of/libfdt/Makefile
@@ -0,0 +1,8 @@
+ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
+
+obj-y = fdt.o fdt_wip.o fdt_ro.o
+
+
+$(obj)/%.o: $(src)/../../../scripts/dtc/libfdt/%.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_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
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code
2011-05-05 17:02 ` [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code David Daney
@ 2011-05-06 10:56 ` Michal Marek
2011-05-06 17:14 ` David Daney
0 siblings, 1 reply; 14+ messages in thread
From: Michal Marek @ 2011-05-06 10:56 UTC (permalink / raw)
To: David Daney
Cc: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
On 5.5.2011 19:02, David Daney wrote:
> --- /dev/null
> +++ b/drivers/of/libfdt/Makefile
> @@ -0,0 +1,8 @@
> +ccflags-y := -include linux/libfdt_env.h -I$(src)/../../../scripts/dtc/libfdt
> +
> +obj-y = fdt.o fdt_wip.o fdt_ro.o
> +
> +
> +$(obj)/%.o: $(src)/../../../scripts/dtc/libfdt/%.c FORCE
> + $(call cmd,force_checksrc)
> + $(call if_changed_rule,cc_o_c)
It's just three source files, so you could use three one-line wrappers
that #include ../../../scripts/dtc/libfdt/<file>.c instead of copying
the %.c -> %.o rule here.
Michal
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code
2011-05-06 10:56 ` Michal Marek
@ 2011-05-06 17:14 ` David Daney
0 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-06 17:14 UTC (permalink / raw)
To: Michal Marek
Cc: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
On 05/06/2011 03:56 AM, Michal Marek wrote:
> On 5.5.2011 19:02, David Daney wrote:
>> --- /dev/null
>> +++ b/drivers/of/libfdt/Makefile
>> @@ -0,0 +1,8 @@
>> +ccflags-y := -include linux/libfdt_env.h
>> -I$(src)/../../../scripts/dtc/libfdt
>> +
>> +obj-y = fdt.o fdt_wip.o fdt_ro.o
>> +
>> +
>> +$(obj)/%.o: $(src)/../../../scripts/dtc/libfdt/%.c FORCE
>> + $(call cmd,force_checksrc)
>> + $(call if_changed_rule,cc_o_c)
>
> It's just three source files, so you could use three one-line wrappers
> that #include ../../../scripts/dtc/libfdt/<file>.c instead of copying
> the %.c -> %.o rule here.
>
Good idea, that does seem cleaner.
I will adjust the patch.
David Daney
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths.
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
2011-05-05 17:02 ` [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-06 10:05 ` Sergei Shtylyov
2011-05-06 10:17 ` Sergei Shtylyov
2011-05-05 17:02 ` [RFC PATCH v3 3/6] MIPS: Octeon: Add device tree source files David Daney
` (4 subsequent siblings)
6 siblings, 2 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
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 <ddaney@caviumnetworks.com>
---
drivers/of/base.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 632ebae..1a0a83e 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -340,7 +340,10 @@ 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.
@@ -348,14 +351,50 @@ EXPORT_SYMBOL(of_get_next_child);
struct device_node *of_find_node_by_path(const char *path)
{
struct device_node *np = allnodes;
+ struct device_node *aliases = NULL;
+ char *alias = NULL;
+ char *new_path = NULL;
read_lock(&devtree_lock);
+
+ 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 = kmalloc(len + 1, GFP_KERNEL);
+ strncpy(alias, path, len);
+ alias[len] = 0;
+ path = of_get_property(aliases, alias, NULL);
+ if (!path)
+ goto out;
+ len = strlen(path) + strlen(ps) + 1;
+ new_path = kmalloc(len, GFP_KERNEL);
+ 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; 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
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths.
2011-05-05 17:02 ` [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths David Daney
@ 2011-05-06 10:05 ` Sergei Shtylyov
2011-05-19 18:54 ` Grant Likely
2011-05-06 10:17 ` Sergei Shtylyov
1 sibling, 1 reply; 14+ messages in thread
From: Sergei Shtylyov @ 2011-05-06 10:05 UTC (permalink / raw)
To: David Daney
Cc: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Hello.
On 05-05-2011 21:02, 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<ddaney@caviumnetworks.com>
> ---
> drivers/of/base.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 40 insertions(+), 1 deletions(-)
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 632ebae..1a0a83e 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
[...]
> @@ -348,14 +351,50 @@ EXPORT_SYMBOL(of_get_next_child);
> struct device_node *of_find_node_by_path(const char *path)
> {
> struct device_node *np = allnodes;
> + struct device_node *aliases = NULL;
> + char *alias = NULL;
> + char *new_path = NULL;
>
> read_lock(&devtree_lock);
> +
> + 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 = kmalloc(len + 1, GFP_KERNEL);
How about error handling?
> + strncpy(alias, path, len);
> + alias[len] = 0;
> + path = of_get_property(aliases, alias, NULL);
> + if (!path)
> + goto out;
> + len = strlen(path) + strlen(ps) + 1;
> + new_path = kmalloc(len, GFP_KERNEL);
Here too...
WBR, Sergei
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths.
2011-05-06 10:05 ` Sergei Shtylyov
@ 2011-05-19 18:54 ` Grant Likely
0 siblings, 0 replies; 14+ messages in thread
From: Grant Likely @ 2011-05-19 18:54 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: David Daney, linux-mips, ralf, devicetree-discuss, linux-kernel
On Fri, May 06, 2011 at 02:05:48PM +0400, Sergei Shtylyov wrote:
> Hello.
>
> On 05-05-2011 21:02, 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<ddaney@caviumnetworks.com>
> >---
> > drivers/of/base.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> > 1 files changed, 40 insertions(+), 1 deletions(-)
>
> >diff --git a/drivers/of/base.c b/drivers/of/base.c
> >index 632ebae..1a0a83e 100644
> >--- a/drivers/of/base.c
> >+++ b/drivers/of/base.c
> [...]
> >@@ -348,14 +351,50 @@ EXPORT_SYMBOL(of_get_next_child);
> > struct device_node *of_find_node_by_path(const char *path)
> > {
> > struct device_node *np = allnodes;
> >+ struct device_node *aliases = NULL;
> >+ char *alias = NULL;
> >+ char *new_path = NULL;
> >
> > read_lock(&devtree_lock);
> >+
> >+ 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 = kmalloc(len + 1, GFP_KERNEL);
>
> How about error handling?
Yes, please add error handling and repost.
Thanks,
g.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths.
2011-05-05 17:02 ` [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths David Daney
2011-05-06 10:05 ` Sergei Shtylyov
@ 2011-05-06 10:17 ` Sergei Shtylyov
1 sibling, 0 replies; 14+ messages in thread
From: Sergei Shtylyov @ 2011-05-06 10:17 UTC (permalink / raw)
To: David Daney
Cc: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Hello.
On 05-05-2011 21:02, 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<ddaney@caviumnetworks.com>
> ---
> drivers/of/base.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 40 insertions(+), 1 deletions(-)
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 632ebae..1a0a83e 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
[...]
> @@ -348,14 +351,50 @@ EXPORT_SYMBOL(of_get_next_child);
> struct device_node *of_find_node_by_path(const char *path)
> {
> struct device_node *np = allnodes;
> + struct device_node *aliases = NULL;
> + char *alias = NULL;
> + char *new_path = NULL;
>
> read_lock(&devtree_lock);
> +
> + 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 = kmalloc(len + 1, GFP_KERNEL);
> + strncpy(alias, path, len);
> + alias[len] = 0;
BTW, you could use kstrndup() (from mm/util.c) instead of the above 3 lines.
WBR, Sergei
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v3 3/6] MIPS: Octeon: Add device tree source files.
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
2011-05-05 17:02 ` [RFC PATCH v3 1/6] of: Allow scripts/dtc/libfdt to be used from kernel code David Daney
2011-05-05 17:02 ` [RFC PATCH v3 2/6] of: Make of_find_node_by_path() traverse /aliases for relative paths David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-05 17:02 ` [RFC PATCH v3 4/6] MIPS: Prune some target specific code out of prom.c David Daney
` (3 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
.../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 | 431 ++++++++++++++++++++
12 files changed, 822 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..8c1d3d4
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -0,0 +1,431 @@
+/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>;
+ };
+ };
+
+ interface@2 { /* DPI interface. */
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ interface@3 { /* Loop interface. */
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+ };
+
+ 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
^ permalink raw reply related [flat|nested] 14+ messages in thread* [RFC PATCH v3 4/6] MIPS: Prune some target specific code out of prom.c
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
` (2 preceding siblings ...)
2011-05-05 17:02 ` [RFC PATCH v3 3/6] MIPS: Octeon: Add device tree source files David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-05 17:02 ` [RFC PATCH v3 5/6] MIPS: Octeon: Add irq_create_of_mapping() and GPIO interrupts David Daney
` (2 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
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 <ddaney@caviumnetworks.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread* [RFC PATCH v3 5/6] MIPS: Octeon: Add irq_create_of_mapping() and GPIO interrupts.
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
` (3 preceding siblings ...)
2011-05-05 17:02 ` [RFC PATCH v3 4/6] MIPS: Prune some target specific code out of prom.c David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-05 17:02 ` [RFC PATCH v3 6/6] MIPS: Octeon: Initialize and fixup device tree David Daney
2011-05-05 17:40 ` [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree Grant Likely
6 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
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 <ddaney@caviumnetworks.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread* [RFC PATCH v3 6/6] MIPS: Octeon: Initialize and fixup device tree.
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
` (4 preceding siblings ...)
2011-05-05 17:02 ` [RFC PATCH v3 5/6] MIPS: Octeon: Add irq_create_of_mapping() and GPIO interrupts David Daney
@ 2011-05-05 17:02 ` David Daney
2011-05-05 17:40 ` [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree Grant Likely
6 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:02 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/Makefile | 2 +
arch/mips/cavium-octeon/octeon-platform.c | 295 +++++++++++++++++++++++++++++
arch/mips/cavium-octeon/setup.c | 17 ++
4 files changed, 315 insertions(+), 0 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 12b6a07..6767176 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1382,6 +1382,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..602eadf 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -9,6 +9,8 @@
# Copyright (C) 2005-2009 Cavium Networks
#
+ccflags-y := -include linux/libfdt_env.h -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 <ddaney@caviumnetworks.com>");
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..91431a6 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/of_fdt.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/initrd.h>
#endif
@@ -797,3 +798,19 @@ 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 = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ /* 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, &__dtb_octeon_3xxx_begin, dt_size);
+ octeon_prune_device_tree();
+ unflatten_device_tree();
+}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree.
2011-05-05 17:02 [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree David Daney
` (5 preceding siblings ...)
2011-05-05 17:02 ` [RFC PATCH v3 6/6] MIPS: Octeon: Initialize and fixup device tree David Daney
@ 2011-05-05 17:40 ` Grant Likely
2011-05-05 17:48 ` David Daney
6 siblings, 1 reply; 14+ messages in thread
From: Grant Likely @ 2011-05-05 17:40 UTC (permalink / raw)
To: David Daney; +Cc: linux-mips, ralf, devicetree-discuss, linux-kernel
On Thu, May 5, 2011 at 11:02 AM, David Daney <ddaney@caviumnetworks.com> wrote:
> After several weeks of fire fighting, I am back to my Octeon device
> tree patches.
>
> 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 | 15 +
> arch/mips/cavium-octeon/octeon-irq.c | 183 ++++++++-
> arch/mips/cavium-octeon/octeon-platform.c | 295 +++++++++++++
> arch/mips/cavium-octeon/octeon_3xxx.dts | 431 ++++++++++++++++++++
> arch/mips/cavium-octeon/setup.c | 17 +
> arch/mips/kernel/prom.c | 49 ---
> drivers/of/Kconfig | 3 +
> drivers/of/Makefile | 2 +
> drivers/of/base.c | 41 ++-
> drivers/of/libfdt/Makefile | 8 +
Out of curiosity, how big are the compiled libfdt object files?
> include/linux/libfdt.h | 8 +
> include/linux/libfdt_env.h | 13 +
> 23 files changed, 1393 insertions(+), 51 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 include/linux/libfdt.h
> create mode 100644 include/linux/libfdt_env.h
>
> --
> 1.7.2.3
>
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree.
2011-05-05 17:40 ` [RFC PATCH v3 0/6] MIPS: Octeon: Use Device Tree Grant Likely
@ 2011-05-05 17:48 ` David Daney
0 siblings, 0 replies; 14+ messages in thread
From: David Daney @ 2011-05-05 17:48 UTC (permalink / raw)
To: Grant Likely; +Cc: linux-mips, ralf, devicetree-discuss, linux-kernel
On 05/05/2011 10:40 AM, Grant Likely wrote:
> On Thu, May 5, 2011 at 11:02 AM, David Daney<ddaney@caviumnetworks.com> wrote:
[...]
>> drivers/of/libfdt/Makefile | 8 +
>
> Out of curiosity, how big are the compiled libfdt object files?
>
For my 64-bit mips64 kernel:
[ddaney@dd1 libfdt]$ mips64-linux-size *.o
text data bss dec hex filename
7024 0 0 7024 1b70 built-in.o
1792 0 0 1792 700 fdt.o
4328 0 0 4328 10e8 fdt_ro.o
904 0 0 904 388 fdt_wip.o
David Daney
^ permalink raw reply [flat|nested] 14+ messages in thread