Few more patches for Kumar's powerpc.git
Subsystems (5)
v2 cover Few more patches for Kumar's powerpc.git
Hello Kumar,
This is the second try...
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
PATCH v2 1/5 sysdev: implement FSL GTM support
GTM stands for General-purpose Timers Module and able to generate timer{1,2,3,4} interrupts. These timers are used by the drivers that need time precise interrupts (like for USB transactions scheduling for the Freescale USB Host controller as found in some QE and CPM chips), or these timers could be used as wakeup events from the CPU deep-sleep mode.
Things unimplemented:
1. Cascaded (32 bit) timers (1-2, 3-4).
This is straightforward to implement when needed, two timers should be marked as "requested" and configured as appropriate.
2. Super-cascaded (64 bit) timers (1-2-3-4).
This is also straightforward to implement when needed, all timers should be marked as "requested" and configured as appropriate.
--- Documentation/powerpc/booting-without-of.txt | 32 +++- arch/powerpc/Kconfig | 5 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_gtm.c | 365 ++++++++++++++++++++++++++ include/asm-powerpc/fsl_gtm.h | 108 ++++++++ 5 files changed, 510 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/sysdev/fsl_gtm.c create mode 100644 include/asm-powerpc/fsl_gtm.h
Documentation/powerpc/booting-without-of.txt +31 -1
@@ -57,7 +57,8 @@ Table of Contents n) 4xx/Axon EMAC ethernet nodes o) Xilinx IP cores p) Freescale Synchronous Serial Interface - q) USB EHCI controllers + q) USB EHCI controllers + r) Freescale General-purpose Timers Module VII - Marvell Discovery mv64[345]6x System Controller chips 1) The /system-controller node
@@ -2825,6 +2826,35 @@ platforms are moved over to use the flattened-device-tree model. big-endian; }; + r) Freescale General-purpose Timers Module + + Required properties: + - compatible : should be "fsl,gtm" ("fsl,qe-gtm" in addition for QE + GTMs or "fsl,cpm2-gtm" for CPM2 GTMs). + - reg : should contain gtm registers location and length (0x40). + - interrupts : should contain four interrupts. + - interrupt-parent : interrupt source phandle. + - clock-frequency : specifies the frequency driving the timer. + + Example: + + timer@500 { + compatible = "fsl,gtm"; + reg = <0x500 0x40>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + timer@440 { + compatible = "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; VII - Marvell Discovery mv64[345]6x System Controller chips ===========================================================
arch/powerpc/Kconfig +5 -0
@@ -525,6 +525,11 @@ config FSL_LBC help Freescale Localbus support +config FSL_GTM + bool + help + Freescale General-purpose Timers support + # Yes MCA RS/6000s exist but Linux-PPC does not currently support any config MCA bool
arch/powerpc/sysdev/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o +obj-$(CONFIG_FSL_GTM) += fsl_gtm.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
arch/powerpc/sysdev/fsl_gtm.c new file +365 -0
365 lines not on this page · raw message
include/asm-powerpc/fsl_gtm.h new file +108 -0
108 lines not on this page · raw message
Signature · 1 line
1.5.5
Re: [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support
2008/4/18 Anton Vorontsov <[email protected]>:
Quoted 6 lines
GTM stands for General-purpose Timers Module and able to generate
timer{1,2,3,4} interrupts. These timers are used by the drivers that need time precise interrupts (like for USB transactions scheduling for the Freescale USB Host controller as found in some QE and CPM chips), or these timers could be used as wakeup events from the CPU deep-sleep mode.
Comments below.
Quoted 1 line
diff --git
a/Documentation/powerpc/booting-without-of.txtb/Documentatio=
n/powerpc/booting-without-of.txt
Quoted 11 lines
index 4cc7800..827b630 100644
---a/Documentation/powerpc/booting-without-of.txt+++b/Documentation/powerpc/booting-without-of.txt@@ -57,7 +57,8 @@ Table of Contents
n) 4xx/Axon EMAC ethernet nodes
o) Xilinx IP cores
p) Freescale Synchronous Serial Interface
- q) USB EHCI controllers
+ q) USB EHCI controllers
+ r) Freescale General-purpose Timers Module
Quoted 3 lines
VII - Marvell Discovery mv64[345]6x System Controller chips
1) The /system-controller node
@@ -2825,6 +2826,35 @@ platforms are moved over to use the flattened-dev=
ice-tree model.
Quoted 7 lines
big-endian; };+ r) Freescale General-purpose Timers Module
+
+ Required properties:
+ - compatible : should be "fsl,gtm" ("fsl,qe-gtm" in addition for =
QE
Quoted 1 line
+ GTMs or "fsl,cpm2-gtm" for CPM2 GTMs).
I don't think this is specific enough. It is a very real possibility for Freescale to produce another part with a "general purpose timers module" that isn't register level compatible (and fsl,i2c is an example of what not to do). The compatible string should include the exact chip version. Newer parts can also claim compatibility with older ones.
Defining a 'generic' compatible value is also known as "making stuff up". = :-)
Quoted 23 lines
+ - reg : should contain gtm registers location and length (0x40).
+ - interrupts : should contain four interrupts.
+ - interrupt-parent : interrupt source phandle.
+ - clock-frequency : specifies the frequency driving the timer.
+
+ Example:
+
+ timer@500 {
+ compatible =3D "fsl,gtm";
+ reg =3D <0x500 0x40>;
+ interrupts =3D <90 8 78 8 84 8 72 8>;
+ interrupt-parent =3D <&ipic>;
+ /* filled by u-boot */
+ clock-frequency =3D <0>;
+ };
+
+ timer@440 {
+ compatible =3D "fsl,qe-gtm", "fsl,gtm";
+ reg =3D <0x440 0x40>;
+ interrupts =3D <12 13 14 15>;
+ interrupt-parent =3D <&qeic>;
+ /* filled by u-boot */
+ clock-frequency =3D <0>;Quoted 4 lines
+ };
VII - Marvell Discovery mv64[345]6x System Controller chips =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Quoted 21 lines
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7f2f126..ad874e4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -525,6 +525,11 @@ configFSL_LBC
help
Freescale Localbus support+config
FSL_GTM
+ bool
+ help
+ Freescale General-purpose Timers support
+
# Yes MCA RS/6000s exist but Linux-PPC does not currently support any config MCA
bool
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6d386d0..9d3ddd2 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMIO_NVRAM) +=3D mmio_nvram.o
Quoted 8 lines
obj-$(CONFIG_FSL_SOC) +=3D fsl_soc.o obj-$(CONFIG_FSL_PCI) +=3D fsl_pci.o obj-$(CONFIG_FSL_LBC) +=3D fsl_lbc.o +obj-$(CONFIG_FSL_GTM) +=3D fsl_gtm.o obj-$(CONFIG_RAPIDIO) +=3D fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) +=3D tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) +=3D qe_lib/diff --git
a/arch/powerpc/sysdev/fsl_gtm.cb/arch/powerpc/sysdev/fsl_gtm=
.c
Quoted 7 lines
new file mode 100644
index 0000000..d29df56
---/dev/null
+++b/arch/powerpc/sysdev/fsl_gtm.c
@@ -0,0 +1,365 @@
+/*
+ * Freescale General-purpose Timers Module
Quoted 8 lines
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <[email protected]>
+ * Jerry Huang <[email protected]>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modif=
y it
Quoted 1 line
+ * under the terms of the GNU General Public License as published by=
the
Quoted 1 line
+ * Free Software Foundation; either version 2 of the License, or (at =
your
Quoted 6 lines
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/io.h>
Quoted 8 lines
+#include <
linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <asm/fsl_gtm.h>
+
+/**
+ *gtm_get_timer- request GTM timer to use it with the rest of GTM API
+ * @width: timer width (only 16 bits wide timers implemented so far=
)
Quoted 29 lines
+ *
+ * This function reserves GTM timer for later use. It returnsgtm_timer
+ * structure to use with the rest of GTM API, you should usetimer->irq
+ * to manage timer interrupt.
+ */
+structgtm_timer*gtm_get_timer(int width)
+{+ struct device_node *np; + struct gtm *gtm =3D NULL; + int i; + + if (width !=3D 16) + return ERR_PTR(-ENOSYS); + + for_each_compatible_node(np, NULL, "fsl,gtm") { + if (!np->data) { + WARN_ON(1); + continue; + } + gtm =3D np->data; + + spin_lock_irq(>m->lock); + + for (i =3D 0; i < ARRAY_SIZE(gtm->timers); i++) { + if (!gtm->timers[i].requested) { + gtm->timers[i].requested =3D true; + spin_unlock_irq(>m->lock); + of_node_put(np); + return >m->timers[i];
Quoted 11 lines
+ }
+ }
+
+spin_unlock_irq(>m->lock);
+ }
+
+ if (gtm)
+ returnERR_PTR(-EBUSY);
+ returnERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(gtm_get_timer);
This isn't a very efficient construct. You've already located all of the relevant nodes in the gtm_init() function. Searching the device tree is not efficient, so it should be avoided and only be performed once. Can you move the extraction of data from the tree to gtm_init() and only parse the drivers list of timers in this function?
Quoted 6 lines
+
+/**
+ *gtm_get_specific_timer- request specific GTM timer+ * @gtm: specific GTM, pass here GTM's device_node->data + * @timer: specific timer number, Timer1 is 0. + * @width: timer width (only 16 bits wide timers implemented so far=
)
Quoted 6 lines
+ *
+ * This function reserves GTM timer for later use. It returnsgtm_timer
+ * structure to use with the rest of GTM API, you should usetimer->irq
+ * to manage timer interrupt.
+ */
+structgtm_timer*gtm_get_specific_timer(struct gtm *gtm, int timer, in=
t width)
Quoted 15 lines
+{
+ structgtm_timer*ret =3DERR_PTR(-EBUSY);
+
+ if (width !=3D 16)
+ returnERR_PTR(-ENOSYS);
+
+spin_lock_irq(>m->lock);
+
+ if (gtm->timers[timer].requested)
+ goto out;
+
+ ret =3D >m->timers[timer];
+ret->requested=3D true;
+
+out:
Quoted 8 lines
+
spin_unlock_irq(>m->lock);
+ return ret;
+}
+EXPORT_SYMBOL(gtm_get_specific_timer);
+
+/**
+ *gtm_put_timer- release GTM timer
+ * @width: timer width (only 16 bits wide timers implemented so far=
)
Quoted 7 lines
+ *
+ * This function releases GTM timer so others may request it.
+ */
+voidgtm_put_timer(struct gtm_timer *tmr)
+{
+spin_lock_irq(&tmr->gtm->lock);
+
Quoted 8 lines
+
tmr->requested=3D false;
+
+spin_unlock_irq(&tmr->gtm->lock);
+}
+EXPORT_SYMBOL(gtm_put_timer);
+
+/*
+ * This is back-end for the exported functions, it's used to reset sing=
le
Quoted 13 lines
+ * timer in reference mode.
+ */
+static int gtm_reset_ref_timer16(structgtm_timer*tmr, int frequency,
+ intreference_value, boolfree_run)
+{+ struct gtm *gtm =3D tmr->gtm; + int num =3D tmr - >m->timers[0]; + unsigned int prescaler; + u8 iclk =3D GTMDR_ICLK_ICLK; + u8 psr; + u8 sps; + unsigned long flags; + int max_prescaler =3D 256 * 256 * 16;
Quoted 8 lines
+
+ /* CPM2 doesn't have primary prescaler */
+ if (!tmr->gtpsr)
+max_prescaler/=3D 256;
+
+ prescaler =3Dgtm->clock/ frequency;
+ /*
+ * We have two 8 bit prescalers -- primary and secondary (psr, s=
ps),
Quoted 2 lines
+ * plus "slow go" mode (clk / 16). So, total prescale value is
+ * 16 * (psr + 1) * (sps + 1). Though, for CPM2 GTMs we losing p=
sr.
Quoted 13 lines
+ */
+ if (prescaler >max_prescaler)
+ return-EINVAL;
+
+ if (prescaler >max_prescaler/ 16) {
+ iclk =3DGTMDR_ICLK_SLGO;
+ prescaler /=3D 16;
+ }
+
+ if (prescaler <=3D 256) {
+ psr =3D 0;
+ sps =3D prescaler - 1;
+ } else {
Quoted 8 lines
+ psr =3D 256 - 1;
+ sps =3D prescaler / 256 - 1;
+ }
+
+spin_lock_irqsave(>m->lock, flags);
+
+ /*
+ * Properly reset timers: stop, reset, set up prescalers, refere=
nce
Quoted 14 lines
+ * value and clear event register.
+ */
+ clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) |GTCFR_RST(num)),
+GTCFR_STP(num)|GTCFR_RST(num));
+
+setbits8(tmr->gtcfr, GTCFR_STP(num));
+
+ if (tmr->gtpsr)
+out_be16(tmr->gtpsr, psr);
+ clrsetbits_be16(tmr->gtmdr,0xFFFF, iclk |GTMDR_SPS(sps)|
+GTMDR_ORI| (free_run?GTMDR_FRR: 0));+ out_be16(tmr->gtcnr, 0); + out_be16(tmr->gtrfr, reference_value); + out_be16(tmr->gtevr, 0xFFFF);
Quoted 11 lines
+
+ /* Let it be. */
+clrbits8(tmr->gtcfr, GTCFR_STP(num));
+
+spin_unlock_irqrestore(>m->lock, flags);
+
+ return 0;
+}
+/**
+ *gtm_reset_timer16- reset 16 bit timer with arbitrary precision
+ * @tmr: pointer to thegtm_timerstructure obtained from gtm_get=
_timer
Quoted 5 lines
+ * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free.+ *
+ * This function (re)sets the GTM timer so that it counts up to the req=
uested
Quoted 1 line
+ * interval value, and fires the interrupt when the value is reached. T=
his
Quoted 1 line
+ * function will reduce the precision of the timer as needed in order f=
or the
Quoted 3 lines
+ * requested timeout to fit in a 16-bit register.
+ */
+int gtm_reset_timer16(structgtm_timer*tmr, unsigned long usec, bool r=
eload)
Quoted 2 lines
+{
+ /* quite obvious, frequency which is enough for =B5Sec precision=
*/
Quoted 11 lines
+ int freq =3D 1000000;
+ unsigned int bit;
+
+ bit =3Dfls_long(usec);
+ if (bit > 15) {
+ freq >>=3D bit - 15;
+ usec >>=3D bit - 15;
+ }
+
+ if (!freq)
+ return-EINVAL;
Quoted 8 lines
+
+ returngtm_reset_ref_timer16(tmr, freq, usec, reload);
+}
+EXPORT_SYMBOL(gtm_reset_timer16);
+
+/**
+ *gtm_reset_utimer16- reset 16 bits timer
+ * @tmr: pointer to thegtm_timerstructure obtained from gtm_get=
_timer
Quoted 5 lines
+ * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free.+ *
+ * This function (re)sets GTM timer so that it counts up to the request=
ed
Quoted 1 line
+ * interval value, and fires the interrupt when the value is reached. I=
f reload
Quoted 1 line
+ * flag was set, timer will also reset itself upon reference value, oth=
erwise
Quoted 5 lines
+ * it continues to increment.
+ */
+intgtm_reset_utimer16(struct gtm_timer *tmr, u16 usec, bool reload)+{
+ /* quite obvious, frequency which is enough for =B5Sec precision=
*/
Quoted 4 lines
+ const int freq =3D 1000000;
+
+ /*
+ * We can lower the frequency (and probably power consumption) b=
y
Quoted 1 line
+ * dividing both frequency and usec by 2 until there is no remai=
nder.
Quoted 1 line
+ * But we won't bother with this unless savings are measured, so=
just
Quoted 10 lines
+ * run the timer as is.
+ */
+
+ returngtm_reset_ref_timer16(tmr, freq, usec, reload);
+}
+EXPORT_SYMBOL(gtm_reset_utimer16);
+
+/**
+ *gtm_stop_timer16- stop single timer
+ * @tmr: pointer to thegtm_timerstructure obtained from gtm_get=
_timer
Quoted 8 lines
+ *
+ * This function simply stops the GTM timer.
+ */
+voidgtm_stop_timer16(struct gtm_timer *tmr)
+{+ struct gtm *gtm =3D tmr->gtm; + int num =3D tmr - >m->timers[0]; + unsigned long flags;
Quoted 13 lines
+
+spin_lock_irqsave(>m->lock, flags);
+
+setbits8(tmr->gtcfr, GTCFR_STP(num));
+out_be16(tmr->gtevr, 0xFFFF);
+
+spin_unlock_irqrestore(>m->lock, flags);
+}
+EXPORT_SYMBOL(gtm_stop_timer16);
+
+static void__initgtm_set_shortcuts(structdevice_node*np,
+ structgtm_timer*timers,
+ structgtm_timers_regs__iomem*reg=
s)
Quoted 3 lines
+{
+ /*
+ * Yeah, I don't like this either, but timers' registers a bit m=
essed,
Quoted 1 line
+ * so we have to provide shortcuts to write timer independent co=
de.
Quoted 1 line
+ * Alternative option is to create gt*() accessors, but that wil=
l be
Quoted 44 lines
+ * even uglier and cryptic.
+ */+ timers[0].gtcfr =3D ®s->gtcfr1; + timers[0].gtmdr =3D ®s->gtmdr1; + timers[0].gtcnr =3D ®s->gtcnr1; + timers[0].gtrfr =3D ®s->gtrfr1; + timers[0].gtevr =3D ®s->gtevr1; + + timers[1].gtcfr =3D ®s->gtcfr1; + timers[1].gtmdr =3D ®s->gtmdr2; + timers[1].gtcnr =3D ®s->gtcnr2; + timers[1].gtrfr =3D ®s->gtrfr2; + timers[1].gtevr =3D ®s->gtevr2; + + timers[2].gtcfr =3D ®s->gtcfr2; + timers[2].gtmdr =3D ®s->gtmdr3; + timers[2].gtcnr =3D ®s->gtcnr3; + timers[2].gtrfr =3D ®s->gtrfr3; + timers[2].gtevr =3D ®s->gtevr3; + + timers[3].gtcfr =3D ®s->gtcfr2; + timers[3].gtmdr =3D ®s->gtmdr4; + timers[3].gtcnr =3D ®s->gtcnr4; + timers[3].gtrfr =3D ®s->gtrfr4; + timers[3].gtevr =3D ®s->gtevr4; + + /* CPM2 doesn't have primary prescaler */ + if (!of_device_is_compatible(np, "fsl,cpm2-gtm")) { + timers[0].gtpsr =3D ®s->gtpsr1; + timers[1].gtpsr =3D ®s->gtpsr2; + timers[2].gtpsr =3D ®s->gtpsr3; + timers[3].gtpsr =3D ®s->gtpsr4; + } +} + +static int __init gtm_init(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,gtm") { + int i; + struct gtm *gtm; + const u32 *clock; + int size;
Quoted 13 lines
+
+ gtm =3Dkzalloc(sizeof(*gtm), GFP_KERNEL);
+ if (!gtm) {
+ pr_err("%s: unable to allocate memory\n",
+np->full_name);
+ continue;
+ }
+
+spin_lock_init(>m->lock);
+
+ clock =3Dof_get_property(np, "clock-frequency", &size);
+ if (!clock || size !=3Dsizeof(*clock)) {
+ pr_err("%s: no clock-frequency\n", np->full_name=
);
Quoted 11 lines
+ goto err;
+ }
+gtm->clock=3D *clock;
+
+ for (i =3D 0; i <ARRAY_SIZE(gtm->timers); i++) {
+ int ret;
+ struct resource irq;
+
+ ret =3Dof_irq_to_resource(np, i, &irq);
+ if (ret =3D=3DNO_IRQ) {
+ pr_err("%s: not enough interrupts specif=
ied\n",
Quoted 19 lines
+
np->full_name);
+ goto err;+ } + gtm->timers[i].irq =3D irq.start; + gtm->timers[i].gtm =3D gtm; + } + + gtm->regs =3D of_iomap(np, 0); + if (!gtm->regs) { + pr_err("%s: unable to iomap registers\n", + np->full_name); + goto err; + } + + gtm_set_shortcuts(np, gtm->timers, gtm->regs); + + /* We don't want to lose the node and its ->data */ + of_node_get(np); + np->data =3D gtm;
Quoted 9 lines
+
+ continue;
+err:
+ kfree(gtm);
+ }
+ return 0;
+}
+arch_initcall(gtm_init);
diff --gita/include/asm-powerpc/fsl_gtm.hb/include/asm-powerpc/fsl_gtm=
.h
Quoted 7 lines
new file mode 100644
index 0000000..3eafb21
---/dev/null
+++b/include/asm-powerpc/fsl_gtm.h
@@ -0,0 +1,108 @@
+/*
+ * Freescale General-purpose Timers Module
Quoted 8 lines
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <[email protected]>
+ * Jerry Huang <[email protected]>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modif=
y it
Quoted 1 line
+ * under the terms of the GNU General Public License as published by=
the
Quoted 1 line
+ * Free Software Foundation; either version 2 of the License, or (at =
your
Quoted 20 lines
+ * option) any later version.
+ */
+
+#ifndef__ASM_FSL_GTM_H
+#define__ASM_FSL_GTM_H
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#defineGTCFR_STP(x)((x) & 1 ? 1 << 5 : 1 << 1)
+#defineGTCFR_RST(x)((x) & 1 ? 1 << 4 : 1 << 0)
++#define GTMDR_ICLK_MASK (3 << 1) +#define GTMDR_ICLK_ICAS (0 << 1) +#define GTMDR_ICLK_ICLK (1 << 1) +#define GTMDR_ICLK_SLGO (2 << 1) +#define GTMDR_FRR (1 << 3) +#define GTMDR_ORI (1 << 4) +#define GTMDR_SPS(x) ((x) << 8)
Quoted 3 lines
+
+structgtm_timers_regs{
+ u8 gtcfr1; /* Timer 1, Timer 2 global config regist=
er */
Quoted 2 lines
+ u8 res0[0x3]; + u8 gtcfr2; /* Timer 3, timer 4 global config regist=
er */
Quoted 46 lines
+ u8 res1[0xB];
+ __be16 gtmdr1; /* Timer 1 mode register */
+ __be16 gtmdr2; /* Timer 2 mode register */
+ __be16 gtrfr1; /* Timer 1 reference register */
+ __be16 gtrfr2; /* Timer 2 reference register */
+ __be16 gtcpr1; /* Timer 1 capture register */
+ __be16 gtcpr2; /* Timer 2 capture register */
+ __be16 gtcnr1; /* Timer 1 counter */
+ __be16 gtcnr2; /* Timer 2 counter */
+ __be16 gtmdr3; /* Timer 3 mode register */
+ __be16 gtmdr4; /* Timer 4 mode register */
+ __be16 gtrfr3; /* Timer 3 reference register */
+ __be16 gtrfr4; /* Timer 4 reference register */
+ __be16 gtcpr3; /* Timer 3 capture register */
+ __be16 gtcpr4; /* Timer 4 capture register */
+ __be16 gtcnr3; /* Timer 3 counter */
+ __be16 gtcnr4; /* Timer 4 counter */
+ __be16 gtevr1; /* Timer 1 event register */
+ __be16 gtevr2; /* Timer 2 event register */
+ __be16 gtevr3; /* Timer 3 event register */
+ __be16 gtevr4; /* Timer 4 event register */
+ __be16 gtpsr1; /* Timer 1 prescale register */
+ __be16 gtpsr2; /* Timer 2 prescale register */
+ __be16 gtpsr3; /* Timer 3 prescale register */
+ __be16 gtpsr4; /* Timer 4 prescale register */
+ u8 res2[0x40];
+} __attribute__ ((packed));
+
+struct gtm_timer {
+ unsigned int irq;
+
+ struct gtm *gtm;
+ bool requested;
+ u8 __iomem *gtcfr;
+ __be16 __iomem *gtmdr;
+ __be16 __iomem *gtpsr;
+ __be16 __iomem *gtcnr;
+ __be16 __iomem *gtrfr;
+ __be16 __iomem *gtevr;
+};
+
+struct gtm {
+ unsigned int clock;
+ struct gtm_timers_regs __iomem *regs;
+ struct gtm_timer timers[4];
+ spinlock_t lock;Quoted 1 line
+};
Consider moving the register definitions and structures inside the .c file. This is all anonymous data as far as the caller is concerned. If the structures are only access inside the driver then you gain yourself a bit of safety by moving them.
Quoted 3 lines
+
+extern structgtm_timer*gtm_get_timer(int width);
+extern structgtm_timer*gtm_get_specific_timer(struct gtm *gtm, int ti=
mer,
Quoted 5 lines
+ int width);
+extern voidgtm_put_timer(struct gtm_timer *tmr);
+extern int gtm_reset_timer16(structgtm_timer*tmr, unsigned long usec,
+ bool reload);
+extern int gtm_reset_utimer16(structgtm_timer*tmr, u16 usec, bool rel=
oad);
Quoted 5 lines
+extern void
gtm_stop_timer16(struct gtm_timer *tmr);
+
+/**
+ *gtm_ack_timer16- acknowledge timer event (free-run timers only)
+ * @tmr: pointer to thegtm_timerstructure obtained from gtm_get=
_timer
Quoted 3 lines
+ * @events: events mask to ack
+ *
+ * Thus function used to acknowledge timer interrupt event, use it insi=
de the
Quoted 6 lines
+ * interrupt handler.
+ */
+static inline voidgtm_ack_timer16(struct gtm_timer *tmr, u16 events)+{
+out_be16(tmr->gtevr, events);
+}
Drop 'inline' and expect gcc to do the right thing.
Quoted 9 lines
+
+#endif /*__ASM_FSL_GTM_H*/
--
1.5.5_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
Re: [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support
Quoted 34 lines · Grant Likely
2008/4/18 Anton Vorontsov <[email protected]>:
Quoted 6 lines
GTM stands for General-purpose Timers Module and able to generate
timer{1,2,3,4} interrupts. These timers are used by the drivers that need time precise interrupts (like for USB transactions scheduling for the Freescale USB Host controller as found in some QE and CPM chips), or these timers could be used as wakeup events from the CPU deep-sleep mode.Comments below.
Quoted 15 lines
diff --git
a/Documentation/powerpc/booting-without-of.txtb/Documentation/powerpc/booting-without-of.txtindex 4cc7800..827b630 100644
---a/Documentation/powerpc/booting-without-of.txt
+++b/Documentation/powerpc/booting-without-of.txt
@@ -57,7 +57,8 @@ Table of Contents
n) 4xx/Axon EMAC ethernet nodes
o) Xilinx IP cores
p) Freescale Synchronous Serial Interface
- q) USB EHCI controllers
+ q) USB EHCI controllers
+ r) Freescale General-purpose Timers ModuleVII - Marvell Discovery mv64[345]6x System Controller chips
1) The /system-controller node
@@ -2825,6 +2826,35 @@ platforms are moved over to use the flattened-device-tree model.Quoted 8 lines
big-endian; };+ r) Freescale General-purpose Timers Module
+
+ Required properties:
+ - compatible : should be "fsl,gtm" ("fsl,qe-gtm" in addition for QE
+ GTMs or "fsl,cpm2-gtm" for CPM2 GTMs).
Quoted 6 lines
I don't think this is specific enough. It is a very real possibility for Freescale to produce another part with a "general purpose timers module" that isn't register level compatible (and fsl,i2c is an example of what not to do). The compatible string should include the exact chip version. Newer parts can also claim compatibility with older ones.
Ok, I'll expand this to fsl,<cpu-specific>-gtm and fsl,<cpu-specific>-{qe,cpm2}-gtm.
Quoted 130 lines
Defining a 'generic' compatible value is also known as "making stuff up". :-)
Quoted 116 lines
+ - reg : should contain gtm registers location and length (0x40). + - interrupts : should contain four interrupts. + - interrupt-parent : interrupt source phandle. + - clock-frequency : specifies the frequency driving the timer. + + Example: + + timer@500 { + compatible = "fsl,gtm"; + reg = <0x500 0x40>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + timer@440 { + compatible = "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>;+ };
VII - Marvell Discovery mv64[345]6x System Controller chips
===========================================================
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7f2f126..ad874e4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -525,6 +525,11 @@ configFSL_LBC
help
Freescale Localbus support+config
FSL_GTM
+ bool
+ help
+ Freescale General-purpose Timers support
+
# Yes MCA RS/6000s exist but Linux-PPC does not currently support any config MCA
bool
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6d386d0..9d3ddd2 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.oobj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o +obj-$(CONFIG_FSL_GTM) += fsl_gtm.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c new file mode 100644 index 0000000..d29df56 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -0,0 +1,365 @@ +/* + * Freescale General-purpose Timers Module + * + * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Shlomi Gridish <[email protected]> + * Jerry Huang <[email protected]> + * Copyright (c) MontaVista Software, Inc. 2008. + * Anton Vorontsov <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/spinlock.h> +#include <linux/bitops.h> +#include <asm/fsl_gtm.h> + +/** + * gtm_get_timer - request GTM timer to use it with the rest of GTM API + * @width: timer width (only 16 bits wide timers implemented so far) + * + * This function reserves GTM timer for later use. It returns gtm_timer + * structure to use with the rest of GTM API, you should use timer->irq + * to manage timer interrupt. + */ +struct gtm_timer *gtm_get_timer(int width) +{ + struct device_node *np; + struct gtm *gtm = NULL; + int i; + + if (width != 16) + return ERR_PTR(-ENOSYS); + + for_each_compatible_node(np, NULL, "fsl,gtm") { + if (!np->data) { + WARN_ON(1); + continue; + } + gtm = np->data; + + spin_lock_irq(>m->lock); + + for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) { + if (!gtm->timers[i].requested) { + gtm->timers[i].requested = true; + spin_unlock_irq(>m->lock); + of_node_put(np); + return >m->timers[i];Quoted 11 lines
+ }
+ }
+
+spin_unlock_irq(>m->lock);
+ }
+
+ if (gtm)
+ returnERR_PTR(-EBUSY);
+ returnERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(gtm_get_timer);
Quoted 5 lines
This isn't a very efficient construct. You've already located all of the relevant nodes in the
gtm_init()function. Searching the device tree is not efficient, so it should be avoided and only be performed once. Can you move the extraction of data from the tree togtm_init()and only parse the drivers list of timers in this function?
Well, yes. I can create a list, and place all the GTMs in there.
Quoted 390 lines
Quoted 388 lines
+
+/**
+ *gtm_get_specific_timer- request specific GTM timer+ * @gtm: specific GTM, pass here GTM's device_node->data + * @timer: specific timer number, Timer1 is 0. + * @width: timer width (only 16 bits wide timers implemented so far) + * + * This function reserves GTM timer for later use. It returns gtm_timer + * structure to use with the rest of GTM API, you should use timer->irq + * to manage timer interrupt. + */ +struct gtm_timer *gtm_get_specific_timer(struct gtm *gtm, int timer, int width) +{ + struct gtm_timer *ret = ERR_PTR(-EBUSY); + + if (width != 16) + return ERR_PTR(-ENOSYS); + + spin_lock_irq(>m->lock); + + if (gtm->timers[timer].requested) + goto out; + + ret = >m->timers[timer]; + ret->requested = true; + +out: + spin_unlock_irq(>m->lock); + return ret; +} +EXPORT_SYMBOL(gtm_get_specific_timer); + +/** + * gtm_put_timer - release GTM timer + * @width: timer width (only 16 bits wide timers implemented so far) + * + * This function releases GTM timer so others may request it. + */ +void gtm_put_timer(struct gtm_timer *tmr) +{ + spin_lock_irq(&tmr->gtm->lock); + + tmr->requested = false; + + spin_unlock_irq(&tmr->gtm->lock); +} +EXPORT_SYMBOL(gtm_put_timer); + +/* + * This is back-end for the exported functions, it's used to reset single + * timer in reference mode. + */ +static int gtm_reset_ref_timer16(struct gtm_timer *tmr, int frequency, + int reference_value, bool free_run) +{ + struct gtm *gtm = tmr->gtm; + int num = tmr - >m->timers[0]; + unsigned int prescaler; + u8 iclk = GTMDR_ICLK_ICLK; + u8 psr; + u8 sps; + unsigned long flags; + int max_prescaler = 256 * 256 * 16; + + /* CPM2 doesn't have primary prescaler */ + if (!tmr->gtpsr) + max_prescaler /= 256; + + prescaler = gtm->clock / frequency; + /* + * We have two 8 bit prescalers -- primary and secondary (psr, sps), + * plus "slow go" mode (clk / 16). So, total prescale value is + * 16 * (psr + 1) * (sps + 1). Though, for CPM2 GTMs we losing psr. + */ + if (prescaler > max_prescaler) + return -EINVAL; + + if (prescaler > max_prescaler / 16) { + iclk = GTMDR_ICLK_SLGO; + prescaler /= 16; + } + + if (prescaler <= 256) { + psr = 0; + sps = prescaler - 1; + } else { + psr = 256 - 1; + sps = prescaler / 256 - 1; + } + + spin_lock_irqsave(>m->lock, flags); + + /* + * Properly reset timers: stop, reset, set up prescalers, reference + * value and clear event register. + */ + clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)), + GTCFR_STP(num) | GTCFR_RST(num)); + + setbits8(tmr->gtcfr, GTCFR_STP(num)); + + if (tmr->gtpsr) + out_be16(tmr->gtpsr, psr); + clrsetbits_be16(tmr->gtmdr, 0xFFFF, iclk | GTMDR_SPS(sps) | + GTMDR_ORI | (free_run ? GTMDR_FRR : 0)); + out_be16(tmr->gtcnr, 0); + out_be16(tmr->gtrfr, reference_value); + out_be16(tmr->gtevr, 0xFFFF); + + /* Let it be. */ + clrbits8(tmr->gtcfr, GTCFR_STP(num)); + + spin_unlock_irqrestore(>m->lock, flags); + + return 0; +} +/** + * gtm_reset_timer16 - reset 16 bit timer with arbitrary precision + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free. + * + * This function (re)sets the GTM timer so that it counts up to the requested + * interval value, and fires the interrupt when the value is reached. This + * function will reduce the precision of the timer as needed in order for the + * requested timeout to fit in a 16-bit register. + */ +int gtm_reset_timer16(struct gtm_timer *tmr, unsigned long usec, bool reload) +{ + /* quite obvious, frequency which is enough for µSec precision */ + int freq = 1000000; + unsigned int bit; + + bit = fls_long(usec); + if (bit > 15) { + freq >>= bit - 15; + usec >>= bit - 15; + } + + if (!freq) + return -EINVAL; + + return gtm_reset_ref_timer16(tmr, freq, usec, reload); +} +EXPORT_SYMBOL(gtm_reset_timer16); + +/** + * gtm_reset_utimer16 - reset 16 bits timer + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free. + * + * This function (re)sets GTM timer so that it counts up to the requested + * interval value, and fires the interrupt when the value is reached. If reload + * flag was set, timer will also reset itself upon reference value, otherwise + * it continues to increment. + */ +int gtm_reset_utimer16(struct gtm_timer *tmr, u16 usec, bool reload) +{ + /* quite obvious, frequency which is enough for µSec precision */ + const int freq = 1000000; + + /* + * We can lower the frequency (and probably power consumption) by + * dividing both frequency and usec by 2 until there is no remainder. + * But we won't bother with this unless savings are measured, so just + * run the timer as is. + */ + + return gtm_reset_ref_timer16(tmr, freq, usec, reload); +} +EXPORT_SYMBOL(gtm_reset_utimer16); + +/** + * gtm_stop_timer16 - stop single timer + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * + * This function simply stops the GTM timer. + */ +void gtm_stop_timer16(struct gtm_timer *tmr) +{ + struct gtm *gtm = tmr->gtm; + int num = tmr - >m->timers[0]; + unsigned long flags; + + spin_lock_irqsave(>m->lock, flags); + + setbits8(tmr->gtcfr, GTCFR_STP(num)); + out_be16(tmr->gtevr, 0xFFFF); + + spin_unlock_irqrestore(>m->lock, flags); +} +EXPORT_SYMBOL(gtm_stop_timer16); + +static void __init gtm_set_shortcuts(struct device_node *np, + struct gtm_timer *timers, + struct gtm_timers_regs __iomem *regs) +{ + /* + * Yeah, I don't like this either, but timers' registers a bit messed, + * so we have to provide shortcuts to write timer independent code. + * Alternative option is to create gt*() accessors, but that will be + * even uglier and cryptic. + */ + timers[0].gtcfr = ®s->gtcfr1; + timers[0].gtmdr = ®s->gtmdr1; + timers[0].gtcnr = ®s->gtcnr1; + timers[0].gtrfr = ®s->gtrfr1; + timers[0].gtevr = ®s->gtevr1; + + timers[1].gtcfr = ®s->gtcfr1; + timers[1].gtmdr = ®s->gtmdr2; + timers[1].gtcnr = ®s->gtcnr2; + timers[1].gtrfr = ®s->gtrfr2; + timers[1].gtevr = ®s->gtevr2; + + timers[2].gtcfr = ®s->gtcfr2; + timers[2].gtmdr = ®s->gtmdr3; + timers[2].gtcnr = ®s->gtcnr3; + timers[2].gtrfr = ®s->gtrfr3; + timers[2].gtevr = ®s->gtevr3; + + timers[3].gtcfr = ®s->gtcfr2; + timers[3].gtmdr = ®s->gtmdr4; + timers[3].gtcnr = ®s->gtcnr4; + timers[3].gtrfr = ®s->gtrfr4; + timers[3].gtevr = ®s->gtevr4; + + /* CPM2 doesn't have primary prescaler */ + if (!of_device_is_compatible(np, "fsl,cpm2-gtm")) { + timers[0].gtpsr = ®s->gtpsr1; + timers[1].gtpsr = ®s->gtpsr2; + timers[2].gtpsr = ®s->gtpsr3; + timers[3].gtpsr = ®s->gtpsr4; + } +} + +static int __init gtm_init(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,gtm") { + int i; + struct gtm *gtm; + const u32 *clock; + int size; + + gtm = kzalloc(sizeof(*gtm), GFP_KERNEL); + if (!gtm) { + pr_err("%s: unable to allocate memory\n", + np->full_name); + continue; + } + + spin_lock_init(>m->lock); + + clock = of_get_property(np, "clock-frequency", &size); + if (!clock || size != sizeof(*clock)) { + pr_err("%s: no clock-frequency\n", np->full_name); + goto err; + } + gtm->clock = *clock; + + for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) { + int ret; + struct resource irq; + + ret = of_irq_to_resource(np, i, &irq); + if (ret == NO_IRQ) { + pr_err("%s: not enough interrupts specified\n", + np->full_name); + goto err; + } + gtm->timers[i].irq = irq.start; + gtm->timers[i].gtm = gtm; + } + + gtm->regs = of_iomap(np, 0); + if (!gtm->regs) { + pr_err("%s: unable to iomap registers\n", + np->full_name); + goto err; + } + + gtm_set_shortcuts(np, gtm->timers, gtm->regs); + + /* We don't want to lose the node and its ->data */ + of_node_get(np); + np->data = gtm; + + continue; +err: + kfree(gtm); + } + return 0; +} +arch_initcall(gtm_init); diff --git a/include/asm-powerpc/fsl_gtm.h b/include/asm-powerpc/fsl_gtm.h new file mode 100644 index 0000000..3eafb21 --- /dev/null +++ b/include/asm-powerpc/fsl_gtm.h @@ -0,0 +1,108 @@ +/* + * Freescale General-purpose Timers Module + * + * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Shlomi Gridish <[email protected]> + * Jerry Huang <[email protected]> + * Copyright (c) MontaVista Software, Inc. 2008. + * Anton Vorontsov <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_FSL_GTM_H +#define __ASM_FSL_GTM_H + +#include <linux/types.h> +#include <linux/spinlock.h> +#include <linux/io.h> + +#define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1) +#define GTCFR_RST(x) ((x) & 1 ? 1 << 4 : 1 << 0) + +#define GTMDR_ICLK_MASK (3 << 1) +#define GTMDR_ICLK_ICAS (0 << 1) +#define GTMDR_ICLK_ICLK (1 << 1) +#define GTMDR_ICLK_SLGO (2 << 1) +#define GTMDR_FRR (1 << 3) +#define GTMDR_ORI (1 << 4) +#define GTMDR_SPS(x) ((x) << 8) + +struct gtm_timers_regs { + u8 gtcfr1; /* Timer 1, Timer 2 global config register */ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3, timer 4 global config register */ + u8 res1[0xB]; + __be16 gtmdr1; /* Timer 1 mode register */ + __be16 gtmdr2; /* Timer 2 mode register */ + __be16 gtrfr1; /* Timer 1 reference register */ + __be16 gtrfr2; /* Timer 2 reference register */ + __be16 gtcpr1; /* Timer 1 capture register */ + __be16 gtcpr2; /* Timer 2 capture register */ + __be16 gtcnr1; /* Timer 1 counter */ + __be16 gtcnr2; /* Timer 2 counter */ + __be16 gtmdr3; /* Timer 3 mode register */ + __be16 gtmdr4; /* Timer 4 mode register */ + __be16 gtrfr3; /* Timer 3 reference register */ + __be16 gtrfr4; /* Timer 4 reference register */ + __be16 gtcpr3; /* Timer 3 capture register */ + __be16 gtcpr4; /* Timer 4 capture register */ + __be16 gtcnr3; /* Timer 3 counter */ + __be16 gtcnr4; /* Timer 4 counter */ + __be16 gtevr1; /* Timer 1 event register */ + __be16 gtevr2; /* Timer 2 event register */ + __be16 gtevr3; /* Timer 3 event register */ + __be16 gtevr4; /* Timer 4 event register */ + __be16 gtpsr1; /* Timer 1 prescale register */ + __be16 gtpsr2; /* Timer 2 prescale register */ + __be16 gtpsr3; /* Timer 3 prescale register */ + __be16 gtpsr4; /* Timer 4 prescale register */ + u8 res2[0x40]; +} __attribute__ ((packed)); + +struct gtm_timer { + unsigned int irq; + + struct gtm *gtm; + bool requested; + u8 __iomem *gtcfr; + __be16 __iomem *gtmdr; + __be16 __iomem *gtpsr; + __be16 __iomem *gtcnr; + __be16 __iomem *gtrfr; + __be16 __iomem *gtevr; +}; + +struct gtm { + unsigned int clock; + struct gtm_timers_regs __iomem *regs; + struct gtm_timer timers[4]; + spinlock_t lock;Quoted 1 line
+};
Quoted 4 lines
Consider moving the register definitions and structures inside the .c file. This is all anonymous data as far as the caller is concerned. If the structures are only access inside the driver then you gain yourself a bit of safety by moving them.
Ok.
Quoted 23 lines
Quoted 14 lines
+
+extern structgtm_timer*gtm_get_timer(int width);
+extern structgtm_timer*gtm_get_specific_timer(struct gtm *gtm, int timer,
+ int width);
+extern voidgtm_put_timer(struct gtm_timer *tmr);
+extern int gtm_reset_timer16(structgtm_timer*tmr, unsigned long usec,
+ bool reload);
+extern intgtm_reset_utimer16(struct gtm_timer *tmr, u16 usec, bool reload); +extern voidgtm_stop_timer16(struct gtm_timer *tmr);
+
+/**
+ *gtm_ack_timer16- acknowledge timer event (free-run timers only)
+ * @tmr: pointer to thegtm_timerstructure obtained fromgtm_get_timer
+ * @events: events mask to ackQuoted 8 lines
+ *
+ * Thus function used to acknowledge timer interrupt event, use it inside the
+ * interrupt handler.
+ */
+static inline voidgtm_ack_timer16(struct gtm_timer *tmr, u16 events)+{
+out_be16(tmr->gtevr, events);
+}
Quoted 1 line
Drop 'inline' and expect gcc to do the right thing.
Not sure about newer gccs, but older complained about "defined but not used" functions w/o inline keyword. I'm almost sure that this is still true. I can surely use __maybe_unused, but "static inline" is pretty settled tradition, plus this function is small enough anyway.
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support
Quoted 11 lines
Quoted 7 lines
Quoted 5 lines
+static inline void gtm_ack_timer16(struct
gtm_timer*tmr, u16
events)
+{
+out_be16(tmr->gtevr, events);
+}Drop 'inline' and expect gcc to do the right thing.
Not sure about newer gccs, but older complained about "defined but not used" functions w/o inline keyword. I'm almost sure that this is still true.
It is. So why is it unused? Because you put the code in the header file. Can't you move it to the .c file instead?
Quoted 2 lines
I can surely use
__maybe_unused, but "static inline" is pretty settled tradition, plus this function is small enough anyway.
All code in header files should be inline. Code in implementation files should only be inline if you have a very good reason for doing so. Same goes for __maybe_unused.
Segher
Re: [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support
In reply to Grant LikelyQuoted 10 lines · Grant Likely
Quoted 5 lines
+ r) Freescale General-purpose Timers Module
+
+ Required properties:
+ - compatible : should be "fsl,gtm" ("fsl,qe-gtm" in addition for QE
+ GTMs or "fsl,cpm2-gtm" for CPM2 GTMs).I don't think this is specific enough. It is a very real possibility for Freescale to produce another part with a "general purpose timers module" that isn't register level compatible (and fsl,i2c is an example of what not to do).
If that happens, we'll make up "fsl,gtm2". :-)
Quoted 5 lines
The compatible string should include the
exact chip version. Newer parts can also claim compatibility with older ones.Defining a 'generic' compatible value is also known as "making stuff up". :-)
Nothing wrong with making stuff up as long as we do it sanely.
How about something like fsl,gtm-1.0?
Quoted 13 lines
Quoted 4 lines
+/**
+ *gtm_ack_timer16- acknowledge timer event (free-run timers only)
+ * @tmr: pointer to thegtm_timerstructure obtained fromgtm_get_timer
+ * @events: events mask to ackQuoted 8 lines
+ *
+ * Thus function used to acknowledge timer interrupt event, use it inside the
+ * interrupt handler.
+ */
+static inline voidgtm_ack_timer16(struct gtm_timer *tmr, u16 events)+{
+out_be16(tmr->gtevr, events);
+}
Quoted 1 line
Drop 'inline' and expect gcc to do the right thing.
Not in a header...
-Scott
Re: [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support
Quoted 8 lines · Scott Wood
Quoted 6 lines · Grant Likely
Quoted 5 lines
+ r) Freescale General-purpose Timers Module
+
+ Required properties:
+ - compatible : should be "fsl,gtm" ("fsl,qe-gtm" in addition for QE
+ GTMs or "fsl,cpm2-gtm" for CPM2 GTMs).
Quoted 6 lines
Quoted 4 lines
I don't think this is specific enough. It is a very real possibility for Freescale to produce another part with a "general purpose timers module" that isn't register level compatible (and fsl,i2c is an example of what not to do).
If that happens, we'll make up "fsl,gtm2". :-)
:-P
Quoted 9 lines
Quoted 5 lines
The compatible string should include the
exact chip version. Newer parts can also claim compatibility with older ones.Defining a 'generic' compatible value is also known as "making stuff up". :-)
Nothing wrong with making stuff up as long as we do it sanely.
How about something like fsl,gtm-1.0?
The problem I have with that is that there is always the potential that some rogue hardware will appear that messes up your sane scheme. Plus there is pretty much no downside to just choosing a device that the more recent parts reference.
Example: consider 3 chips using the same i2c core; say MPC8313, MPC5200 & MPC8548. compatible lines could look like this:
compatible = "fsl,mpc8313-i2c","fsl-i2c";
compatible = "fsl,mpc5200-i2c","fsl-i2c";
compatible = "fsl,mpc8548-i2c","fsl-i2c";Or; (assuming 8313 is where it first appeared) it could look like this:
compatible = "fsl,mpc8313-i2c";
compatible = "fsl,mpc5200-i2c","fsl,mpc8313-i2c";
compatible = "fsl,mpc8548-i2c","fsl,mpc8313-i2c";To the driver it's just a different string ("fsl,mpc8313-i2c" instead of "fsl-i2c"), but with the second you *always* know what an mpc8131-i2c core is; the mpc8131 user guide tells you. Even if you are strict about your sane naming scheme, you cannot look into the future and someone will do something wonky on you.
The other benefit is it avoids the temptation to define generic compatible values for things which will *never* be generic parts. Case in point; when I did the original mpc5200 bindings I did things like "mpc52xx-<blah>". However, there probably never will be another mpc52xx part; and if there is it will look vastly different from the current 5200. So I wasted all kinds of effort trying to be generic about stuff when it is almost certainly wasted effort and additional complexity to the naming conventions.
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
+static inline void
gtm_ack_timer16(struct gtm_timer *tmr, u16 events)+{
+out_be16(tmr->gtevr, events);
+}Drop 'inline' and expect gcc to do the right thing.
Not in a header...
Oops, yeah; not sure what I was smoking.
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
PATCH v2 2/5 QE: add support for QE USB clocks routing
In reply to Anton VorontsovThis patch adds a function to the qe_lib to setup QE USB clocks routing. To setup clocks safely, cmxgcr register needs locking, so I just reused ucc_lock since it was used only to protect cmxgcr.
The idea behind placing clocks routing functions into the qe_lib is that later we'll hopefully switch to the generic Linux Clock API, thus, for example, FHCI driver may be used for QE and CPM chips without nasty #ifdefs.
This patch also fixes QE_USB_RESTART_TX command definition in the qe.h.
--- arch/powerpc/sysdev/qe_lib/Kconfig | 4 ++ arch/powerpc/sysdev/qe_lib/Makefile | 1 + arch/powerpc/sysdev/qe_lib/ucc.c | 7 ++-- arch/powerpc/sysdev/qe_lib/usb.c | 56 +++++++++++++++++++++++++++++++++++ include/asm-powerpc/qe.h | 23 +++++++++++++- 5 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/sysdev/qe_lib/usb.c
arch/powerpc/sysdev/qe_lib/Kconfig +4 -0
@@ -20,3 +20,7 @@ config UCC bool default y if UCC_FAST || UCC_SLOW +config QE_USB + bool + help + QE USB Host Controller support
arch/powerpc/sysdev/qe_lib/Makefile +1 -0
@@ -6,3 +6,4 @@ obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o obj-$(CONFIG_UCC) += ucc.o obj-$(CONFIG_UCC_SLOW) += ucc_slow.o obj-$(CONFIG_UCC_FAST) += ucc_fast.o +obj-$(CONFIG_QE_USB) += usb.o
arch/powerpc/sysdev/qe_lib/ucc.c +4 -3
@@ -26,7 +26,8 @@#include <asm/qe.h> #include <asm/ucc.h> -static DEFINE_SPINLOCK (ucc_lock); +DEFINE_SPINLOCK (cmxgcr_lock); +EXPORT_SYMBOL (cmxgcr_lock);int ucc_set_qe_mux_mii_mng (unsigned int ucc_num) {
@@ -35,10 +36,10 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)if (ucc_num >UCC_MAX_NUM -1 )return -EINVAL ; -spin_lock_irqsave (&ucc_lock, flags); +spin_lock_irqsave (&cmxgcr_lock, flags);clrsetbits_be32 (&qe_immr->qmx.cmxgcr,QE_CMXGCR_MII_ENET_MNG , ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT ); -spin_unlock_irqrestore (&ucc_lock, flags); +spin_unlock_irqrestore (&cmxgcr_lock, flags);return 0 ; }
arch/powerpc/sysdev/qe_lib/usb.c new file +56 -0
56 lines not on this page · raw message
include/asm-powerpc/qe.h +22 -1
@@ -16,6 +16,7 @@#define _ASM_POWERPC_QE_H#ifdef __KERNEL__ +#include <linux/spinlock.h> #include <asm/immap_qe.h> #define QE_NUM_OF_SNUM 28
@@ -74,6 +75,13 @@ enum qe_clock { QE_CLK_DUMMY }; +static inline bool qe_clock_is_brg (enum qe_clock clk) +{ +return clk >=QE_BRG1 && clk <=QE_BRG16 ; +} + +extern spinlock_t cmxgcr_lock; +/* Export QE common operations */ extern void qe_reset (void );extern int par_io_init (struct device_node *np);
@@ -156,6 +164,9 @@ int qe_upload_firmware(const struct qe_firmware *firmware);/* Obtain information on the uploaded firmware */ struct qe_firmware_info *qe_get_firmware_info (void ); +/* QE USB */ +int qe_usb_clock_set (enum qe_clock clk,int rate); +/* Buffer descriptors */ struct qe_bd {__be16 status;
@@ -254,6 +265,16 @@ enum comm_dir {#define QE_CMXGCR_MII_ENET_MNG 0x00007000#define QE_CMXGCR_MII_ENET_MNG_SHIFT 12#define QE_CMXGCR_USBCS 0x0000000f +#define QE_CMXGCR_USBCS_CLK3 0x1 +#define QE_CMXGCR_USBCS_CLK5 0x2 +#define QE_CMXGCR_USBCS_CLK7 0x3 +#define QE_CMXGCR_USBCS_CLK9 0x4 +#define QE_CMXGCR_USBCS_CLK13 0x5 +#define QE_CMXGCR_USBCS_CLK17 0x6 +#define QE_CMXGCR_USBCS_CLK19 0x7 +#define QE_CMXGCR_USBCS_CLK21 0x8 +#define QE_CMXGCR_USBCS_BRG9 0x9 +#define QE_CMXGCR_USBCS_BRG10 0xa/* QE CECR Commands. */
@@ -283,7 +304,7 @@ enum comm_dir {#define QE_HPAC_START_TX 0x0000060b#define QE_HPAC_START_RX 0x0000070b#define QE_USB_STOP_TX 0x0000000a -#define QE_USB_RESTART_TX 0x0000000b +#define QE_USB_RESTART_TX 0x0000000c#define QE_QMC_STOP_TX 0x0000000c#define QE_QMC_STOP_RX 0x0000000d#define QE_SS7_SU_FIL_RESET 0x0000000e
Signature · 1 line
1.5.5
PATCH v2 3/5 QE: prepare QE PIO code for GPIO LIB support
In reply to Anton Vorontsov- split and export __par_io_config_pin() out of par_io_config_pin(), so we could use the prefixed version with GPIO LIB API;
- rename struct port_regs to qe_pio_regs, and place it into qe.h;
- rename #define NUM_OF_PINS to QE_PIO_PINS, and place it into qe.h.
--- arch/powerpc/sysdev/qe_lib/qe_io.c | 94 +++++++++++++++++------------------- include/asm-powerpc/qe.h | 19 +++++++ 2 files changed, 64 insertions(+), 49 deletions(-)
arch/powerpc/sysdev/qe_lib/qe_io.c +45 -49
@@ -28,21 +28,7 @@#undef DEBUG -#define NUM_OF_PINS 32 - -struct port_regs { -__be32 cpodr;/* Open drain register */ -__be32 cpdata;/* Data register */ -__be32 cpdir1;/* Direction register */ -__be32 cpdir2;/* Direction register */ -__be32 cppar1;/* Pin assignment register */ -__be32 cppar2;/* Pin assignment register */ -#ifdef CONFIG_PPC_85xx -u8 pad[8 ]; -#endif -}; - -static struct port_regs __iomem *par_io; +static struct qe_pio_regs __iomem *par_io;static int num_par_io_ports =0 ;int par_io_init (struct device_node *np)
@@ -64,69 +50,79 @@ int par_io_init(struct device_node *np)return 0 ; } -int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain, -int assignment,int has_irq) +void __par_io_config_pin (struct qe_pio_regs __iomem *par_io,u8 pin,int dir, +int open_drain,int assignment,int has_irq) { -u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val; - -if (!par_io) -return -1 ; +u32 pin_mask1bit; +u32 pin_mask2bits; +u32 new_mask2bits; +u32 tmp_val;/* calculate pin location for single and 2 bits information */ - pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin +1 ))); + pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin +1 )));/* Set open drain, if required */ - tmp_val =in_be32 (&par_io[port].cpodr); + tmp_val =in_be32 (&par_io->cpodr);if (open_drain) -out_be32 (&par_io[port].cpodr, pin_mask1bit | tmp_val); +out_be32 (&par_io->cpodr, pin_mask1bit | tmp_val);else -out_be32 (&par_io[port].cpodr, ~pin_mask1bit & tmp_val); +out_be32 (&par_io->cpodr, ~pin_mask1bit & tmp_val);/* define direction */ - tmp_val = (pin > (NUM_OF_PINS /2 ) -1 ) ? -in_be32 (&par_io[port].cpdir2) : -in_be32 (&par_io[port].cpdir1); + tmp_val = (pin > (QE_PIO_PINS /2 ) -1 ) ? +in_be32 (&par_io->cpdir2) : +in_be32 (&par_io->cpdir1);/* get all bits mask for 2 bit per port */ - pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS - - (pin % (NUM_OF_PINS /2 ) +1 ) *2 )); + pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS - + (pin % (QE_PIO_PINS /2 ) +1 ) *2 ));/* Get the final mask we need for the right definition */ - new_mask2bits = (u32) (dir << (NUM_OF_PINS - - (pin % (NUM_OF_PINS /2 ) +1 ) *2 )); + new_mask2bits = (u32) (dir << (QE_PIO_PINS - + (pin % (QE_PIO_PINS /2 ) +1 ) *2 ));/* clear and set 2 bits mask */ -if (pin > (NUM_OF_PINS /2 ) -1 ) { -out_be32 (&par_io[port].cpdir2, +if (pin > (QE_PIO_PINS /2 ) -1 ) { +out_be32 (&par_io->cpdir2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cpdir2, new_mask2bits | tmp_val); +out_be32 (&par_io->cpdir2, new_mask2bits | tmp_val); }else { -out_be32 (&par_io[port].cpdir1, +out_be32 (&par_io->cpdir1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cpdir1, new_mask2bits | tmp_val); +out_be32 (&par_io->cpdir1, new_mask2bits | tmp_val); }/* define pin assignment */ - tmp_val = (pin > (NUM_OF_PINS /2 ) -1 ) ? -in_be32 (&par_io[port].cppar2) : -in_be32 (&par_io[port].cppar1); + tmp_val = (pin > (QE_PIO_PINS /2 ) -1 ) ? +in_be32 (&par_io->cppar2) : +in_be32 (&par_io->cppar1); - new_mask2bits = (u32) (assignment << (NUM_OF_PINS - - (pin % (NUM_OF_PINS /2 ) +1 ) *2 )); + new_mask2bits = (u32) (assignment << (QE_PIO_PINS - + (pin % (QE_PIO_PINS /2 ) +1 ) *2 ));/* clear and set 2 bits mask */ -if (pin > (NUM_OF_PINS /2 ) -1 ) { -out_be32 (&par_io[port].cppar2, +if (pin > (QE_PIO_PINS /2 ) -1 ) { +out_be32 (&par_io->cppar2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cppar2, new_mask2bits | tmp_val); +out_be32 (&par_io->cppar2, new_mask2bits | tmp_val); }else { -out_be32 (&par_io[port].cppar1, +out_be32 (&par_io->cppar1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; -out_be32 (&par_io[port].cppar1, new_mask2bits | tmp_val); +out_be32 (&par_io->cppar1, new_mask2bits | tmp_val); } +} +EXPORT_SYMBOL (__par_io_config_pin); + +int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain, +int assignment,int has_irq) +{ +if (!par_io || port >= num_par_io_ports) +return -EINVAL ; +__par_io_config_pin (&par_io[port], pin, dir, open_drain, assignment, + has_irq);return 0 ; }EXPORT_SYMBOL (par_io_config_pin);
@@ -137,10 +133,10 @@ int par_io_data_set(u8 port, u8 pin, u8 val)if (port >= num_par_io_ports)return -EINVAL ; -if (pin >=NUM_OF_PINS ) +if (pin >=QE_PIO_PINS )return -EINVAL ;/* calculate pin location */ - pin_mask = (u32) (1 << (NUM_OF_PINS -1 - pin)); + pin_mask = (u32) (1 << (QE_PIO_PINS -1 - pin)); tmp_val =in_be32 (&par_io[port].cpdata);
include/asm-powerpc/qe.h +19 -0
@@ -84,8 +84,27 @@ extern spinlock_t cmxgcr_lock;/* Export QE common operations */ extern void qe_reset (void ); + +/* QE PIO */ +#define QE_PIO_PINS 32 + +struct qe_pio_regs { +__be32 cpodr;/* Open drain register */ +__be32 cpdata;/* Data register */ +__be32 cpdir1;/* Direction register */ +__be32 cpdir2;/* Direction register */ +__be32 cppar1;/* Pin assignment register */ +__be32 cppar2;/* Pin assignment register */ +#ifdef CONFIG_PPC_85xx +u8 pad[8 ]; +#endif +}; +extern int par_io_init (struct device_node *np);extern int par_io_of_config (struct device_node *np); +extern void __par_io_config_pin (struct qe_pio_regs __iomem *par_io,u8 pin, +int dir,int open_drain,int assignment, +int has_irq);extern int par_io_config_pin (u8 port,u8 pin,int dir,int open_drain,int assignment,int has_irq);extern int par_io_data_set (u8 port,u8 pin,u8 val);
Signature · 1 line
1.5.5
Re: [PATCH 3/5] [POWERPC] QE: prepare QE PIO code for GPIO LIB support
Quoted 6 lines · Anton Vorontsov
- split and export
__par_io_config_pin()out ofpar_io_config_pin(), so we could use the prefixed version with GPIO LIB API;
- rename structport_regstoqe_pio_regs, and place it intoqe.h;
- rename #defineNUM_OF_PINStoQE_PIO_PINS, and place it intoqe.h.Signed-off-by Anton Vorontsov <[email protected]>
I don't see any mutual exclusion here. How is __par_io_config_pin() protected when there are multiple callers?
Quoted 197 lines
---
arch/powerpc/sysdev/qe_lib/qe_io.c | 94 +++++++++++++++++------------------- include/asm-powerpc/qe.h | 19 +++++++ 2 files changed, 64 insertions(+), 49 deletions(-)diff --git
a/arch/powerpc/sysdev/qe_lib/qe_io.cb/arch/powerpc/sysdev/qe_lib/qe_io.cindex 93916a4..7c87460 100644
---a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -28,21 +28,7 @@#undef DEBUG
-#define
NUM_OF_PINS32
-
-structport_regs{- __be32 cpodr; /* Open drain register */ - __be32 cpdata; /* Data register */ - __be32 cpdir1; /* Direction register */ - __be32 cpdir2; /* Direction register */ - __be32 cppar1; /* Pin assignment register */ - __be32 cppar2; /* Pin assignment register */-#ifdef
CONFIG_PPC_85xx
- u8 pad[8];
-#endif
-};
-
-static structport_regs__iomem*par_io;
+static structqe_pio_regs__iomem*par_io;
static intnum_par_io_ports= 0;int
par_io_init(struct device_node *np)
@@ -64,69 +50,79 @@ intpar_io_init(struct device_node *np)return 0;}
-int par_io_config_pin(u8 port, u8 pin, int dir, int
open_drain,
- int assignment, inthas_irq)
+void __par_io_config_pin(structqe_pio_regs__iomem*par_io, u8 pin, int dir,
+ intopen_drain, int assignment, inthas_irq)
{
- u32pin_mask1bit,pin_mask2bits,new_mask2bits,tmp_val;
-
- if (!par_io)
- return -1;+ u32 pin_mask1bit; + u32 pin_mask2bits; + u32 new_mask2bits; + u32 tmp_val;/* calculate pin location for single and 2 bits information */-
pin_mask1bit= (u32) (1 << (NUM_OF_PINS- (pin + 1)));
+pin_mask1bit= (u32) (1 << (QE_PIO_PINS- (pin + 1)));/* Set open drain, if required */-
tmp_val=in_be32(&par_io[port].cpodr);
+tmp_val=in_be32(&par_io->cpodr);
if (open_drain)
-out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val);
+out_be32(&par_io->cpodr, pin_mask1bit | tmp_val);
else
-out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val);
+out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val);/* define direction */-
tmp_val= (pin > (NUM_OF_PINS/ 2) - 1) ?
-in_be32(&par_io[port].cpdir2):
-in_be32(&par_io[port].cpdir1);
+tmp_val= (pin > (QE_PIO_PINS/ 2) - 1) ?
+in_be32(&par_io->cpdir2):
+in_be32(&par_io->cpdir1);/* get all bits mask for 2 bit per port */-
pin_mask2bits= (u32) (0x3<< (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+pin_mask2bits= (u32) (0x3<< (QE_PIO_PINS-
+ (pin % (QE_PIO_PINS/ 2) + 1) * 2));/* Get the final mask we need for the right definition */-
new_mask2bits= (u32) (dir << (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+new_mask2bits= (u32) (dir << (QE_PIO_PINS-
+ (pin % (QE_PIO_PINS/ 2) + 1) * 2));/* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cpdir2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cpdir2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cpdir1, + out_be32(&par_io->cpdir1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir1, new_mask2bits | tmp_val); } /* define pin assignment */-
tmp_val= (pin > (NUM_OF_PINS/ 2) - 1) ?
-in_be32(&par_io[port].cppar2):
-in_be32(&par_io[port].cppar1);
+tmp_val= (pin > (QE_PIO_PINS/ 2) - 1) ?
+in_be32(&par_io->cppar2):
+in_be32(&par_io->cppar1);-
new_mask2bits= (u32) (assignment << (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+new_mask2bits= (u32) (assignment << (QE_PIO_PINS-+ (pin % (QE_PIO_PINS / 2) + 1) * 2)); /* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cppar2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cppar2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val); + out_be32(&par_io->cppar2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cppar1, + out_be32(&par_io->cppar1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val); + out_be32(&par_io->cppar1, new_mask2bits | tmp_val); }+}
+EXPORT_SYMBOL(__par_io_config_pin);
+
+int par_io_config_pin(u8 port, u8 pin, int dir, intopen_drain,
+ int assignment, inthas_irq)
+{
+ if (!par_io || port >=num_par_io_ports)
+ return-EINVAL;+ __par_io_config_pin(&par_io[port], pin, dir,
open_drain, assignment,+ has_irq); return 0;}
EXPORT_SYMBOL(par_io_config_pin);
@@ -137,10 +133,10 @@ intpar_io_data_set(u8 port, u8 pin, u8 val)if (port >=
num_par_io_ports)
return-EINVAL;
- if (pin >=NUM_OF_PINS)
+ if (pin >=QE_PIO_PINS)return -EINVAL; /* calculate pin location */-
pin_mask= (u32) (1 << (NUM_OF_PINS- 1 - pin));
+pin_mask= (u32) (1 << (QE_PIO_PINS- 1 - pin));tmp_val = in_be32(&par_io[port].cpdata);diff --git
a/include/asm-powerpc/qe.hb/include/asm-powerpc/qe.hindex d217288..c4523ac 100644
---a/include/asm-powerpc/qe.h
+++b/include/asm-powerpc/qe.h
@@ -84,8 +84,27 @@ externspinlock_tcmxgcr_lock;/* Export QE common operations */
extern voidqe_reset(void);
+
+/* QE PIO */
+#defineQE_PIO_PINS32
+
+structqe_pio_regs{+ __be32 cpodr; /* Open drain register */ + __be32 cpdata; /* Data register */ + __be32 cpdir1; /* Direction register */ + __be32 cpdir2; /* Direction register */ + __be32 cppar1; /* Pin assignment register */ + __be32 cppar2; /* Pin assignment register */ +#ifdef CONFIG_PPC_85xx + u8 pad[8]; +#endif +}; + extern int par_io_init(struct device_node *np); extern int par_io_of_config(struct device_node *np); +extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, + int dir, int open_drain, int assignment, + int has_irq); extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, int assignment, int has_irq);extern int
par_io_data_set(u8 port, u8 pin, u8 val);
--
1.5.5_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 3/5] [POWERPC] QE: prepare QE PIO code for GPIO LIB support
Quoted 11 lines · Grant Likely
Quoted 6 lines · Anton Vorontsov
- split and export
__par_io_config_pin()out ofpar_io_config_pin(), so we could use the prefixed version with GPIO LIB API;
- rename structport_regstoqe_pio_regs, and place it intoqe.h;
- rename #defineNUM_OF_PINStoQE_PIO_PINS, and place it intoqe.h.Signed-off-by Anton Vorontsov <[email protected]>I don't see any mutual exclusion here. How is
__par_io_config_pin()protected when there are multiple callers?
The idea is to not have multiple callers.
Today most callers of par_io_config_pin() is various board fixups, e.g. this in the setup_arch():
for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
par_io_of_config(np);Which calls par_io_config_pin(). But we're safe here, setup_arch called very early.
The only abuser of this is mpc832x_rdb.c, but it will be converted to the GPIO API.
Quoted 203 lines
Quoted 197 lines
---
arch/powerpc/sysdev/qe_lib/qe_io.c | 94 +++++++++++++++++------------------- include/asm-powerpc/qe.h | 19 +++++++ 2 files changed, 64 insertions(+), 49 deletions(-)diff --git
a/arch/powerpc/sysdev/qe_lib/qe_io.cb/arch/powerpc/sysdev/qe_lib/qe_io.cindex 93916a4..7c87460 100644
---a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -28,21 +28,7 @@#undef DEBUG
-#define
NUM_OF_PINS32
-
-structport_regs{- __be32 cpodr; /* Open drain register */ - __be32 cpdata; /* Data register */ - __be32 cpdir1; /* Direction register */ - __be32 cpdir2; /* Direction register */ - __be32 cppar1; /* Pin assignment register */ - __be32 cppar2; /* Pin assignment register */-#ifdef
CONFIG_PPC_85xx
- u8 pad[8];
-#endif
-};
-
-static structport_regs__iomem*par_io;
+static structqe_pio_regs__iomem*par_io;
static intnum_par_io_ports= 0;int
par_io_init(struct device_node *np)
@@ -64,69 +50,79 @@ intpar_io_init(struct device_node *np)return 0;}
-int par_io_config_pin(u8 port, u8 pin, int dir, int
open_drain,
- int assignment, inthas_irq)
+void __par_io_config_pin(structqe_pio_regs__iomem*par_io, u8 pin, int dir,
+ intopen_drain, int assignment, inthas_irq)
{
- u32pin_mask1bit,pin_mask2bits,new_mask2bits,tmp_val;
-
- if (!par_io)
- return -1;+ u32 pin_mask1bit; + u32 pin_mask2bits; + u32 new_mask2bits; + u32 tmp_val;/* calculate pin location for single and 2 bits information */-
pin_mask1bit= (u32) (1 << (NUM_OF_PINS- (pin + 1)));
+pin_mask1bit= (u32) (1 << (QE_PIO_PINS- (pin + 1)));/* Set open drain, if required */-
tmp_val=in_be32(&par_io[port].cpodr);
+tmp_val=in_be32(&par_io->cpodr);
if (open_drain)
-out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val);
+out_be32(&par_io->cpodr, pin_mask1bit | tmp_val);
else
-out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val);
+out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val);/* define direction */-
tmp_val= (pin > (NUM_OF_PINS/ 2) - 1) ?
-in_be32(&par_io[port].cpdir2):
-in_be32(&par_io[port].cpdir1);
+tmp_val= (pin > (QE_PIO_PINS/ 2) - 1) ?
+in_be32(&par_io->cpdir2):
+in_be32(&par_io->cpdir1);/* get all bits mask for 2 bit per port */-
pin_mask2bits= (u32) (0x3<< (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+pin_mask2bits= (u32) (0x3<< (QE_PIO_PINS-
+ (pin % (QE_PIO_PINS/ 2) + 1) * 2));/* Get the final mask we need for the right definition */-
new_mask2bits= (u32) (dir << (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+new_mask2bits= (u32) (dir << (QE_PIO_PINS-
+ (pin % (QE_PIO_PINS/ 2) + 1) * 2));/* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cpdir2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cpdir2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cpdir1, + out_be32(&par_io->cpdir1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir1, new_mask2bits | tmp_val); } /* define pin assignment */-
tmp_val= (pin > (NUM_OF_PINS/ 2) - 1) ?
-in_be32(&par_io[port].cppar2):
-in_be32(&par_io[port].cppar1);
+tmp_val= (pin > (QE_PIO_PINS/ 2) - 1) ?
+in_be32(&par_io->cppar2):
+in_be32(&par_io->cppar1);-
new_mask2bits= (u32) (assignment << (NUM_OF_PINS-
- (pin % (NUM_OF_PINS/ 2) + 1) * 2));
+new_mask2bits= (u32) (assignment << (QE_PIO_PINS-+ (pin % (QE_PIO_PINS / 2) + 1) * 2)); /* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cppar2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cppar2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val); + out_be32(&par_io->cppar2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cppar1, + out_be32(&par_io->cppar1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val); + out_be32(&par_io->cppar1, new_mask2bits | tmp_val); }+}
+EXPORT_SYMBOL(__par_io_config_pin);
+
+int par_io_config_pin(u8 port, u8 pin, int dir, intopen_drain,
+ int assignment, inthas_irq)
+{
+ if (!par_io || port >=num_par_io_ports)
+ return-EINVAL;+ __par_io_config_pin(&par_io[port], pin, dir,
open_drain, assignment,+ has_irq); return 0;}
EXPORT_SYMBOL(par_io_config_pin);
@@ -137,10 +133,10 @@ intpar_io_data_set(u8 port, u8 pin, u8 val)if (port >=
num_par_io_ports)
return-EINVAL;
- if (pin >=NUM_OF_PINS)
+ if (pin >=QE_PIO_PINS)return -EINVAL; /* calculate pin location */-
pin_mask= (u32) (1 << (NUM_OF_PINS- 1 - pin));
+pin_mask= (u32) (1 << (QE_PIO_PINS- 1 - pin));tmp_val = in_be32(&par_io[port].cpdata);diff --git
a/include/asm-powerpc/qe.hb/include/asm-powerpc/qe.hindex d217288..c4523ac 100644
---a/include/asm-powerpc/qe.h
+++b/include/asm-powerpc/qe.h
@@ -84,8 +84,27 @@ externspinlock_tcmxgcr_lock;/* Export QE common operations */
extern voidqe_reset(void);
+
+/* QE PIO */
+#defineQE_PIO_PINS32
+
+structqe_pio_regs{+ __be32 cpodr; /* Open drain register */ + __be32 cpdata; /* Data register */ + __be32 cpdir1; /* Direction register */ + __be32 cpdir2; /* Direction register */ + __be32 cppar1; /* Pin assignment register */ + __be32 cppar2; /* Pin assignment register */ +#ifdef CONFIG_PPC_85xx + u8 pad[8]; +#endif +}; + extern int par_io_init(struct device_node *np); extern int par_io_of_config(struct device_node *np); +extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, + int dir, int open_drain, int assignment, + int has_irq); extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, int assignment, int has_irq);extern int
par_io_data_set(u8 port, u8 pin, u8 val);
--
1.5.5_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-devSignature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
PATCH v2 4/5 QE: implement support for the GPIO LIB API
In reply to Anton VorontsovThis is needed to access QE GPIOs via Linux GPIO API.
---
Quoted 22 lines · Kumar Gala
Quoted 20 lines · Anton Vorontsov
Quoted 18 lines · Kumar Gala
Quoted 14 lines
index a3f9c3f..a4a195a 100644
arch/powerpc/sysdev/qe_lib/qe_io.c +2
-1@@ -20,7 +20,8 @@#include <linux/errno.h> #include <linux/module.h> #include <linux/ioport.h> - +#include <linux/spinlock.h> +#include <linux/of_gpio.h> #include <asm/io.h> #include <asm/qe.h> #include <asm/prom.h> arch/powerpc/sysdev/qe_lib/qe_io.c int par_io_of_config(struct device_node *np) · line 216
Quoted 2 lines
arch/powerpc/sysdev/qe_lib/qe_io.c +0
-0@@ -214,6 +215,140 @@ int par_io_of_config(struct device_node *np) }EXPORT_SYMBOL (par_io_of_config);can we split this out into a new file since its pretty much a driver.
Quoted 5 lines
Quoted 1 line
No problem. Would you prefer this to go under
drivers/gpio/?Yes that would be better. We actively worked on pull drivers out of
arch/ppcback in the day.
Hi David,
Do we need your Ack to go this through powerpc tree, and if so, could you provide one?
Thanks.
Documentation/powerpc/booting-without-of.txt | 34 ++++--- arch/powerpc/platforms/Kconfig | 2 + drivers/gpio/Kconfig | 9 ++ drivers/gpio/Makefile | 1 + drivers/gpio/qe.c | 147 ++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 drivers/gpio/qe.c
Documentation/powerpc/booting-without-of.txt +20 -12
@@ -1721,24 +1721,32 @@ platforms are moved over to use the flattened-device-tree model. information. Required properties: - - device_type : should be "par_io". + - #gpio-cells : should be "2". + - compatible : should be "fsl,qe-pario-bank-<bank>", "fsl,qe-pario-bank" - reg : offset to the register set and its length. - - num-ports : number of Parallel I/O ports + - gpio-controller : node to identify gpio controllers. - Example: - par_io@1400 { - reg = <1400 100>; - #address-cells = <1>; - #size-cells = <0>; - device_type = "par_io"; - num-ports = <7>; - ucc_pin@01 { - ...... - }; + For example, two QE Par I/O banks: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; vi) Pin configuration nodes + NOTE: pin configuration nodes are obsolete. Usually, their existance + is an evidence of the firmware shortcomings. Such fixups are + better handled by the Linux board file, not the device tree. + Required properties: - linux,phandle : phandle of this node; likely referenced by a QE device.
arch/powerpc/platforms/Kconfig +2 -0
@@ -270,6 +270,8 @@ config QUICC_ENGINE bool select PPC_LIB_RHEAP select CRC32 + select GENERIC_GPIO + select HAVE_GPIO_LIB help The QUICC Engine (QE) is a new generation of communications coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
drivers/gpio/Kconfig +9 -0
@@ -25,6 +25,15 @@ config DEBUG_GPIO # put expanders in the right section, in alphabetical order +comment "On-chip GPIOs:" + +config GPIO_QE + bool "QUICC Engine GPIOs" + depends on QUICC_ENGINE + help + Say Y here to use GPIOs on the Freescale PowerPC CPUs with + QUICC Engine block. + comment "I2C GPIO expanders:" config GPIO_PCA953X
drivers/gpio/Makefile +1 -0
@@ -7,3 +7,4 @@ obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o +obj-$(CONFIG_GPIO_QE) += qe.o
drivers/gpio/qe.c new file +147 -0
147 lines not on this page · raw message
Signature · 1 line
1.5.5
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 7 lines · Anton Vorontsov
Quoted 6 lines · Kumar Gala
Quoted 2 lines · Anton Vorontsov
No problem. Would you prefer this to go under
drivers/gpio/?Yes that would be better. We actively worked on pull drivers out of
arch/ppcback in the day.
I'm not sure I see the problem here. This is precisely the kind of *non-driver* code that normally (i.e. for all other Linux platforms I've looked at) *belongs* in the arch code ... what's the objection to doing it the same way other platforms do?
And for that matter, why make it optional, via Kconfig, instead of always configuring it in, along with the GPIO interrupt support? A quick glance at one of the MPC83xx chips suggested that QE port IRQ capabilities would be very chip specific, so I'd expect that GPIO IRQ support wouldn't naturally move out of the arch tree.
- Dave
Quoted 14 lines
Hi David,
Do we need your Ack to go this through powerpc tree, and if so, could you provide one?
Thanks.
Documentation/powerpc/booting-without-of.txt | 34 ++++---
arch/powerpc/platforms/Kconfig| 2 +drivers/gpio/Kconfig| 9 ++drivers/gpio/Makefile| 1 +drivers/gpio/qe.c| 147 ++++++++++++++++++++++++++5 files changed, 180 insertions(+), 13 deletions(-)create mode 100644
drivers/gpio/qe.c
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
In reply to Anton VorontsovQuoted 11 lines · Anton Vorontsov
This is needed to access QE GPIOs via Linux GPIO API.
Signed-off-by Anton Vorontsov <[email protected]>---
diff --gita/Documentation/powerpc/booting-without-of.txtb/Documentation/powerpc/booting-without-of.txtindex 827b630..5c9cfab 100644
---a/Documentation/powerpc/booting-without-of.txt
+++b/Documentation/powerpc/booting-without-of.txt
@@ -1721,24 +1721,32 @@ platforms are moved over to use the flattened-device-tree model.
information.
Quoted 4 lines
Required properties:
- - device_type : should be "par_io". + - #gpio-cells : should be "2". + - compatible : should be "fsl,qe-pario-bank-<bank>", "fsl,qe-pario-bank"
Once again; I don't like the generic compatible values. Please include the exact chip name in the string. ie: "fsl,<chip>-qe-pario".
"fsl,qe-pario-bank" is not a real thing. If you want a common compatible string that the driver can bind against, then choose one real part and add it to the compatible list for all the other parts.
Also, why is <bank> encoded in compatible? Do the different banks have different register interfaces?
Quoted 76 lines
- reg : offset to the register set and its length.
- - num-ports : number of Parallel I/O ports
+ - gpio-controller : node to identify gpio controllers.- Example:
- par_io@1400 {- reg = <1400 100>; - #address-cells = <1>; - #size-cells = <0>; - device_type = "par_io"; - num-ports = <7>; - ucc_pin@01 { - ...... - }; + For example, two QE Par I/O banks: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller;+ };
+
qe_pio_e: gpio-controller@1460 {+ #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller;+ };
vi) Pin configuration nodes
+ NOTE: pin configuration nodes are obsolete. Usually, their existance
+ is an evidence of the firmware shortcomings. Such fixups are
+ better handled by the Linux board file, not the device tree.
+
Required properties:
- linux,phandle : phandle of this node; likely referenced by a QE device.
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index f38c50b..f6eecd1 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -270,6 +270,8 @@ configQUICC_ENGINE
bool
selectPPC_LIB_RHEAP
select CRC32
+ selectGENERIC_GPIO
+ selectHAVE_GPIO_LIB
help
The QUICC Engine (QE) is a new generation of communications coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bbd2834..cee56f9 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -25,6 +25,15 @@ configDEBUG_GPIO# put expanders in the right section, in alphabetical order+comment "On-chip GPIOs:"
+
+configGPIO_QE+ bool "QUICC Engine GPIOs" + depends on QUICC_ENGINE + help+ Say Y here to use GPIOs on the Freescale PowerPC CPUs with
+ QUICC Engine block.
+
comment "I2C GPIO expanders:"config
GPIO_PCA953X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fdde992..fd0a41f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
Quoted 4 lines
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o +obj-$(CONFIG_GPIO_QE) += qe.o
Since this isn't an of_platform or a platform driver; I'd put it into arch/powerpc instead.
Quoted 46 lines
diff --git
a/drivers/gpio/qe.cb/drivers/gpio/qe.cnew file mode 100644
index 0000000..474bc44
---/dev/null
+++b/drivers/gpio/qe.c
+static int__initqe_add_gpiochips(void)+{
+ int ret;
+ structdevice_node*np;
+
+for_each_compatible_node(np, NULL, "fsl,qe-pario-bank"){+ struct qe_gpio_chip *qe_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); + if (!qe_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&qe_gc->lock); + + mm_gc = &qe_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + mm_gc->save_regs = qe_gpio_save_regs; + of_gc->gpio_cells = 2; + gc->ngpio = QE_PIO_PINS; + gc->direction_input = qe_gpio_dir_in; + gc->direction_output = qe_gpio_dir_out; + gc->get = qe_gpio_get; + gc->set = qe_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + } + + return 0; +err: + pr_err("%s: registration failed with status %d\n", np->full_name, ret); + of_node_put(np); + return ret;
Quoted 2 lines
+}
+arch_initcall(qe_add_gpiochips);
Should this really be a arch_initcall()? Would it be better for platforms needing it to call it explicitly from one of the platform's machine_arch_initcall()? Otherwise it gets called for all platforms in a multiplatform kernel.
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 21 lines · Grant Likely
Quoted 11 lines · Anton Vorontsov
This is needed to access QE GPIOs via Linux GPIO API.
Signed-off-by Anton Vorontsov <[email protected]>---
diff --gita/Documentation/powerpc/booting-without-of.txtb/Documentation/powerpc/booting-without-of.txtindex 827b630..5c9cfab 100644
---a/Documentation/powerpc/booting-without-of.txt
+++b/Documentation/powerpc/booting-without-of.txt
@@ -1721,24 +1721,32 @@ platforms are moved over to use the flattened-device-tree model.
information.Quoted 4 lines
Required properties:
- - device_type : should be "par_io". + - #gpio-cells : should be "2". + - compatible : should be "fsl,qe-pario-bank-<bank>", "fsl,qe-pario-bank"Once again; I don't like the generic compatible values. Please include the exact chip name in the string. ie: "fsl,<chip>-qe-pario".
Quoted 6 lines
"fsl,qe-pario-bank" is not a real thing. If you want a common compatible string that the driver can bind against, then choose one real part and add it to the compatible list for all the other parts.
Also, why is <bank> encoded in compatible? Do the different banks have different register interfaces?
Yes, they could. For example, interrupt pins are bank-specific.
Quoted 81 lines
Quoted 76 lines
- reg : offset to the register set and its length.
- - num-ports : number of Parallel I/O ports
+ - gpio-controller : node to identify gpio controllers.- Example:
- par_io@1400 {- reg = <1400 100>; - #address-cells = <1>; - #size-cells = <0>; - device_type = "par_io"; - num-ports = <7>; - ucc_pin@01 { - ...... - }; + For example, two QE Par I/O banks: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller;+ };
+
qe_pio_e: gpio-controller@1460 {+ #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller;+ };
vi) Pin configuration nodes
+ NOTE: pin configuration nodes are obsolete. Usually, their existance
+ is an evidence of the firmware shortcomings. Such fixups are
+ better handled by the Linux board file, not the device tree.
+
Required properties:
- linux,phandle : phandle of this node; likely referenced by a QE device.
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index f38c50b..f6eecd1 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -270,6 +270,8 @@ configQUICC_ENGINE
bool
selectPPC_LIB_RHEAP
select CRC32
+ selectGENERIC_GPIO
+ selectHAVE_GPIO_LIB
help
The QUICC Engine (QE) is a new generation of communications coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bbd2834..cee56f9 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -25,6 +25,15 @@ configDEBUG_GPIO# put expanders in the right section, in alphabetical order+comment "On-chip GPIOs:"
+
+configGPIO_QE+ bool "QUICC Engine GPIOs" + depends on QUICC_ENGINE + help+ Say Y here to use GPIOs on the Freescale PowerPC CPUs with
+ QUICC Engine block.
+
comment "I2C GPIO expanders:"config
GPIO_PCA953X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fdde992..fd0a41f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.oQuoted 4 lines
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o +obj-$(CONFIG_GPIO_QE) += qe.o
Quoted 2 lines
Since this isn't an
of_platformor a platform driver; I'd put it intoarch/powerpcinstead.
Heh.
Quoted 49 lines
Quoted 46 lines
diff --git
a/drivers/gpio/qe.cb/drivers/gpio/qe.cnew file mode 100644
index 0000000..474bc44
---/dev/null
+++b/drivers/gpio/qe.c
+static int__initqe_add_gpiochips(void)+{
+ int ret;
+ structdevice_node*np;
+
+for_each_compatible_node(np, NULL, "fsl,qe-pario-bank"){+ struct qe_gpio_chip *qe_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); + if (!qe_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&qe_gc->lock); + + mm_gc = &qe_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + mm_gc->save_regs = qe_gpio_save_regs; + of_gc->gpio_cells = 2; + gc->ngpio = QE_PIO_PINS; + gc->direction_input = qe_gpio_dir_in; + gc->direction_output = qe_gpio_dir_out; + gc->get = qe_gpio_get; + gc->set = qe_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + } + + return 0; +err: + pr_err("%s: registration failed with status %d\n", np->full_name, ret); + of_node_put(np); + return ret;Quoted 2 lines
+}
+arch_initcall(qe_add_gpiochips);
Quoted 4 lines
Should this really be a
arch_initcall()? Would it be better for platforms needing it to call it explicitly from one of the platform'smachine_arch_initcall()? Otherwise it gets called for all platforms in a multiplatform kernel.
Ok, I'll place it into qe_reset().
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
On Mon, Apr 21, 2008 at 06:33:13PM +0400, Anton Vorontsov wrote:
[...]
Quoted 44 lines
Quoted 44 lines
Quoted 43 lines
+static int
__initqe_add_gpiochips(void)
+{
+ int ret;
+ structdevice_node*np;
+
+for_each_compatible_node(np, NULL, "fsl,qe-pario-bank"){+ struct qe_gpio_chip *qe_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); + if (!qe_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&qe_gc->lock); + + mm_gc = &qe_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + mm_gc->save_regs = qe_gpio_save_regs; + of_gc->gpio_cells = 2; + gc->ngpio = QE_PIO_PINS; + gc->direction_input = qe_gpio_dir_in; + gc->direction_output = qe_gpio_dir_out; + gc->get = qe_gpio_get; + gc->set = qe_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + } + + return 0; +err: + pr_err("%s: registration failed with status %d\n", np->full_name, ret); + of_node_put(np); + return ret;+}
+arch_initcall(qe_add_gpiochips);
Quoted 6 lines
Quoted 4 lines
Should this really be a
arch_initcall()? Would it be better for platforms needing it to call it explicitly from one of the platform'smachine_arch_initcall()? Otherwise it gets called for all platforms in a multiplatform kernel.Ok, I'll place it into
qe_reset().
Ugh, no, I can't. qe_reset() is called too early. And I don't like having every QE board file to call this through machine_arch_initcall... Hmm, what to do.. well, is this thaat bad to call this for every platform?..
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 11 lines · Anton Vorontsov
Quoted 6 lines
Quoted 4 lines
Should this really be a
arch_initcall()? Would it be better for platforms needing it to call it explicitly from one of the platform'smachine_arch_initcall()? Otherwise it gets called for all platforms in a multiplatform kernel.Ok, I'll place it into
qe_reset().Ugh, no, I can't.
qe_reset()is called too early. And I don't like having every QE board file to call this throughmachine_arch_initcall... Hmm, what to do.. well, is this thaat bad to call this for every platform?..
Its not great. It has a boot time impact for every platform compiled into the kernel. The problem gets worse every time another block of code uses this method. Personally I prefer platform code calling it explicitly.
Making it an of_platform device would also eliminate that problem, but you'd need a method to synchronize the driver with its users.
I'm not going to raise a big stink about it, but the issue should not be ignored.
Cheers,
g.
Quoted 8 lines
--
Anton Vorontsov
email: [email protected]
irc://irc.freenode.net/bd2
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 19 lines · Grant Likely
Quoted 11 lines · Anton Vorontsov
Quoted 6 lines
Quoted 4 lines
Should this really be a
arch_initcall()? Would it be better for platforms needing it to call it explicitly from one of the platform'smachine_arch_initcall()? Otherwise it gets called for all platforms in a multiplatform kernel.Ok, I'll place it into
qe_reset().Ugh, no, I can't.
qe_reset()is called too early. And I don't like having every QE board file to call this throughmachine_arch_initcall... Hmm, what to do.. well, is this thaat bad to call this for every platform?..Its not great. It has a boot time impact for every platform compiled into the kernel. The problem gets worse every time another block of code uses this method. Personally I prefer platform code calling it explicitly.
Quoted 5 lines
Making it an
of_platformdevice would also eliminate that problem, but you'd need a method to synchronize the driver with its users.I'm not going to raise a big stink about it, but the issue should not be ignored.
Heh.. how QE GPIO is different from FSL GTM then? Should I call fsl_gtm_init() from the board file too? For the every board? I do believe that years later someone will show up with something like this:
From: J. Random Hacker
Subject: [POWERPC] cleanup board initialization code
This patch removes vast amount of machine_arch_initcall()s that were used to solely initialize some hardware, like this:
qe_add_gpio_chips();
fsl_gtm_init();
fsl_spi_init();
...
So, instead of calling this stuff from the board files, we implement own arch_initcalls for these functions.
This causes negligible run-time overhead for the boards that aren't using that hardware, but this overhead isn't measurable anyway. Also, this patch shrinks .text size a bit, and produces nice looking diffstat.
12 file changed, 6 insertions(+), 140 deletions(-)
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 6 lines · Anton Vorontsov
From: J. Random Hacker
Subject: [POWERPC] cleanup board initialization codeThis patch removes vast amount of machine_arch_initcall()s that were used to solely initialize some hardware, like this:
Quoted 7 lines
qe_add_gpio_chips();
fsl_gtm_init();
fsl_spi_init();
...So, instead of calling this stuff from the board files, we implement own
arch_initcallsfor these functions.
The way other platforms do this is to hav SOC-specific init code, and have board-specific initcalls call the relevant SOC-specific setup.
Among other things that facilitates kernels that handle multiple SOCs (if they're closely-enough related). That may not be used by many distros (handhelds.org being at least a partial exception), but it certainly helps cut the number of configurations that need build-testing.
- Dave
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 12 lines · David Brownell
Quoted 11 lines · Anton Vorontsov
From: J. Random Hacker
Subject: [POWERPC] cleanup board initialization codeThis patch removes vast amount of machine_arch_initcall()s that were used to solely initialize some hardware, like this:
qe_add_gpio_chips();
fsl_gtm_init();
fsl_spi_init();
...
Quoted 6 lines
Quoted 2 lines
So, instead of calling this stuff from the board files, we implement own
arch_initcallsfor these functions.The way other platforms do this is to hav SOC-specific init code, and have board-specific initcalls call the relevant SOC-specific setup.
I don't know about other platforms other than PowerPC and some ARM, of course. For example, PXA boards don't call any SOC specific code. Instead, looking into reworked PXA code, I can see that there are separate arch_initcalls() for the pxa25x, pxa27x, and pxa3xx SOCs. The same for s3cxxxx. So, at least not every platform out there doing this.
Yes, I can see AVR32. But there are only two boards, and when you'll have more, probably later you'd want to eliminate some repetitive code, if possible.
Here, with OF, it's quite simple because we have methods of "probing" SOC devices instead of placing init code into board files (think arch/ppc/).
Quoted 5 lines
Among other things that facilitates kernels that handle multiple SOCs (if they're closely-enough related). That may not be used by many distros (handhelds.org being at least a partial exception), but it certainly helps cut the number of configurations that need build-testing.
Is this about QE_GPIO being user-selectable? Yes, verbose Konfig option have its own drawbacks. Though, I don't actually have any objections for making it silent.
And well, I'm not objecting for placing qe gpio code under arch/, too. I'll resend this patch once again reverting its placement to arch/.
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Quoted 10 lines · Anton Vorontsov
Quoted 3 lines · David Brownell
The way other platforms do this is to hav SOC-specific init code, and have board-specific initcalls call the relevant SOC-specific setup.
I don't know about other platforms other than PowerPC and some ARM, of course. For example, PXA boards don't call any SOC specific code. Instead, looking into reworked PXA code, I can see that there are separate
arch_initcalls()for the pxa25x, pxa27x, and pxa3xx SOCs.
Exactly: SOC-specific initcalls.
Quoted 7 lines
Quoted 5 lines
Among other things that facilitates kernels that handle multiple SOCs (if they're closely-enough related). That may not be used by many distros (handhelds.org being at least a partial exception), but it certainly helps cut the number of configurations that need build-testing.
Is this about
QE_GPIObeing user-selectable?
No. It's about "kernels that handle multiple SOCs". Like for example pxa{25,27,3x}x ... or omap{16xx,17xx,5912}.
Consider several ways to support a family of SOCs.
- One way supports only one board at a time. Testing builds after arch level changes means rebuilding kernels for each board ... quite possibly several dozen.
- Another supports several boards, but only if they use the same SOC. Testing builds here takes fewer kernels; one per SOC; better, but still routinely shortchanged.
- Yet another way supports any number of boards, using a variety of mostly-compatible SOCs. This allows test builds that support entire SOC families (e.g. OMAP1, or OMAP2/OMAP3, or PXA XScale, etc).
Test builds are a quality control thing. If they're done regularly, it's less likely you'll push code upstream that can't build in some configuration.
Quoted 2 lines
And well, I'm not objecting for placing qe gpio code under
arch/, too. I'll resend this patch once again reverting its placement toarch/.
OK, good. Then I don't really have to be involved with that.
- Dave
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
In reply to Anton VorontsovQuoted 20 lines · Anton Vorontsov
Quoted 10 lines · Grant Likely
Its not great. It has a boot time impact for every platform compiled into the kernel. The problem gets worse every time another block of code uses this method. Personally I prefer platform code calling it explicitly.
Making it an
of_platformdevice would also eliminate that problem, but you'd need a method to synchronize the driver with its users.I'm not going to raise a big stink about it, but the issue should not be ignored.
Heh.. how QE GPIO is different from FSL GTM then? Should I call
fsl_gtm_init()from the board file too? For the every board? I do believe that years later someone will show up with something like this:From: J. Random Hacker
Subject: [POWERPC] cleanup board initialization code
Quoted 6 lines
This patch removes vast amount of machine_arch_initcall()s that were used to solely initialize some hardware, like this:
qe_add_gpio_chips(); fsl_gtm_init(); fsl_spi_init();
Or have a soc-level helper function for calling them for you; but yes.
And, no, we shouldn't have a vast array of individual initcalls because the platform code shouldn't be that large. As much as possible, multiple boards should be supported by the same platform code. I argue that most boards using the same SoC should use the same platform code. (see platforms/52xx/mpc5200_simple.c)
Individual calls has the added advantage that if a board port needs those functions to *not* be called (for whatever reason) then it has the ability to not call them.
It is for the same reason that the platform code is responsible for calling of_platform_bus_probe() instead of it being an initcall; it give the platform code control over the device registrations.
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
In reply to Anton VorontsovQuoted 4 lines
Quoted 2 lines
Also, why is <bank> encoded in compatible? Do the different banks have different register interfaces?
Yes, they could. For example, interrupt pins are bank-specific.
In what way? If different banks just have different IRQ #s, there are easier ways to express this.
Segher
PATCH v2 5/5 83xx: new board support: MPC8360E-RDK
In reply to Anton VorontsovThis is patch adds board file, device tree, and defconfig for the new board, made by Freescale Semiconductor Inc. and Logic Product Development.
Currently supported:
1. UEC{1,2,7,4};
2. I2C;
3. SPI;
4. NS16550 serial;
5. PCI and miniPCI;
6. Intel NOR StrataFlash X16 64Mbit PC28F640P30T85;
7. Graphics controller, Fujitsu MB86277.
Not supported in this patch:
1. StMICRO NAND512W3A2BN6E, 512 Mbit (supported with FSL UPM NAND driver);
2. FHCI USB (supported with FHCI driver).
3. QE Serial UCCs (tested to not work with ucc_uart driver, reason unknown, yet);
4. ADC AD7843 (tested to work, but support via device tree depends on major SPI rework, GPIO API, etc);
--- arch/powerpc/boot/dts/mpc836x_rdk.dts | 394 ++++++++ arch/powerpc/configs/83xx/mpc836x_rdk_defconfig | 1092 +++++++++++++++++++++++ arch/powerpc/platforms/83xx/Kconfig | 8 + arch/powerpc/platforms/83xx/Makefile | 1 + arch/powerpc/platforms/83xx/mpc836x_rdk.c | 106 +++ 5 files changed, 1601 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/boot/dts/mpc836x_rdk.dts create mode 100644 arch/powerpc/configs/83xx/mpc836x_rdk_defconfig create mode 100644 arch/powerpc/platforms/83xx/mpc836x_rdk.c
arch/powerpc/boot/dts/mpc836x_rdk.dts new file +394 -0
@@ -0,0 +1,394 @@ +/* + * MPC8360E RDK Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * Copyright 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8360rdk"; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + pci0 = &pci0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8360@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + /* filled by u-boot */ + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + }; + + memory { + device_type = "memory"; + /* filled by u-boot */ + reg = <0 0>; + }; + + soc@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "fsl,mpc8360-immr", "fsl,immr", "fsl,soc", + "simple-bus"; + ranges = <0 0xe0000000 0x200000>; + reg = <0xe0000000 0x200>; + /* filled by u-boot */ + bus-frequency = <0>; + + wdt@200 { + compatible = "mpc83xx_wdt"; + reg = <0x200 0x100>; + }; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 8>; + interrupt-parent = <&ipic>; + dfsrr; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <16 8>; + interrupt-parent = <&ipic>; + dfsrr; + }; + + serial0: serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4500 0x100>; + interrupts = <9 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + serial1: serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + interrupts = <10 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + crypto@30000 { + compatible = "fsl,sec2-crypto"; + reg = <0x30000 0x10000>; + interrupts = <11 8>; + interrupt-parent = <&ipic>; + num-channels = <4>; + channel-fifo-len = <24>; + exec-units-mask = <0x7e>; + /* + * desc mask is for rev1.x, we need runtime fixup + * for >=2.x + */ + descriptor-types-mask = <0x1010ebf>; + }; + + ipic: interrupt-controller@700 { + #address-cells = <0>; + #interrupt-cells = <2>; + compatible = "fsl,pq2pro-pic", "fsl,ipic"; + interrupt-controller; + reg = <0x700 0x100>; + }; + + qe_pio_b: gpio-controller@1418 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1418 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; + + qe@100000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "qe"; + compatible = "fsl,qe", "simple-bus"; + ranges = <0 0x100000 0x100000>; + reg = <0x100000 0x480>; + /* filled by u-boot */ + clock-frequency = <0>; + bus-frequency = <0>; + brg-frequency = <0>; + + muram@10000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,qe-muram", "fsl,cpm-muram"; + ranges = <0 0x10000 0xc000>; + + data-only@0 { + compatible = "fsl,qe-muram-data", + "fsl,cpm-muram-data"; + reg = <0 0xc000>; + }; + }; + + timer@440 { + compatible = "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + spi@4c0 { + cell-index = <0>; + compatible = "fsl,spi"; + reg = <0x4c0 0x40>; + interrupts = <2>; + interrupt-parent = <&qeic>; + mode = "cpu-qe"; + }; + + spi@500 { + cell-index = <1>; + compatible = "fsl,spi"; + reg = <0x500 0x40>; + interrupts = <1>; + interrupt-parent = <&qeic>; + mode = "cpu-qe"; + }; + + enet0: ucc@2000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <1>; + reg = <0x2000 0x200>; + interrupts = <32>; + interrupt-parent = <&qeic>; + rx-clock-name = "none"; + tx-clock-name = "clk9"; + phy-handle = <&phy2>; + phy-connection-type = "rgmii-rxid"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet1: ucc@3000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <2>; + reg = <0x3000 0x200>; + interrupts = <33>; + interrupt-parent = <&qeic>; + rx-clock-name = "none"; + tx-clock-name = "clk4"; + phy-handle = <&phy4>; + phy-connection-type = "rgmii-rxid"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet2: ucc@2600 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <7>; + reg = <0x2600 0x200>; + interrupts = <42>; + interrupt-parent = <&qeic>; + rx-clock-name = "clk20"; + tx-clock-name = "clk19"; + phy-handle = <&phy1>; + phy-connection-type = "mii"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet3: ucc@3200 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <4>; + reg = <0x3200 0x200>; + interrupts = <35>; + interrupt-parent = <&qeic>; + rx-clock-name = "clk8"; + tx-clock-name = "clk7"; + phy-handle = <&phy3>; + phy-connection-type = "mii"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + mdio@2120 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,ucc-mdio"; + reg = <0x2120 0x18>; + + phy1: ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "national,DP83848VV"; + reg = <1>; + }; + + phy2: ethernet-phy@2 { + device_type = "ethernet-phy"; + compatible = "broadcom,BCM5481UA2KMLG"; + reg = <2>; + }; + + phy3: ethernet-phy@3 { + device_type = "ethernet-phy"; + compatible = "national,DP83848VV"; + reg = <3>; + }; + + phy4: ethernet-phy@4 { + device_type = "ethernet-phy"; + compatible = "broadcom,BCM5481UA2KMLG"; + reg = <4>; + }; + }; + + serial2: ucc@2400 { + device_type = "serial"; + compatible = "ucc_uart"; + reg = <0x2400 0x200>; + cell-index = <5>; + port-number = <0>; + rx-clock-name = "brg7"; + tx-clock-name = "brg8"; + interrupts = <40>; + interrupt-parent = <&qeic>; + soft-uart; + }; + + serial3: ucc@3400 { + device_type = "serial"; + compatible = "ucc_uart"; + reg = <0x3400 0x200>; + cell-index = <6>; + port-number = <1>; + rx-clock-name = "brg13"; + tx-clock-name = "brg14"; + interrupts = <41>; + interrupt-parent = <&qeic>; + soft-uart; + }; + + qeic: interrupt-controller@80 { + #address-cells = <0>; + #interrupt-cells = <1>; + compatible = "fsl,qe-ic"; + interrupt-controller; + reg = <0x80 0x80>; + big-endian; + interrupts = <32 8 33 8>; + interrupt-parent = <&ipic>; + }; + }; + }; + + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus", + "simple-bus"; + reg = <0xe0005000 0xd8>; + ranges = <0 0 0xff800000 0x0800000 + 1 0 0x60000000 0x0001000 + 2 0 0x70000000 0x4000000>; + + flash@0,0 { + compatible = "intel,PC28F640P30T85", "cfi-flash"; + reg = <0 0 0x800000>; + bank-width = <2>; + device-width = <1>; + }; + + display@2,0 { + device_type = "display"; + compatible = "fujitsu,MB86277", "fujitsu,mint"; + reg = <2 0 0x4000000>; + fujitsu,sh3; + little-endian; + /* filled by u-boot */ + address = <0>; + depth = <0>; + width = <0>; + height = <0>; + linebytes = <0>; + /* linux,opened; - added by uboot */ + }; + }; + + pci0: pci@e0008500 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci"; + reg = <0xe0008500 0x100>; + ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 + 0x42000000 0 0x80000000 0x80000000 0 0x10000000 + 0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>; + interrupts = <66 8>; + interrupt-parent = <&ipic>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = </* miniPCI0 IDSEL 0x14 AD20 */ + 0xa000 0 0 1 &ipic 18 8 + 0xa000 0 0 2 &ipic 19 8 + + /* PCI1 IDSEL 0x15 AD21 */ + 0xa800 0 0 1 &ipic 19 8 + 0xa800 0 0 2 &ipic 20 8 + 0xa800 0 0 3 &ipic 21 8 + 0xa800 0 0 4 &ipic 18 8>; + /* filled by u-boot */ + bus-range = <0 0>; + clock-frequency = <0>; + }; +};
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig new file +1092 -0
1,092 lines not on this page · raw message
arch/powerpc/platforms/83xx/Kconfig +8 -0
@@ -58,6 +58,14 @@ config MPC836x_MDS help This option enables support for the MPC836x MDS Processor Board. +config MPC836x_RDK + bool "Freescale/Logic MPC836x RDK" + select DEFAULT_UIMAGE + select QUICC_ENGINE + help + This option enables support for the MPC836x RDK Processor Board, + also known as ZOOM PowerQUICC Kit. + config MPC837x_MDS bool "Freescale MPC837x MDS" select DEFAULT_UIMAGE
arch/powerpc/platforms/83xx/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o +obj-$(CONFIG_MPC836x_RDK) += mpc836x_rdk.o obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o obj-$(CONFIG_SBC834x) += sbc834x.o
arch/powerpc/platforms/83xx/mpc836x_rdk.c new file +106 -0
106 lines not on this page · raw message
Signature · 1 line
1.5.5
Re: [PATCH 5/5] [POWERPC] 83xx: new board support: MPC8360E-RDK
Quoted 4 lines · Anton Vorontsov
This is patch adds board file, device tree, and defconfig for the new
board, made by Freescale Semiconductor Inc. and Logic Product Development.arch/powerpc/platforms/83xx/mpc836x_rdk.c | 106 +++
I don't see anything exotic in here. This can be merged with one of the other non-exotic mpc83xx board files. The dts parsing takes care of the differences.
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Quoted 1,653 lines
5 files changed, 1601 insertions(+), 0 deletions(-)create mode 100644
arch/powerpc/boot/dts/mpc836x_rdk.dtscreate mode 100644arch/powerpc/configs/83xx/mpc836x_rdk_defconfigcreate mode 100644arch/powerpc/platforms/83xx/mpc836x_rdk.cdiff --git
a/arch/powerpc/boot/dts/mpc836x_rdk.dtsb/arch/powerpc/boot/dts/mpc836x_rdk.dtsnew file mode 100644
index 0000000..39a7dcb
---/dev/null
+++b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -0,0 +1,394 @@
+/*
+ * MPC8360E RDK Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ * Copyright 2007-2008 MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {+ #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8360rdk"; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + pci0 = &pci0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8360@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + /* filled by u-boot */ + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + }; + + memory { + device_type = "memory"; + /* filled by u-boot */ + reg = <0 0>; + }; + + soc@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "fsl,mpc8360-immr", "fsl,immr", "fsl,soc", + "simple-bus"; + ranges = <0 0xe0000000 0x200000>; + reg = <0xe0000000 0x200>; + /* filled by u-boot */ + bus-frequency = <0>; + + wdt@200 { + compatible = "mpc83xx_wdt"; + reg = <0x200 0x100>; + }; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 8>; + interrupt-parent = <&ipic>; + dfsrr; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <16 8>; + interrupt-parent = <&ipic>; + dfsrr; + }; + + serial0: serial@4500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4500 0x100>; + interrupts = <9 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + serial1: serial@4600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + interrupts = <10 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + crypto@30000 { + compatible = "fsl,sec2-crypto"; + reg = <0x30000 0x10000>; + interrupts = <11 8>; + interrupt-parent = <&ipic>; + num-channels = <4>; + channel-fifo-len = <24>; + exec-units-mask = <0x7e>; + /* + * desc mask is for rev1.x, we need runtime fixup + * for >=2.x + */ + descriptor-types-mask = <0x1010ebf>; + }; + + ipic: interrupt-controller@700 { + #address-cells = <0>; + #interrupt-cells = <2>; + compatible = "fsl,pq2pro-pic", "fsl,ipic"; + interrupt-controller; + reg = <0x700 0x100>; + }; + + qe_pio_b: gpio-controller@1418 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1418 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; + + qe@100000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "qe"; + compatible = "fsl,qe", "simple-bus"; + ranges = <0 0x100000 0x100000>; + reg = <0x100000 0x480>; + /* filled by u-boot */ + clock-frequency = <0>; + bus-frequency = <0>; + brg-frequency = <0>; + + muram@10000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,qe-muram", "fsl,cpm-muram"; + ranges = <0 0x10000 0xc000>; + + data-only@0 { + compatible = "fsl,qe-muram-data", + "fsl,cpm-muram-data"; + reg = <0 0xc000>; + }; + }; + + timer@440 { + compatible = "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + spi@4c0 { + cell-index = <0>; + compatible = "fsl,spi"; + reg = <0x4c0 0x40>; + interrupts = <2>; + interrupt-parent = <&qeic>; + mode = "cpu-qe"; + }; + + spi@500 { + cell-index = <1>; + compatible = "fsl,spi"; + reg = <0x500 0x40>; + interrupts = <1>; + interrupt-parent = <&qeic>; + mode = "cpu-qe"; + }; + + enet0: ucc@2000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <1>; + reg = <0x2000 0x200>; + interrupts = <32>; + interrupt-parent = <&qeic>; + rx-clock-name = "none"; + tx-clock-name = "clk9"; + phy-handle = <&phy2>; + phy-connection-type = "rgmii-rxid"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet1: ucc@3000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <2>; + reg = <0x3000 0x200>; + interrupts = <33>; + interrupt-parent = <&qeic>; + rx-clock-name = "none"; + tx-clock-name = "clk4"; + phy-handle = <&phy4>; + phy-connection-type = "rgmii-rxid"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet2: ucc@2600 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <7>; + reg = <0x2600 0x200>; + interrupts = <42>; + interrupt-parent = <&qeic>; + rx-clock-name = "clk20"; + tx-clock-name = "clk19"; + phy-handle = <&phy1>; + phy-connection-type = "mii"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + enet3: ucc@3200 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <4>; + reg = <0x3200 0x200>; + interrupts = <35>; + interrupt-parent = <&qeic>; + rx-clock-name = "clk8"; + tx-clock-name = "clk7"; + phy-handle = <&phy3>; + phy-connection-type = "mii"; + /* filled by u-boot */ + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + mdio@2120 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,ucc-mdio"; + reg = <0x2120 0x18>; + + phy1: ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "national,DP83848VV"; + reg = <1>; + }; + + phy2: ethernet-phy@2 { + device_type = "ethernet-phy"; + compatible = "broadcom,BCM5481UA2KMLG"; + reg = <2>; + }; + + phy3: ethernet-phy@3 { + device_type = "ethernet-phy"; + compatible = "national,DP83848VV"; + reg = <3>; + }; + + phy4: ethernet-phy@4 { + device_type = "ethernet-phy"; + compatible = "broadcom,BCM5481UA2KMLG"; + reg = <4>; + }; + }; + + serial2: ucc@2400 { + device_type = "serial"; + compatible = "ucc_uart"; + reg = <0x2400 0x200>; + cell-index = <5>; + port-number = <0>; + rx-clock-name = "brg7"; + tx-clock-name = "brg8"; + interrupts = <40>; + interrupt-parent = <&qeic>; + soft-uart; + }; + + serial3: ucc@3400 { + device_type = "serial"; + compatible = "ucc_uart"; + reg = <0x3400 0x200>; + cell-index = <6>; + port-number = <1>; + rx-clock-name = "brg13"; + tx-clock-name = "brg14"; + interrupts = <41>; + interrupt-parent = <&qeic>; + soft-uart; + }; + + qeic: interrupt-controller@80 { + #address-cells = <0>; + #interrupt-cells = <1>; + compatible = "fsl,qe-ic"; + interrupt-controller; + reg = <0x80 0x80>; + big-endian; + interrupts = <32 8 33 8>; + interrupt-parent = <&ipic>; + }; + }; + }; + + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus", + "simple-bus"; + reg = <0xe0005000 0xd8>; + ranges = <0 0 0xff800000 0x0800000 + 1 0 0x60000000 0x0001000 + 2 0 0x70000000 0x4000000>; + + flash@0,0 { + compatible = "intel,PC28F640P30T85", "cfi-flash"; + reg = <0 0 0x800000>; + bank-width = <2>; + device-width = <1>; + }; + + display@2,0 { + device_type = "display"; + compatible = "fujitsu,MB86277", "fujitsu,mint"; + reg = <2 0 0x4000000>; + fujitsu,sh3; + little-endian; + /* filled by u-boot */ + address = <0>; + depth = <0>; + width = <0>; + height = <0>; + linebytes = <0>; + /* linux,opened; - added by uboot */ + }; + }; + + pci0: pci@e0008500 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci"; + reg = <0xe0008500 0x100>; + ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 + 0x42000000 0 0x80000000 0x80000000 0 0x10000000 + 0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>; + interrupts = <66 8>; + interrupt-parent = <&ipic>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = </* miniPCI0 IDSEL 0x14 AD20 */ + 0xa000 0 0 1 &ipic 18 8 + 0xa000 0 0 2 &ipic 19 8 + + /* PCI1 IDSEL 0x15 AD21 */ + 0xa800 0 0 1 &ipic 19 8 + 0xa800 0 0 2 &ipic 20 8 + 0xa800 0 0 3 &ipic 21 8 + 0xa800 0 0 4 &ipic 18 8>; + /* filled by u-boot */ + bus-range = <0 0>; + clock-frequency = <0>;+ };
+};
diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig new file mode 100644
index 0000000..f8bde7b
---/dev/null
+++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
@@ -0,0 +1,1092 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.25-rc9
+# Fri Apr 18 22:25:18 2008
+#
+#CONFIG_PPC64is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+#CONFIG_PPC_85xxis not set
+#CONFIG_PPC_8xxis not set
+#CONFIG_40xis not set
+#CONFIG_44xis not set
+#CONFIG_E200is not set
+CONFIG_PPC_FPU=y
+#CONFIG_FSL_EMB_PERFMONis not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+#CONFIG_PPC_MM_SLICESis not set
+#CONFIG_SMPis not set
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+#CONFIG_HAVE_SETUP_PER_CPU_AREAis not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+#CONFIG_ARCH_NO_VIRT_TO_BUSis not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+#CONFIG_GENERIC_TBSYNCis not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+#CONFIG_PPC_DCR_NATIVEis not set
+#CONFIG_PPC_DCR_MMIOis not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+#CONFIG_POSIX_MQUEUEis not set
+#CONFIG_BSD_PROCESS_ACCTis not set
+#CONFIG_TASKSTATSis not set
+#CONFIG_AUDITis not set
+#CONFIG_IKCONFIGis not set
+CONFIG_LOG_BUF_SHIFT=14
+#CONFIG_CGROUPSis not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+#CONFIG_RT_GROUP_SCHEDis not set
+CONFIG_USER_SCHED=y
+#CONFIG_CGROUP_SCHEDis not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+#CONFIG_RELAYis not set
+#CONFIG_NAMESPACESis not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+#CONFIG_CC_OPTIMIZE_FOR_SIZEis not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+#CONFIG_KALLSYMSis not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+#CONFIG_EPOLLis not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+#CONFIG_SLABis not set
+CONFIG_SLUB=y
+#CONFIG_SLOBis not set
+#CONFIG_PROFILINGis not set
+#CONFIG_MARKERSis not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+#CONFIG_TINY_SHMEMis not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+#CONFIG_MODULE_FORCE_UNLOADis not set
+#CONFIG_MODVERSIONSis not set
+#CONFIG_MODULE_SRCVERSION_ALLis not set
+#CONFIG_KMODis not set
+CONFIG_BLOCK=y
+#CONFIG_LBDis not set
+#CONFIG_BLK_DEV_IO_TRACEis not set
+#CONFIG_LSFis not set
+#CONFIG_BLK_DEV_BSGis not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+#CONFIG_DEFAULT_DEADLINEis not set
+#CONFIG_DEFAULT_CFQis not set
+#CONFIG_DEFAULT_NOOPis not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+#CONFIG_PPC_MULTIPLATFORMis not set
+#CONFIG_PPC_82xxis not set
+CONFIG_PPC_83xx=y
+#CONFIG_PPC_86xxis not set
+#CONFIG_PPC_MPC512xis not set
+#CONFIG_PPC_MPC5121is not set
+#CONFIG_PPC_CELLis not set
+#CONFIG_PPC_CELL_NATIVEis not set
+#CONFIG_PQ2ADSis not set
+CONFIG_MPC83xx=y
+#CONFIG_MPC831x_RDBis not set
+#CONFIG_MPC832x_MDSis not set
+#CONFIG_MPC832x_RDBis not set
+#CONFIG_MPC834x_MDSis not set
+#CONFIG_MPC834x_ITXis not set
+#CONFIG_MPC836x_MDSis not set
+CONFIG_MPC836x_RDK=y
+#CONFIG_MPC837x_MDSis not set
+#CONFIG_MPC837x_RDBis not set
+#CONFIG_SBC834xis not set
+CONFIG_IPIC=y
+#CONFIG_MPICis not set
+#CONFIG_MPIC_WEIRDis not set
+#CONFIG_PPC_I8259is not set
+#CONFIG_PPC_RTASis not set
+#CONFIG_MMIO_NVRAMis not set
+#CONFIG_PPC_MPC106is not set
+#CONFIG_PPC_970_NAPis not set
+#CONFIG_PPC_INDIRECT_IOis not set
+#CONFIG_GENERIC_IOMAPis not set
+#CONFIG_CPU_FREQis not set
+CONFIG_QUICC_ENGINE=y
+#CONFIG_FSL_ULI1575is not set
+
+#
+# Kernel options
+#
+#CONFIG_HIGHMEMis not set
+#CONFIG_TICK_ONESHOTis not set
+#CONFIG_NO_HZis not set
+#CONFIG_HIGH_RES_TIMERSis not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+#CONFIG_HZ_100is not set
+CONFIG_HZ_250=y
+#CONFIG_HZ_300is not set
+#CONFIG_HZ_1000is not set
+CONFIG_HZ=250
+#CONFIG_SCHED_HRTICKis not set
+CONFIG_PREEMPT_NONE=y
+#CONFIG_PREEMPT_VOLUNTARYis not set
+#CONFIG_PREEMPTis not set
+CONFIG_BINFMT_ELF=y
+#CONFIG_BINFMT_MISCis not set
+#CONFIG_IOMMU_HELPERis not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+#CONFIG_DISCONTIGMEM_MANUALis not set
+#CONFIG_SPARSEMEM_MANUALis not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+#CONFIG_SPARSEMEM_STATICis not set
+#CONFIG_SPARSEMEM_VMEMMAP_ENABLEis not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+#CONFIG_RESOURCES_64BITis not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+#CONFIG_CMDLINE_BOOLis not set
+#CONFIG_PMis not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+#CONFIG_PCIEPORTBUSis not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+#CONFIG_PCI_MSIis not set
+CONFIG_PCI_LEGACY=y
+#CONFIG_PCCARDis not set
+#CONFIG_HOTPLUG_PCIis not set
+
+#
+# Advanced setup
+#
+#CONFIG_ADVANCED_OPTIONSis not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0xc0000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+#CONFIG_PACKET_MMAPis not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+#CONFIG_XFRM_USERis not set
+#CONFIG_XFRM_SUB_POLICYis not set
+#CONFIG_XFRM_MIGRATEis not set
+#CONFIG_XFRM_STATISTICSis not set
+#CONFIG_NET_KEYis not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+#CONFIG_IP_ADVANCED_ROUTERis not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+#CONFIG_IP_PNP_RARPis not set
+#CONFIG_NET_IPIPis not set
+#CONFIG_NET_IPGREis not set
+#CONFIG_IP_MROUTEis not set
+#CONFIG_ARPDis not set
+CONFIG_SYN_COOKIES=y
+#CONFIG_INET_AHis not set
+#CONFIG_INET_ESPis not set
+#CONFIG_INET_IPCOMPis not set
+#CONFIG_INET_XFRM_TUNNELis not set
+#CONFIG_INET_TUNNELis not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+#CONFIG_INET_LROis not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+#CONFIG_TCP_CONG_ADVANCEDis not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+#CONFIG_TCP_MD5SIGis not set
+#CONFIG_IPV6is not set
+#CONFIG_INET6_XFRM_TUNNELis not set
+#CONFIG_INET6_TUNNELis not set
+#CONFIG_NETWORK_SECMARKis not set
+#CONFIG_NETFILTERis not set
+#CONFIG_IP_DCCPis not set
+#CONFIG_IP_SCTPis not set
+#CONFIG_TIPCis not set
+#CONFIG_ATMis not set
+#CONFIG_BRIDGEis not set
+#CONFIG_VLAN_8021Qis not set
+#CONFIG_DECNETis not set
+#CONFIG_LLC2is not set
+#CONFIG_IPXis not set
+#CONFIG_ATALKis not set
+#CONFIG_X25is not set
+#CONFIG_LAPBis not set
+#CONFIG_ECONETis not set
+#CONFIG_WAN_ROUTERis not set
+#CONFIG_NET_SCHEDis not set
+
+#
+# Network testing
+#
+#CONFIG_NET_PKTGENis not set
+#CONFIG_HAMRADIOis not set
+#CONFIG_CANis not set
+#CONFIG_IRDAis not set
+#CONFIG_BTis not set
+#CONFIG_AF_RXRPCis not set
+
+#
+# Wireless
+#
+#CONFIG_CFG80211is not set
+#CONFIG_WIRELESS_EXTis not set
+#CONFIG_MAC80211is not set
+#CONFIG_IEEE80211is not set
+#CONFIG_RFKILLis not set
+#CONFIG_NET_9Pis not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+#CONFIG_SYS_HYPERVISORis not set
+#CONFIG_CONNECTORis not set
+CONFIG_MTD=y
+#CONFIG_MTD_DEBUGis not set
+#CONFIG_MTD_CONCATis not set
+CONFIG_MTD_PARTITIONS=y
+#CONFIG_MTD_REDBOOT_PARTSis not set
+CONFIG_MTD_CMDLINE_PARTS=y
+#CONFIG_MTD_OF_PARTSis not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+#CONFIG_FTLis not set
+#CONFIG_NFTLis not set
+#CONFIG_INFTLis not set
+#CONFIG_RFD_FTLis not set
+#CONFIG_SSFDCis not set
+#CONFIG_MTD_OOPSis not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+#CONFIG_MTD_JEDECPROBEis not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+#CONFIG_MTD_CFI_BE_BYTE_SWAPis not set
+#CONFIG_MTD_CFI_LE_BYTE_SWAPis not set
+#CONFIG_MTD_CFI_GEOMETRYis not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+#CONFIG_MTD_MAP_BANK_WIDTH_8is not set
+#CONFIG_MTD_MAP_BANK_WIDTH_16is not set
+#CONFIG_MTD_MAP_BANK_WIDTH_32is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+#CONFIG_MTD_CFI_I4is not set
+#CONFIG_MTD_CFI_I8is not set
+#CONFIG_MTD_OTPis not set
+CONFIG_MTD_CFI_INTELEXT=y
+#CONFIG_MTD_CFI_AMDSTDis not set
+#CONFIG_MTD_CFI_STAAis not set
+CONFIG_MTD_CFI_UTIL=y
+#CONFIG_MTD_RAMis not set
+#CONFIG_MTD_ROMis not set
+#CONFIG_MTD_ABSENTis not set
+
+#
+# Mapping drivers for chip access
+#
+#CONFIG_MTD_COMPLEX_MAPPINGSis not set
+#CONFIG_MTD_PHYSMAPis not set
+CONFIG_MTD_PHYSMAP_OF=y
+#CONFIG_MTD_INTEL_VR_NORis not set
+#CONFIG_MTD_PLATRAMis not set
+
+#
+# Self-contained MTD device drivers
+#
+#CONFIG_MTD_PMC551is not set
+#CONFIG_MTD_DATAFLASHis not set
+#CONFIG_MTD_M25P80is not set
+#CONFIG_MTD_SLRAMis not set
+#CONFIG_MTD_PHRAMis not set
+#CONFIG_MTD_MTDRAMis not set
+#CONFIG_MTD_BLOCK2MTDis not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+#CONFIG_MTD_DOC2000is not set
+#CONFIG_MTD_DOC2001is not set
+#CONFIG_MTD_DOC2001PLUSis not set
+#CONFIG_MTD_NANDis not set
+#CONFIG_MTD_ONENANDis not set
+
+#
+# UBI - Unsorted block images
+#
+#CONFIG_MTD_UBIis not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+#CONFIG_PARPORTis not set
+CONFIG_BLK_DEV=y
+#CONFIG_BLK_DEV_FDis not set
+#CONFIG_BLK_CPQ_DAis not set
+#CONFIG_BLK_CPQ_CISS_DAis not set
+#CONFIG_BLK_DEV_DAC960is not set
+#CONFIG_BLK_DEV_UMEMis not set
+#CONFIG_BLK_DEV_COW_COMMONis not set
+CONFIG_BLK_DEV_LOOP=y
+#CONFIG_BLK_DEV_CRYPTOLOOPis not set
+#CONFIG_BLK_DEV_NBDis not set
+#CONFIG_BLK_DEV_SX8is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+#CONFIG_BLK_DEV_XIPis not set
+#CONFIG_CDROM_PKTCDVDis not set
+#CONFIG_ATA_OVER_ETHis not set
+CONFIG_MISC_DEVICES=y
+#CONFIG_PHANTOMis not set
+#CONFIG_EEPROM_93CX6is not set
+#CONFIG_SGI_IOC4is not set
+#CONFIG_TIFM_COREis not set
+#CONFIG_ENCLOSURE_SERVICESis not set
+CONFIG_HAVE_IDE=y
+#CONFIG_IDEis not set
+
+#
+# SCSI device support
+#
+#CONFIG_RAID_ATTRSis not set
+#CONFIG_SCSIis not set
+#CONFIG_SCSI_DMAis not set
+#CONFIG_SCSI_NETLINKis not set
+#CONFIG_ATAis not set
+#CONFIG_MDis not set
+#CONFIG_FUSIONis not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+#CONFIG_FIREWIREis not set
+#CONFIG_IEEE1394is not set
+#CONFIG_I2Ois not set
+#CONFIG_MACINTOSH_DRIVERSis not set
+CONFIG_NETDEVICES=y
+#CONFIG_NETDEVICES_MULTIQUEUEis not set
+#CONFIG_DUMMYis not set
+#CONFIG_BONDINGis not set
+#CONFIG_MACVLANis not set
+#CONFIG_EQUALIZERis not set
+#CONFIG_TUNis not set
+#CONFIG_VETHis not set
+#CONFIG_ARCNETis not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+#CONFIG_MARVELL_PHYis not set
+#CONFIG_DAVICOM_PHYis not set
+#CONFIG_QSEMI_PHYis not set
+#CONFIG_LXT_PHYis not set
+#CONFIG_CICADA_PHYis not set
+#CONFIG_VITESSE_PHYis not set
+#CONFIG_SMSC_PHYis not set
+CONFIG_BROADCOM_PHY=y
+#CONFIG_ICPLUS_PHYis not set
+#CONFIG_REALTEK_PHYis not set
+#CONFIG_FIXED_PHYis not set
+#CONFIG_MDIO_BITBANGis not set
+#CONFIG_NET_ETHERNETis not set
+CONFIG_NETDEV_1000=y
+#CONFIG_ACENICis not set
+#CONFIG_DL2Kis not set
+#CONFIG_E1000is not set
+#CONFIG_E1000Eis not set
+#CONFIG_E1000E_ENABLEDis not set
+#CONFIG_IP1000is not set
+#CONFIG_IGBis not set
+#CONFIG_NS83820is not set
+#CONFIG_HAMACHIis not set
+#CONFIG_YELLOWFINis not set
+#CONFIG_R8169is not set
+#CONFIG_SIS190is not set
+#CONFIG_SKGEis not set
+#CONFIG_SKY2is not set
+#CONFIG_SK98LINis not set
+#CONFIG_VIA_VELOCITYis not set
+#CONFIG_TIGON3is not set
+#CONFIG_BNX2is not set
+#CONFIG_GIANFARis not set
+CONFIG_UCC_GETH=y
+CONFIG_UGETH_NAPI=y
+#CONFIG_UGETH_MAGIC_PACKETis not set
+#CONFIG_UGETH_FILTERINGis not set
+#CONFIG_UGETH_TX_ON_DEMANDis not set
+#CONFIG_QLA3XXXis not set
+#CONFIG_ATL1is not set
+#CONFIG_NETDEV_10000is not set
+#CONFIG_TRis not set
+
+#
+# Wireless LAN
+#
+#CONFIG_WLAN_PRE80211is not set
+#CONFIG_WLAN_80211is not set
+#CONFIG_WANis not set
+#CONFIG_FDDIis not set
+#CONFIG_HIPPIis not set
+#CONFIG_PPPis not set
+#CONFIG_SLIPis not set
+#CONFIG_NETCONSOLEis not set
+#CONFIG_NETPOLLis not set
+#CONFIG_NET_POLL_CONTROLLERis not set
+#CONFIG_ISDNis not set
+#CONFIG_PHONEis not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+#CONFIG_INPUT_FF_MEMLESSis not set
+#CONFIG_INPUT_POLLDEVis not set
+
+#
+# Userland interfaces
+#
+#CONFIG_INPUT_MOUSEDEVis not set
+#CONFIG_INPUT_JOYDEVis not set
+#CONFIG_INPUT_EVDEVis not set
+#CONFIG_INPUT_EVBUGis not set
+
+#
+# Input Device Drivers
+#
+#CONFIG_INPUT_KEYBOARDis not set
+#CONFIG_INPUT_MOUSEis not set
+#CONFIG_INPUT_JOYSTICKis not set
+#CONFIG_INPUT_TABLETis not set
+#CONFIG_INPUT_TOUCHSCREENis not set
+#CONFIG_INPUT_MISCis not set
+
+#
+# Hardware I/O ports
+#
+#CONFIG_SERIOis not set
+#CONFIG_GAMEPORTis not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+#CONFIG_VT_HW_CONSOLE_BINDINGis not set
+#CONFIG_SERIAL_NONSTANDARDis not set
+#CONFIG_NOZOMIis not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+#CONFIG_SERIAL_8250_EXTENDEDis not set
+
+#
+# Non-8250 serial port support
+#
+#CONFIG_SERIAL_UARTLITEis not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+#CONFIG_SERIAL_JSMis not set
+#CONFIG_SERIAL_OF_PLATFORMis not set
+CONFIG_SERIAL_QE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+#CONFIG_IPMI_HANDLERis not set
+CONFIG_HW_RANDOM=y
+#CONFIG_NVRAMis not set
+#CONFIG_GEN_RTCis not set
+#CONFIG_R3964is not set
+#CONFIG_APPLICOMis not set
+#CONFIG_RAW_DRIVERis not set
+#CONFIG_TCG_TPMis not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+#CONFIG_I2C_ALGOBITis not set
+#CONFIG_I2C_ALGOPCFis not set
+#CONFIG_I2C_ALGOPCAis not set
+
+#
+# I2C Hardware Bus support
+#
+#CONFIG_I2C_ALI1535is not set
+#CONFIG_I2C_ALI1563is not set
+#CONFIG_I2C_ALI15X3is not set
+#CONFIG_I2C_AMD756is not set
+#CONFIG_I2C_AMD8111is not set
+#CONFIG_I2C_GPIOis not set
+#CONFIG_I2C_I801is not set
+#CONFIG_I2C_I810is not set
+#CONFIG_I2C_PIIX4is not set
+CONFIG_I2C_MPC=y
+#CONFIG_I2C_NFORCE2is not set
+#CONFIG_I2C_OCORESis not set
+#CONFIG_I2C_PARPORT_LIGHTis not set
+#CONFIG_I2C_PROSAVAGEis not set
+#CONFIG_I2C_SAVAGE4is not set
+#CONFIG_I2C_SIMTECis not set
+#CONFIG_I2C_SIS5595is not set
+#CONFIG_I2C_SIS630is not set
+#CONFIG_I2C_SIS96Xis not set
+#CONFIG_I2C_TAOS_EVMis not set
+#CONFIG_I2C_STUBis not set
+#CONFIG_I2C_VIAis not set
+#CONFIG_I2C_VIAPROis not set
+#CONFIG_I2C_VOODOO3is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+#CONFIG_DS1682is not set
+#CONFIG_SENSORS_EEPROMis not set
+#CONFIG_SENSORS_PCF8574is not set
+#CONFIG_PCF8575is not set
+#CONFIG_SENSORS_PCF8591is not set
+#CONFIG_TPS65010is not set
+#CONFIG_SENSORS_MAX6875is not set
+#CONFIG_SENSORS_TSL2550is not set
+#CONFIG_I2C_DEBUG_COREis not set
+#CONFIG_I2C_DEBUG_ALGOis not set
+#CONFIG_I2C_DEBUG_BUSis not set
+#CONFIG_I2C_DEBUG_CHIPis not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MPC83xx=y
+
+#
+# SPI Protocol Masters
+#
+#CONFIG_SPI_AT25is not set
+CONFIG_SPI_SPIDEV=y
+#CONFIG_SPI_TLE62X0is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+
+#
+# On-chip GPIOs:
+#
+CONFIG_GPIO_QE=y
+
+#
+# I2C GPIO expanders:
+#
+#CONFIG_GPIO_PCA953Xis not set
+#CONFIG_GPIO_PCF857Xis not set
+
+#
+# SPI GPIO expanders:
+#
+#CONFIG_GPIO_MCP23S08is not set
+#CONFIG_W1is not set
+#CONFIG_POWER_SUPPLYis not set
+#CONFIG_HWMONis not set
+#CONFIG_THERMALis not set
+CONFIG_WATCHDOG=y
+#CONFIG_WATCHDOG_NOWAYOUTis not set
+
+#
+# Watchdog Device Drivers
+#
+#CONFIG_SOFT_WATCHDOGis not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+#CONFIG_PCIPCWATCHDOGis not set
+#CONFIG_WDTPCIis not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+#CONFIG_SSBis not set
+
+#
+# Multifunction device drivers
+#
+#CONFIG_MFD_SM501is not set
+
+#
+# Multimedia devices
+#
+#CONFIG_VIDEO_DEVis not set
+#CONFIG_DVB_COREis not set
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+#CONFIG_AGPis not set
+#CONFIG_DRMis not set
+#CONFIG_VGASTATEis not set
+#CONFIG_VIDEO_OUTPUT_CONTROLis not set
+CONFIG_FB=y
+#CONFIG_FIRMWARE_EDIDis not set
+#CONFIG_FB_DDCis not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+#CONFIG_FB_CFB_REV_PIXELS_IN_BYTEis not set
+#CONFIG_FB_SYS_FILLRECTis not set
+#CONFIG_FB_SYS_COPYAREAis not set
+#CONFIG_FB_SYS_IMAGEBLITis not set
+#CONFIG_FB_SYS_FOPSis not set
+CONFIG_FB_DEFERRED_IO=y
+#CONFIG_FB_SVGALIBis not set
+CONFIG_FB_MACMODES=y
+#CONFIG_FB_BACKLIGHTis not set
+#CONFIG_FB_MODE_HELPERSis not set
+#CONFIG_FB_TILEBLITTINGis not set
+
+#
+# Frame buffer hardware drivers
+#
+#CONFIG_FB_CIRRUSis not set
+#CONFIG_FB_PM2is not set
+#CONFIG_FB_CYBER2000is not set
+CONFIG_FB_OF=y
+#CONFIG_FB_CT65550is not set
+#CONFIG_FB_ASILIANTis not set
+#CONFIG_FB_IMSTTis not set
+#CONFIG_FB_VGA16is not set
+#CONFIG_FB_S1D13XXXis not set
+#CONFIG_FB_NVIDIAis not set
+#CONFIG_FB_RIVAis not set
+#CONFIG_FB_MATROXis not set
+#CONFIG_FB_RADEONis not set
+#CONFIG_FB_ATY128is not set
+#CONFIG_FB_ATYis not set
+#CONFIG_FB_S3is not set
+#CONFIG_FB_SAVAGEis not set
+#CONFIG_FB_SISis not set
+#CONFIG_FB_NEOMAGICis not set
+#CONFIG_FB_KYROis not set
+#CONFIG_FB_3DFXis not set
+#CONFIG_FB_VOODOO1is not set
+#CONFIG_FB_VT8623is not set
+#CONFIG_FB_TRIDENTis not set
+#CONFIG_FB_ARKis not set
+#CONFIG_FB_PM3is not set
+#CONFIG_FB_IBM_GXT4500is not set
+#CONFIG_FB_VIRTUALis not set
+#CONFIG_BACKLIGHT_LCD_SUPPORTis not set
+
+#
+# Display device support
+#
+#CONFIG_DISPLAY_SUPPORTis not set
+
+#
+# Console display driver support
+#
+#CONFIG_VGA_CONSOLEis not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+#CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARYis not set
+#CONFIG_FRAMEBUFFER_CONSOLE_ROTATIONis not set
+#CONFIG_FONTSis not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+#CONFIG_LOGO_LINUX_MONOis not set
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+#CONFIG_SOUNDis not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+#CONFIG_HID_DEBUGis not set
+#CONFIG_HIDRAWis not set
+#CONFIG_USB_SUPPORTis not set
+#CONFIG_MMCis not set
+#CONFIG_MEMSTICKis not set
+#CONFIG_NEW_LEDSis not set
+#CONFIG_INFINIBANDis not set
+#CONFIG_EDACis not set
+#CONFIG_RTC_CLASSis not set
+#CONFIG_DMADEVICESis not set
+
+#
+# Userspace I/O
+#
+#CONFIG_UIOis not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+#CONFIG_EXT2_FS_XATTRis not set
+#CONFIG_EXT2_FS_XIPis not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+#CONFIG_EXT3_FS_POSIX_ACLis not set
+#CONFIG_EXT3_FS_SECURITYis not set
+#CONFIG_EXT4DEV_FSis not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+#CONFIG_REISERFS_FSis not set
+#CONFIG_JFS_FSis not set
+#CONFIG_FS_POSIX_ACLis not set
+#CONFIG_XFS_FSis not set
+#CONFIG_GFS2_FSis not set
+#CONFIG_OCFS2_FSis not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+#CONFIG_QUOTAis not set
+#CONFIG_AUTOFS_FSis not set
+#CONFIG_AUTOFS4_FSis not set
+#CONFIG_FUSE_FSis not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+#CONFIG_ISO9660_FSis not set
+#CONFIG_UDF_FSis not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+#CONFIG_MSDOS_FSis not set
+#CONFIG_VFAT_FSis not set
+#CONFIG_NTFS_FSis not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+#CONFIG_TMPFS_POSIX_ACLis not set
+#CONFIG_HUGETLB_PAGEis not set
+#CONFIG_CONFIGFS_FSis not set
+
+#
+# Miscellaneous filesystems
+#
+#CONFIG_ADFS_FSis not set
+#CONFIG_AFFS_FSis not set
+#CONFIG_HFS_FSis not set
+#CONFIG_HFSPLUS_FSis not set
+#CONFIG_BEFS_FSis not set
+#CONFIG_BFS_FSis not set
+#CONFIG_EFS_FSis not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+#CONFIG_JFFS2_FS_WBUF_VERIFYis not set
+#CONFIG_JFFS2_SUMMARYis not set
+#CONFIG_JFFS2_FS_XATTRis not set
+#CONFIG_JFFS2_COMPRESSION_OPTIONSis not set
+CONFIG_JFFS2_ZLIB=y
+#CONFIG_JFFS2_LZOis not set
+CONFIG_JFFS2_RTIME=y
+#CONFIG_JFFS2_RUBINis not set
+#CONFIG_CRAMFSis not set
+#CONFIG_VXFS_FSis not set
+#CONFIG_MINIX_FSis not set
+#CONFIG_HPFS_FSis not set
+#CONFIG_QNX4FS_FSis not set
+#CONFIG_ROMFS_FSis not set
+#CONFIG_SYSV_FSis not set
+#CONFIG_UFS_FSis not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+#CONFIG_NFS_V3_ACLis not set
+CONFIG_NFS_V4=y
+#CONFIG_NFS_DIRECTIOis not set
+#CONFIG_NFSDis not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+#CONFIG_SUNRPC_BIND34is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+#CONFIG_RPCSEC_GSS_SPKM3is not set
+#CONFIG_SMB_FSis not set
+#CONFIG_CIFSis not set
+#CONFIG_NCP_FSis not set
+#CONFIG_CODA_FSis not set
+#CONFIG_AFS_FSis not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+#CONFIG_ACORN_PARTITIONis not set
+#CONFIG_OSF_PARTITIONis not set
+#CONFIG_AMIGA_PARTITIONis not set
+#CONFIG_ATARI_PARTITIONis not set
+#CONFIG_MAC_PARTITIONis not set
+#CONFIG_MSDOS_PARTITIONis not set
+#CONFIG_LDM_PARTITIONis not set
+#CONFIG_SGI_PARTITIONis not set
+#CONFIG_ULTRIX_PARTITIONis not set
+#CONFIG_SUN_PARTITIONis not set
+#CONFIG_KARMA_PARTITIONis not set
+#CONFIG_EFI_PARTITIONis not set
+#CONFIG_SYSV68_PARTITIONis not set
+#CONFIG_NLSis not set
+#CONFIG_DLMis not set
+CONFIG_UCC_SLOW=y
+CONFIG_UCC_FAST=y
+CONFIG_UCC=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+#CONFIG_CRC_CCITTis not set
+#CONFIG_CRC16is not set
+#CONFIG_CRC_ITU_Tis not set
+CONFIG_CRC32=y
+#CONFIG_CRC7is not set
+#CONFIG_LIBCRC32Cis not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+#CONFIG_PRINTK_TIMEis not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+#CONFIG_MAGIC_SYSRQis not set
+#CONFIG_UNUSED_SYMBOLSis not set
+#CONFIG_DEBUG_FSis not set
+#CONFIG_HEADERS_CHECKis not set
+#CONFIG_DEBUG_KERNELis not set
+#CONFIG_SLUB_DEBUG_ONis not set
+#CONFIG_SLUB_STATSis not set
+#CONFIG_DEBUG_BUGVERBOSEis not set
+#CONFIG_SAMPLESis not set
+CONFIG_PPC_EARLY_DEBUG=y
+#CONFIG_PPC_EARLY_DEBUG_LPARis not set
+#CONFIG_PPC_EARLY_DEBUG_G5is not set
+#CONFIG_PPC_EARLY_DEBUG_RTAS_PANELis not set
+#CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLEis not set
+#CONFIG_PPC_EARLY_DEBUG_MAPLEis not set
+#CONFIG_PPC_EARLY_DEBUG_ISERIESis not set
+#CONFIG_PPC_EARLY_DEBUG_PAS_REALMODEis not set
+#CONFIG_PPC_EARLY_DEBUG_BEATis not set
+#CONFIG_PPC_EARLY_DEBUG_44xis not set
+#CONFIG_PPC_EARLY_DEBUG_40xis not set
+#CONFIG_PPC_EARLY_DEBUG_CPMis not set
+
+#
+# Security options
+#
+#CONFIG_KEYSis not set
+#CONFIG_SECURITYis not set
+#CONFIG_SECURITY_FILE_CAPABILITIESis not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+#CONFIG_CRYPTO_SEQIVis not set
+CONFIG_CRYPTO_MANAGER=y
+#CONFIG_CRYPTO_HMACis not set
+#CONFIG_CRYPTO_XCBCis not set
+#CONFIG_CRYPTO_NULLis not set
+#CONFIG_CRYPTO_MD4is not set
+CONFIG_CRYPTO_MD5=y
+#CONFIG_CRYPTO_SHA1is not set
+#CONFIG_CRYPTO_SHA256is not set
+#CONFIG_CRYPTO_SHA512is not set
+#CONFIG_CRYPTO_WP512is not set
+#CONFIG_CRYPTO_TGR192is not set
+#CONFIG_CRYPTO_GF128MULis not set
+#CONFIG_CRYPTO_ECBis not set
+CONFIG_CRYPTO_CBC=y
+#CONFIG_CRYPTO_PCBCis not set
+#CONFIG_CRYPTO_LRWis not set
+#CONFIG_CRYPTO_XTSis not set
+#CONFIG_CRYPTO_CTRis not set
+#CONFIG_CRYPTO_GCMis not set
+#CONFIG_CRYPTO_CCMis not set
+#CONFIG_CRYPTO_CRYPTDis not set
+CONFIG_CRYPTO_DES=y
+#CONFIG_CRYPTO_FCRYPTis not set
+#CONFIG_CRYPTO_BLOWFISHis not set
+#CONFIG_CRYPTO_TWOFISHis not set
+#CONFIG_CRYPTO_SERPENTis not set
+#CONFIG_CRYPTO_AESis not set
+#CONFIG_CRYPTO_CAST5is not set
+#CONFIG_CRYPTO_CAST6is not set
+#CONFIG_CRYPTO_TEAis not set
+#CONFIG_CRYPTO_ARC4is not set
+#CONFIG_CRYPTO_KHAZADis not set
+#CONFIG_CRYPTO_ANUBISis not set
+#CONFIG_CRYPTO_SEEDis not set
+#CONFIG_CRYPTO_SALSA20is not set
+#CONFIG_CRYPTO_DEFLATEis not set
+#CONFIG_CRYPTO_MICHAEL_MICis not set
+#CONFIG_CRYPTO_CRC32Cis not set
+#CONFIG_CRYPTO_CAMELLIAis not set
+#CONFIG_CRYPTO_TESTis not set
+#CONFIG_CRYPTO_AUTHENCis not set
+#CONFIG_CRYPTO_LZOis not set
+CONFIG_CRYPTO_HW=y
+#CONFIG_CRYPTO_DEV_HIFN_795Xis not set
+#CONFIG_PPC_CLOCKis not set
+CONFIG_PPC_LIB_RHEAP=y
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 13587e2..a5f72bb 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -58,6 +58,14 @@ configMPC836x_MDS
help
This option enables support for the MPC836x MDS Processor Board.+config
MPC836x_RDK+ bool "Freescale/Logic MPC836x RDK" + select DEFAULT_UIMAGE + select QUICC_ENGINE + help + This option enables support for the MPC836x RDK Processor Board, + also known as ZOOM PowerQUICC Kit. + config MPC837x_MDS bool "Freescale MPC837x MDS" select DEFAULT_UIMAGE diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index 7e6dd3e..1fcda8e 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o +obj-$(CONFIG_MPC836x_RDK) += mpc836x_rdk.o obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o obj-$(CONFIG_SBC834x) += sbc834x.o diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c new file mode 100644 index 0000000..b6c4b38 --- /dev/null +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c @@ -0,0 +1,106 @@ +/* + * MPC8360E-RDK board file. + * + * Copyright (c) 2006 Freescale Semicondutor, Inc. + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/of_platform.h> +#include <linux/io.h> +#include <asm/prom.h> +#include <asm/time.h> +#include <asm/ipic.h> +#include <asm/udbg.h> +#include <asm/qe.h> +#include <asm/qe_ic.h> +#include <sysdev/fsl_soc.h> + +#include "mpc83xx.h" + +static struct of_device_id __initdata mpc836x_rdk_ids[] = { + { .compatible = "simple-bus", }, + {}, +}; + +static int __init mpc836x_rdk_declare_of_platform_devices(void) +{ + return of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL); +} +machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices); + +static void __init mpc836x_rdk_setup_arch(void) +{ +#ifdef CONFIG_PCI + struct device_node *np; +#endif + + if (ppc_md.progress) + ppc_md.progress("mpc836x_rdk_setup_arch()", 0); + +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") + mpc83xx_add_bridge(np); +#endif + +#ifdef CONFIG_QUICC_ENGINE + qe_reset(); +#endif +} + +static void __init mpc836x_rdk_init_IRQ(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); + if (!np) + return; + + ipic_init(np, 0); + + /* + * Initialize the default interrupt mapping priorities, + * in case the boot rom changed something on us. + */ + ipic_set_default_priority(); + of_node_put(np); + +#ifdef CONFIG_QUICC_ENGINE + np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); + if (!np) + return; + + qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); + of_node_put(np); +#endif +} + +/* + * Called very early, MMU is off, device-tree isn't unflattened. + */ +static int __init mpc836x_rdk_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,mpc8360rdk"); +} + +define_machine(mpc836x_rdk) { + .name = "MPC836x RDK", + .probe = mpc836x_rdk_probe, + .setup_arch = mpc836x_rdk_setup_arch, + .init_IRQ = mpc836x_rdk_init_IRQ, + .get_irq = ipic_get_irq, + .restart = mpc83xx_restart, + .time_init = mpc83xx_time_init, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress,+};
--
1.5.5
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Re: [PATCH 5/5] [POWERPC] 83xx: new board support: MPC8360E-RDK
Quoted 10 lines · Grant Likely
Quoted 4 lines · Anton Vorontsov
This is patch adds board file, device tree, and defconfig for the new
board, made by Freescale Semiconductor Inc. and Logic Product Development.arch/powerpc/platforms/83xx/mpc836x_rdk.c | 106 +++I don't see anything exotic in here. This can be merged with one of the other non-exotic mpc83xx board files. The dts parsing takes care of the differences.
Please name the board file in which you think I'll easily merge this indeed non-exotic board.
The only QE boards there are: mpc832x_{rdb,mds} and mpc836x_mds. All of them have board-specific fixups either in the machine_device_initcall()s or setup_arch()s.
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2