* [PATCH] powerpc: #address-cells & #size-cells properties not inherited
From: Mark A. Greer @ 2008-01-03 0:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: David Gibson
From: Mark A. Greer <mgreer@mvista.com>
Fix error in booting-without-of.txt that indicates that a node can inherit
its #address-cells and #size-cells definitions from its parent's parent.
This is not correct and the latest dtc enforces it.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Documentation/powerpc/booting-without-of.txt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index ee0209a..58db5ea 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -671,10 +671,10 @@ device or bus to be described by the device tree.
In general, the format of an address for a device is defined by the
parent bus type, based on the #address-cells and #size-cells
-property. In the absence of such a property, the parent's parent
-values are used, etc... The kernel requires the root node to have
-those properties defining addresses format for devices directly mapped
-on the processor bus.
+properties. Note that the parent's parent definitions of #address-cells
+and #size-cells are not inhereted so every node with children must specify
+them. The kernel requires the root node to have those properties defining
+addresses format for devices directly mapped on the processor bus.
Those 2 properties define 'cells' for representing an address and a
size. A "cell" is a 32-bit number. For example, if both contain 2
^ permalink raw reply related
* Re: [PATCHv2] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Stephen Rothwell @ 2008-01-02 23:41 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: Jean Delvare, linuxppc-dev, Scott Wood, linux-kernel
In-Reply-To: <477BEB60.4070703@scram.de>
[-- Attachment #1: Type: text/plain, Size: 2439 bytes --]
Hi Jochen,
Just a few trivial things.
On Wed, 02 Jan 2008 20:52:00 +0100 Jochen Friedrich <jochen@scram.de> wrote:
>
> +++ b/drivers/i2c/busses/i2c-cpm.c
> +
> +static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
> +{
> + struct i2c_adapter *adap;
> + struct cpm_i2c *cpm;
> + struct i2c_reg __iomem *i2c_reg;
> + int i;
> +
> + adap = (struct i2c_adapter *) dev_id;
This cast is unnecessary. In fact, you could just pass dev_id to the
following call to i2c_get_adapdata() and eliminate adap completely.
> + /* Get 'me going again.
> + */
For short comments, just make them one line. Similarly later as well.
> + /* This chip can't do zero length writes. However, the i2c core uses
> + them to scan for devices. The best we can do is to convert them
> + into 1 byte reads */
For multiline comments, we normally do
/*
* blah ...
* more blah
*/
> +static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
> +{
> +
> + while (tptr < num) {
> + /* Check for outstanding messages */
> + dev_dbg(&adap->dev, "test ready.\n");
> + if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
> + dev_dbg(&adap->dev, "ready.\n");
> + rmsg = &msgs[tptr];
> + ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
> + tptr++;
> + if (rmsg->flags & I2C_M_RD)
> + rptr++;
> + if (ret) {
> + cpm_i2c_force_close(adap);
> + mutex_unlock(&cpm->i2c_mutex);
> + return ret;
> + }
> + } else {
> + dev_dbg(&adap->dev, "not ready.\n");
> + ret = wait_event_interruptible_timeout(cpm->i2c_wait,
> + !(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
> + if (ret == 0) {
> + cpm_i2c_force_close(adap);
> + dev_dbg(&adap->dev, "I2C read: timeout!\n");
> + mutex_unlock(&cpm->i2c_mutex);
> + return -EREMOTEIO;
> + }
You might want to consolidate the two error paths above using gotos to an
error return section below.
> +static void of_register_i2c_devices(struct i2c_adapter *adap,
> + struct device_node *adap_node)
> +{
> + struct device_node *node = NULL;
> +
> + while ((node = of_get_next_child(adap_node, node))) {
Use
for_each_child_of_node(adap_node, node) {
instead and you don't need to initialise "node" above.
> +static struct of_device_id cpm_i2c_match[] = {
const?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH v4 02/13] [POWERPC] Add 'fsl, lpb' bus type for MPC5200 LocalPlus Bus
From: Grant Likely @ 2008-01-02 23:37 UTC (permalink / raw)
To: Marian Balakowicz; +Cc: linuxppc-dev
In-Reply-To: <20071109171149.16289.88635.stgit@hekate.izotz.org>
On 11/9/07, Marian Balakowicz <m8@semihalf.com> wrote:
> Define MPC52xx specific device id list, add new
> 'fsl,lpb' compatible id for LocalPlus Bus.
I'll pick this up, but I'm going to drop the .compatible="soc" line.
(I'd like to drop the device_type="soc" line also, but that requires a
bit more thought first).
Cheers,
g.
>
> Signed-off-by: Marian Balakowicz <m8@semihalf.com>
> Acked-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>
> arch/powerpc/platforms/52xx/mpc52xx_common.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
>
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> index 9850685..2df97c5 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -124,11 +124,18 @@ mpc5200_setup_xlb_arbiter(void)
> iounmap(xlb);
> }
>
> +static struct of_device_id mpc52xx_ids[] = {
> + { .type = "soc", },
> + { .compatible = "soc", },
> + { .compatible = "fsl,lpb", },
> + {},
> +};
> +
> void __init
> mpc52xx_declare_of_platform_devices(void)
> {
> /* Find every child of the SOC node and add it to of_platform */
> - if (of_platform_bus_probe(NULL, NULL, NULL))
> + if (of_platform_bus_probe(NULL, mpc52xx_ids, NULL))
> printk(KERN_ERR __FILE__ ": "
> "Error while probing of_platform bus\n");
> }
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 22:12 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102215311.GA12558@uranus.ravnborg.org>
I have no opinions about the config symbol names. Among the existing
precedents for internal/descriptionless symbols I find more not using the
HAVE_ prefix than those using it. The patch versions I've sent now work
fine, fix the parallel build problem people were seeing, and AFAICT follow
the style of what's already in common use. At this point, I think it would
be easiest just to keep them and have you send symbol-renaming patches
for any and all symbols of this sort that concern you as separate cleanups.
Thanks,
Roland
^ permalink raw reply
* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Sam Ravnborg @ 2008-01-02 21:59 UTC (permalink / raw)
To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102215311.GA12558@uranus.ravnborg.org>
On Wed, Jan 02, 2008 at 10:53:11PM +0100, Sam Ravnborg wrote:
> On Wed, Jan 02, 2008 at 01:08:31PM -0800, Roland McGrath wrote:
> > This patch should go in immediately after:
> >
> > commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> > Author: Roland McGrath <roland@redhat.com>
> >
> > compat_binfmt_elf
> >
> > Thanks,
> > Roland
> >
> > ---
> > [PATCH] compat_binfmt_elf Kconfig
> >
> > This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
> > just added. Each arch that wants to use this file needs to add a
> > "select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.
> >
> > Signed-off-by: Roland McGrath <roland@redhat.com>
> > ---
> > fs/Kconfig.binfmt | 4 ++++
> > fs/Makefile | 1 +
> > 2 files changed, 5 insertions(+), 0 deletions(-)
> >
> > diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> > index d4fc609..0000000 100644
> > --- a/fs/Kconfig.binfmt
> > +++ b/fs/Kconfig.binfmt
> > @@ -23,6 +23,10 @@ config BINFMT_ELF
> > ld.so (check the file <file:Documentation/Changes> for location and
> > latest version).
> >
> > +config COMPAT_BINFMT_ELF
> > + bool
> > + depends on COMPAT && MMU
> > +
> > config BINFMT_ELF_FDPIC
> > bool "Kernel support for FDPIC ELF binaries"
> > default y
> > diff --git a/fs/Makefile b/fs/Makefile
> > index 500cf15..0000000 100644
> > --- a/fs/Makefile
> > +++ b/fs/Makefile
> > @@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC) += binfmt_misc
> > obj-y += binfmt_script.o
> >
> > obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
> > +obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
> > obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
> > obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
> > obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
>
> You totally missed the point of having selectable features noted
> by a config symbol named "HAVE_*".
> When you see such a "HAVE_*" you know it is supposed to be selected
> and thus you need to be much more careful about the dependencies.
>
> And my patch was purely a cooked up example btw and not at all tested.
> Should have been clear about that.
My comment refer to a private mail - but I saw this hit lkml so a bit out
of context.
Sam
^ permalink raw reply
* Re: [PATCH -mm] x86 compat_binfmt_elf
From: Ingo Molnar @ 2008-01-02 21:58 UTC (permalink / raw)
To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102211243.D7CFA26F9A0@magilla.localdomain>
* Roland McGrath <roland@redhat.com> wrote:
> This patch replaces the earlier patch by the same title already in
> x86/mm:
>
> commit a9014d2dfcb253fb3ce5f4e3318849f743b85427
> Author: Roland McGrath <roland@redhat.com>
>
> x86 compat_binfmt_elf
>
> It requires the new patch I just posted, titled "compat_binfmt_elf
> Kconfig".
thanks, applied.
Ingo
^ permalink raw reply
* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Ingo Molnar @ 2008-01-02 21:57 UTC (permalink / raw)
To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>
* Roland McGrath <roland@redhat.com> wrote:
> This patch should go in immediately after:
>
> commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> Author: Roland McGrath <roland@redhat.com>
>
> compat_binfmt_elf
>
> Thanks,
> Roland
>
> ---
> [PATCH] compat_binfmt_elf Kconfig
thanks, applied.
Ingo
^ permalink raw reply
* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Sam Ravnborg @ 2008-01-02 21:53 UTC (permalink / raw)
To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>
On Wed, Jan 02, 2008 at 01:08:31PM -0800, Roland McGrath wrote:
> This patch should go in immediately after:
>
> commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> Author: Roland McGrath <roland@redhat.com>
>
> compat_binfmt_elf
>
> Thanks,
> Roland
>
> ---
> [PATCH] compat_binfmt_elf Kconfig
>
> This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
> just added. Each arch that wants to use this file needs to add a
> "select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.
>
> Signed-off-by: Roland McGrath <roland@redhat.com>
> ---
> fs/Kconfig.binfmt | 4 ++++
> fs/Makefile | 1 +
> 2 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index d4fc609..0000000 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -23,6 +23,10 @@ config BINFMT_ELF
> ld.so (check the file <file:Documentation/Changes> for location and
> latest version).
>
> +config COMPAT_BINFMT_ELF
> + bool
> + depends on COMPAT && MMU
> +
> config BINFMT_ELF_FDPIC
> bool "Kernel support for FDPIC ELF binaries"
> default y
> diff --git a/fs/Makefile b/fs/Makefile
> index 500cf15..0000000 100644
> --- a/fs/Makefile
> +++ b/fs/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC) += binfmt_misc
> obj-y += binfmt_script.o
>
> obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
> +obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
> obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
> obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
> obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
You totally missed the point of having selectable features noted
by a config symbol named "HAVE_*".
When you see such a "HAVE_*" you know it is supposed to be selected
and thus you need to be much more careful about the dependencies.
And my patch was purely a cooked up example btw and not at all tested.
Should have been clear about that.
Sam
^ permalink raw reply
* Re: [PATCH/RFC] powerpc: DBox2 Board Support
From: Scott Wood @ 2008-01-02 21:22 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: linuxppc-dev
In-Reply-To: <477BF446.9070401@scram.de>
Jochen Friedrich wrote:
>>> + ovpartition@20000 {
>>> + label = "Flash without bootloader";
>>> + reg = <20000 7e0000>;
>>> + };
>>> + ovpartition@0 {
>>> + label = "Complete Flash";
>>> + reg = <0 800000>;
>>> + read-only;
>>> + };
>>
>> What is "ovpartition"?
>
> Overlay partition. Is there a better way to specify this?
Not sure... what will the mtd code do with this?
>>> + lcd@970 {
>>> + reg = <970 10>;
>>> + compatible = "samsung,ks0713";
>>> + };
>>
>> So some driver that matches on samsung,ks0713 has to know the details
>> of the
>> mpc8xx GPIO registers?
>
> The GPIO API only has an accessor for 1bit I/O. The LCD, however has for
> 1bit
> control lines and an 8bit port. The GPIO API currently is unable to
> handle this.
Right, but we shouldn't weird up the device tree because of Linux's
weaknesses. Ideally, the GPIO API should support wider I/O; in the
meantime, there should be something in the board file that tells the
ks0713 driver what to do.
>> I'd use separate device trees (I only did this kind of thing in mpc885ads
>> because it's dip-switchable), but whatever...
>
> I don't really like having to use different images on different DBoxes.
> It's
> already too much to have two images (there are two different flash
> layouts).
> People tend to brick their box by flashing the wrong image.
Fair enough.
> localbus@8000000 {
> cam@3,0 {
> compatible = "betaresearch,dbox2-cam";
> reg = <3 0 20000 6 0 20000>;
> interrupts = <6 2>;
> interrupt-parent = <&PIC>;
> gpios = <1 1c 1 1d 1 1e 1 1f>;
> gpio-parent = <&CPM1_PIO>;
> };
> };
> soc@ff000000 {
> cpm@9c0 {
> CPM1_PIO: pio@950 {
> fp@0,0 {
> compatible = "betaresearch,dbox2-fp";
> interrupts = <4 2>;
> interrupt-parent = <&PIC>;
> gpios = <0 e>;
> gpio-parent = <&CPM1_PIO>;
> };
> };
> i2c@860 {
> fp@30 {
> compatible = "betaresearch,dbox2-fp";
> reg = <30>;
> };
> cam@37 {
> compatible = "betaresearch,dbox2-cam";
> reg = <37>;
> };
> };
> };
> };
I'd make the compatible name specific to the interface (e.g.
"betaresearch,dbox2-cam-mmio", "betaresearch,dbox2-fp-i2c"), use reg
rather than gpios/gpio-parent, and use phandle linkage between the
different inteferfaces of a device. But yes, multiple nodes is the
sanest way to do it.
-Scott
^ permalink raw reply
* [PATCH -mm] powerpc compat_binfmt_elf
From: Roland McGrath @ 2008-01-02 21:17 UTC (permalink / raw)
To: Paul Mackerras
Cc: linux-arch, linuxppc-dev, Ingo Molnar, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>
This replaces my earlier patch of the same title, posted with:
Subject: [PATCH -mm 18/43] powerpc compat_binfmt_elf
Date: Thu, 20 Dec 2007 03:58:16 -0800 (PST)
This requires all the powerpc patches in that series from late December and
also requires the new patch I just posted, titled "compat_binfmt_elf Kconfig".
Thanks,
Roland
---
powerpc compat_binfmt_elf
This switches the CONFIG_PPC64 support for 32-bit ELF to use the generic
fs/compat_binfmt_elf.c implementation instead of our own binfmt_elf32.c.
Since so much is the same between 32/64, there is only one macro we have to
define to make the generic support work out of the box.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/kernel/Makefile | 2 +-
arch/powerpc/kernel/binfmt_elf32.c | 69 ------------------------------------
include/asm-powerpc/elf.h | 1 +
4 files changed, 3 insertions(+), 70 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c17a194..0000000 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -92,6 +92,7 @@ config EARLY_PRINTK
config COMPAT
bool
default y if PPC64
+ select COMPAT_BINFMT_ELF
config SYSVIPC_COMPAT
bool
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ca51f0c..0000000 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -15,7 +15,7 @@ obj-y := semaphore.o cputable.o ptrac
init_task.o process.o systbl.o idle.o \
signal.o
obj-y += vdso32/
-obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
+obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o cpu_setup_ppc970.o \
cpu_setup_pa6t.o \
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
deleted file mode 100644
index 1d45d77... .
--- a/arch/powerpc/kernel/binfmt_elf32.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
- * based on the SPARC64 version.
- * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
- * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
- *
- * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
- * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
- *
- * 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 <asm/processor.h>
-#include <linux/module.h>
-#include <linux/compat.h>
-#include <linux/elfcore-compat.h>
-
-#undef ELF_ARCH
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_PPC
-
-#undef elfhdr
-#undef elf_phdr
-#undef elf_note
-#undef elf_addr_t
-#define elfhdr elf32_hdr
-#define elf_phdr elf32_phdr
-#define elf_note elf32_note
-#define elf_addr_t Elf32_Off
-
-#define elf_prstatus compat_elf_prstatus
-#define elf_prpsinfo compat_elf_prpsinfo
-
-#define elf_core_copy_regs compat_elf_core_copy_regs
-static inline void compat_elf_core_copy_regs(compat_elf_gregset_t *elf_regs,
- struct pt_regs *regs)
-{
- PPC_ELF_CORE_COPY_REGS((*elf_regs), regs);
-}
-
-#define elf_core_copy_task_regs compat_elf_core_copy_task_regs
-static int compat_elf_core_copy_task_regs(struct task_struct *tsk,
- compat_elf_gregset_t *elf_regs)
-{
- struct pt_regs *regs = tsk->thread.regs;
- if (regs)
- compat_elf_core_copy_regs(elf_regs, regs);
- return 1;
-}
-
-#include <linux/time.h>
-
-#undef cputime_to_timeval
-#define cputime_to_timeval cputime_to_compat_timeval
-static __inline__ void
-cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
-{
- unsigned long jiffies = cputime_to_jiffies(cputime);
- value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
- value->tv_sec = jiffies / HZ;
-}
-
-#define init_elf_binfmt init_elf32_binfmt
-
-#include "../../../fs/binfmt_elf.c"
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 6bd07ef..0000000 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -165,6 +165,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+#define compat_elf_check_arch(x) ((x)->e_machine == EM_PPC)
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE PAGE_SIZE
^ permalink raw reply related
* [PATCH -mm] x86 compat_binfmt_elf, Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 21:12 UTC (permalink / raw)
To: Ingo Molnar; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>
This patch replaces the earlier patch by the same title already in x86/mm:
commit a9014d2dfcb253fb3ce5f4e3318849f743b85427
Author: Roland McGrath <roland@redhat.com>
x86 compat_binfmt_elf
It requires the new patch I just posted, titled "compat_binfmt_elf Kconfig".
Thanks,
Roland
---
x86 compat_binfmt_elf
This switches x86-64's 32-bit ELF support to use the shared
fs/compat_binfmt_elf.c code instead of our own ia32_binfmt.c.
Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/Kconfig | 1 +
arch/x86/ia32/Makefile | 3 +-
arch/x86/vdso/vdso32-setup.c | 33 ++++++++++++++++
include/asm-x86/elf.h | 88 ++++++++++++++++++++++++++++++-----------
4 files changed, 99 insertions(+), 26 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 66d38bf..0000000 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1546,6 +1546,7 @@ source "fs/Kconfig.binfmt"
config IA32_EMULATION
bool "IA32 Emulation"
depends on X86_64
+ select COMPAT_BINFMT_ELF
help
Include code to run 32-bit programs under a 64-bit kernel. You should
likely turn this on, unless you're 100% sure that you don't have any
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index 93a6fda..0000000 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -2,8 +2,7 @@
# Makefile for the ia32 kernel emulation subsystem.
#
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o \
- ia32_binfmt.o
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o
sysv-$(CONFIG_SYSVIPC) := ipc32.o
obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index e0feb66..0000000 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -377,6 +377,39 @@ int arch_setup_additional_pages(struct l
__initcall(sysenter_setup);
+#ifdef CONFIG_SYSCTL
+/* Register vsyscall32 into the ABI table */
+#include <linux/sysctl.h>
+
+static ctl_table abi_table2[] = {
+ {
+ .procname = "vsyscall32",
+ .data = &sysctl_vsyscall32,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+ {}
+};
+
+static ctl_table abi_root_table2[] = {
+ {
+ .ctl_name = CTL_ABI,
+ .procname = "abi",
+ .mode = 0555,
+ .child = abi_table2
+ },
+ {}
+};
+
+static __init int ia32_binfmt_init(void)
+{
+ register_sysctl_table(abi_root_table2);
+ return 0;
+}
+__initcall(ia32_binfmt_init);
+#endif
+
#else /* CONFIG_X86_32 */
const char *arch_vma_name(struct vm_area_struct *vma)
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
index d6bf742..0000000 100644
--- a/include/asm-x86/elf.h
+++ b/include/asm-x86/elf.h
@@ -73,6 +73,9 @@ typedef struct user_fxsr_struct elf_fpxr
#endif
#ifdef __KERNEL__
+#include <asm/vdso.h>
+
+extern unsigned int vdso_enabled;
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -84,7 +87,6 @@ typedef struct user_fxsr_struct elf_fpxr
#include <asm/processor.h>
#include <asm/system.h> /* for savesegment */
#include <asm/desc.h>
-#include <asm/vdso.h>
#define elf_check_arch(x) elf_check_arch_ia32(x)
@@ -106,7 +108,6 @@ typedef struct user_fxsr_struct elf_fpxr
#define ELF_PLATFORM (utsname()->machine)
#define set_personality_64bit() do { } while (0)
-extern unsigned int vdso_enabled;
#else /* CONFIG_X86_32 */
@@ -118,29 +119,57 @@ extern unsigned int vdso_enabled;
#define elf_check_arch(x) \
((x)->e_machine == EM_X86_64)
+#define compat_elf_check_arch(x) elf_check_arch_ia32(x)
+
+static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
+{
+ asm volatile("movl %0,%%fs" :: "r" (0));
+ asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS));
+ load_gs_index(0);
+ regs->ip = ip;
+ regs->sp = sp;
+ regs->flags = X86_EFLAGS_IF;
+ regs->cs = __USER32_CS;
+ regs->ss = __USER32_DS;
+}
+
+static inline void elf_common_init(struct thread_struct *t,
+ struct pt_regs *regs, const u16 ds)
+{
+ regs->ax = regs->bx = regs->cx = regs->dx = 0;
+ regs->si = regs->di = regs->bp = 0;
+ regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
+ regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
+ t->fs = t->gs = 0;
+ t->fsindex = t->gsindex = 0;
+ t->ds = t->es = ds;
+}
+
#define ELF_PLAT_INIT(_r, load_addr) do { \
- struct task_struct *cur = current; \
- (_r)->bx = 0; (_r)->cx = 0; (_r)->dx = 0; \
- (_r)->si = 0; (_r)->di = 0; (_r)->bp = 0; \
- (_r)->ax = 0; \
- (_r)->r8 = 0; \
- (_r)->r9 = 0; \
- (_r)->r10 = 0; \
- (_r)->r11 = 0; \
- (_r)->r12 = 0; \
- (_r)->r13 = 0; \
- (_r)->r14 = 0; \
- (_r)->r15 = 0; \
- cur->thread.fs = 0; cur->thread.gs = 0; \
- cur->thread.fsindex = 0; cur->thread.gsindex = 0; \
- cur->thread.ds = 0; cur->thread.es = 0; \
+ elf_common_init(¤t->thread, _r, 0); \
clear_thread_flag(TIF_IA32); \
} while (0)
+#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \
+ elf_common_init(¤t->thread, regs, __USER_DS)
+#define compat_start_thread(regs, ip, sp) do { \
+ start_ia32_thread(regs, ip, sp); \
+ set_fs(USER_DS); \
+ } while (0)
+#define COMPAT_SET_PERSONALITY(ex, ibcs2) do { \
+ if (test_thread_flag(TIF_IA32)) \
+ clear_thread_flag(TIF_ABI_PENDING); \
+ else \
+ set_thread_flag(TIF_ABI_PENDING); \
+ current->personality |= force_personality32; \
+ } while (0)
+#define COMPAT_ELF_PLATFORM ("i686")
+
/* I'm not sure if we can use '-' here */
#define ELF_PLATFORM ("x86_64")
extern void set_personality_64bit(void);
-extern int vdso_enabled;
+extern unsigned int sysctl_vsyscall32;
+extern int force_personality32;
#endif /* !CONFIG_X86_32 */
@@ -179,17 +208,19 @@ extern int vdso_enabled;
struct task_struct;
+#define ARCH_DLINFO_IA32(vdso_enabled) \
+do if (vdso_enabled) { \
+ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \
+} while (0)
+
#ifdef CONFIG_X86_32
#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
-/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
+#define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled)
-#define ARCH_DLINFO \
-do if (vdso_enabled) { \
- NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \
-} while (0)
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#else /* CONFIG_X86_32 */
@@ -203,6 +234,12 @@ do if (vdso_enabled) { \
NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
} while (0)
+#define AT_SYSINFO 32
+
+#define COMPAT_ARCH_DLINFO ARCH_DLINFO_IA32(sysctl_vsyscall32)
+
+#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
+
#endif /* !CONFIG_X86_32 */
#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
@@ -216,6 +253,9 @@ struct linux_binprm;
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int executable_stack);
+extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
+#define compat_arch_setup_additional_pages syscall32_setup_pages
+
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
^ permalink raw reply related
* [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 21:08 UTC (permalink / raw)
To: Ingo Molnar; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102191030.GA11217@uranus.ravnborg.org>
This patch should go in immediately after:
commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
Author: Roland McGrath <roland@redhat.com>
compat_binfmt_elf
Thanks,
Roland
---
[PATCH] compat_binfmt_elf Kconfig
This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
just added. Each arch that wants to use this file needs to add a
"select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
fs/Kconfig.binfmt | 4 ++++
fs/Makefile | 1 +
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index d4fc609..0000000 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -23,6 +23,10 @@ config BINFMT_ELF
ld.so (check the file <file:Documentation/Changes> for location and
latest version).
+config COMPAT_BINFMT_ELF
+ bool
+ depends on COMPAT && MMU
+
config BINFMT_ELF_FDPIC
bool "Kernel support for FDPIC ELF binaries"
default y
diff --git a/fs/Makefile b/fs/Makefile
index 500cf15..0000000 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC) += binfmt_misc
obj-y += binfmt_script.o
obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
+obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
^ permalink raw reply related
* Re: [PATCH/RFC] powerpc: DBox2 Board Support
From: Jochen Friedrich @ 2008-01-02 20:29 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080102180655.GB4398@loki.buserror.net>
Hi Scott,
> These unit addresses look wrong.
I know. These have (hopefully) been fixed in v3.
> What does dbox2-config mean?
I used it to search for the vendor info byte in the flash. It has been moved to the boot wrapper in v3.
Later this should all be moved to u-boot, IMHO.
>> + ovpartition@20000 {
>> + label = "Flash without bootloader";
>> + reg = <20000 7e0000>;
>> + };
>> + ovpartition@0 {
>> + label = "Complete Flash";
>> + reg = <0 800000>;
>> + read-only;
>> + };
>
> What is "ovpartition"?
Overlay partition. Is there a better way to specify this?
>> + // Port D is LCD exclusive. Don't export as GPIO
>> + CPM1_PIO: pio@970 {
>> + compatible = "fsl,cpm1-pario";
>> + reg = <970 180>;
>> + num-ports = <3>;
>> + #gpio-cells = <2>;
>> + };
>
> Why are we doing things differently just because all of the pins on this
> port happen to be directed to one device? If it's because the Linux GPIO
> API sucks, then either fix the API, or work around the suckage in software,
> not the device tree.
>
>> + lcd@970 {
>> + reg = <970 10>;
>> + compatible = "samsung,ks0713";
>> + };
>
> So some driver that matches on samsung,ks0713 has to know the details of the
> mpc8xx GPIO registers?
The GPIO API only has an accessor for 1bit I/O. The LCD, however has for 1bit
control lines and an 8bit port. The GPIO API currently is unable to handle this.
>> + i2c@860 {
>> + compatible = "fsl,mpc823-i2c",
>> + "fsl,cpm1-i2c",
>> + "fsl,cpm-i2c";
>> + reg = <860 20 3c80 30>;
>> + interrupts = <10 3>;
>> + interrupt-parent = <&CPM_PIC>;
>> + fsl,cpm-command = <0010>;
>> + };
>
> Should have #address-cells and #size-cells.
In the meantime, i use the i2c patches from Jon Smirl and have added
these parameters.
>
>> +enum dbox2_mid dbox2_get_mid(void)
>> +{
>> + return dbox2_manuf_id;
>> +}
>> +EXPORT_SYMBOL_GPL(dbox2_get_mid);
>
> Honestly, you're claiming derived-work status by calling a function that
> returns an integer, that was read directly from hardware?
Nope. It was a big fat hint not to use this value :). It has been moved to the
device tree in the mean time.
> I'd use separate device trees (I only did this kind of thing in mpc885ads
> because it's dip-switchable), but whatever...
I don't really like having to use different images on different DBoxes. It's
already too much to have two images (there are two different flash layouts).
People tend to brick their box by flashing the wrong image.
>> --- a/include/asm-powerpc/mpc8xx.h
>> +++ b/include/asm-powerpc/mpc8xx.h
>> @@ -23,6 +23,10 @@
>> #include <platforms/8xx/mpc885ads.h>
>> #endif
>>
>> +#if defined(CONFIG_DBOX2)
>> +#include <platforms/8xx/dbox2.h>
>> +#endif
>
> This shouldn't be needed.
Already gone in v3.
> What happens if a device sits on two different gpio-parents?
On the dbox2, there are even stranger devices. One is using iomaped address spaces, GPIO and an i2c control interface.
Another one uses GPIO and an i2c control interface. For now, they appear twice in the device tree (once under i2c and
once under localbus or pio). Is there a better way to do this?
localbus@8000000 {
cam@3,0 {
compatible = "betaresearch,dbox2-cam";
reg = <3 0 20000 6 0 20000>;
interrupts = <6 2>;
interrupt-parent = <&PIC>;
gpios = <1 1c 1 1d 1 1e 1 1f>;
gpio-parent = <&CPM1_PIO>;
};
};
soc@ff000000 {
cpm@9c0 {
CPM1_PIO: pio@950 {
fp@0,0 {
compatible = "betaresearch,dbox2-fp";
interrupts = <4 2>;
interrupt-parent = <&PIC>;
gpios = <0 e>;
gpio-parent = <&CPM1_PIO>;
};
};
i2c@860 {
fp@30 {
compatible = "betaresearch,dbox2-fp";
reg = <30>;
};
cam@37 {
compatible = "betaresearch,dbox2-cam";
reg = <37>;
};
};
};
};
Thanks,
Jochen
^ permalink raw reply
* Re: [PATCH 3/5] [POWERPC] pasemi: Use machine_*_initcall() hooks in platform code
From: Olof Johansson @ 2008-01-02 20:30 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20080102191441.24178.42988.stgit@trillian.secretlab.ca>
On Wed, Jan 02, 2008 at 12:32:28PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> arch/powerpc/platforms/pasemi/idle.c | 5 +----
> arch/powerpc/platforms/pasemi/setup.c | 10 ++--------
> 2 files changed, 3 insertions(+), 12 deletions(-)
Applied to for-2.6.25.
Thanks,
-Olof
^ permalink raw reply
* Re: [PATCH 1/5] [POWERPC] powermac: Use machine_*_initcall() hooks in platform code
From: Benjamin Herrenschmidt @ 2008-01-02 20:20 UTC (permalink / raw)
To: Grant Likely; +Cc: olof, linuxppc-dev
In-Reply-To: <20080102191424.24178.41726.stgit@trillian.secretlab.ca>
On Wed, 2008-01-02 at 12:14 -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Ack.
>
> arch/powerpc/platforms/powermac/low_i2c.c | 7 ++-----
> arch/powerpc/platforms/powermac/pfunc_base.c | 3 +--
> arch/powerpc/platforms/powermac/pic.c | 3 +--
> arch/powerpc/platforms/powermac/setup.c | 12 ++----------
> 4 files changed, 6 insertions(+), 19 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
> index da2007e..9c9299c 100644
> --- a/arch/powerpc/platforms/powermac/low_i2c.c
> +++ b/arch/powerpc/platforms/powermac/low_i2c.c
> @@ -1462,9 +1462,6 @@ int __init pmac_i2c_init(void)
> return 0;
> i2c_inited = 1;
>
> - if (!machine_is(powermac))
> - return 0;
> -
> /* Probe keywest-i2c busses */
> kw_i2c_probe();
>
> @@ -1483,7 +1480,7 @@ int __init pmac_i2c_init(void)
>
> return 0;
> }
> -arch_initcall(pmac_i2c_init);
> +machine_arch_initcall(powermac, pmac_i2c_init);
>
> /* Since pmac_i2c_init can be called too early for the platform device
> * registration, we need to do it at a later time. In our case, subsys
> @@ -1515,4 +1512,4 @@ static int __init pmac_i2c_create_platform_devices(void)
>
> return 0;
> }
> -subsys_initcall(pmac_i2c_create_platform_devices);
> +machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices);
> diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
> index 45d54b9..db20de5 100644
> --- a/arch/powerpc/platforms/powermac/pfunc_base.c
> +++ b/arch/powerpc/platforms/powermac/pfunc_base.c
> @@ -363,8 +363,7 @@ int __init pmac_pfunc_base_install(void)
>
> return 0;
> }
> -
> -arch_initcall(pmac_pfunc_base_install);
> +machine_arch_initcall(powermac, pmac_pfunc_base_install);
>
> #ifdef CONFIG_PM
>
> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
> index 999f5e1..cd72164 100644
> --- a/arch/powerpc/platforms/powermac/pic.c
> +++ b/arch/powerpc/platforms/powermac/pic.c
> @@ -690,6 +690,5 @@ static int __init init_pmacpic_sysfs(void)
> sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
> return 0;
> }
> -
> -subsys_initcall(init_pmacpic_sysfs);
> +machine_subsys_initcall(powermac, init_pmacpic_sysfs);
>
> diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
> index adad4e9..36ff1b6 100644
> --- a/arch/powerpc/platforms/powermac/setup.c
> +++ b/arch/powerpc/platforms/powermac/setup.c
> @@ -397,17 +397,13 @@ static int initializing = 1;
>
> static int pmac_late_init(void)
> {
> - if (!machine_is(powermac))
> - return -ENODEV;
> -
> initializing = 0;
> /* this is udbg (which is __init) and we can later use it during
> * cpu hotplug (in smp_core99_kick_cpu) */
> ppc_md.progress = NULL;
> return 0;
> }
> -
> -late_initcall(pmac_late_init);
> +machine_late_initcall(powermac, pmac_late_init);
>
> /*
> * This is __init_refok because we check for "initializing" before
> @@ -534,9 +530,6 @@ static int __init pmac_declare_of_platform_devices(void)
> if (machine_is(chrp))
> return -1;
>
> - if (!machine_is(powermac))
> - return 0;
> -
> np = of_find_node_by_name(NULL, "valkyrie");
> if (np)
> of_platform_device_create(np, "valkyrie", NULL);
> @@ -551,8 +544,7 @@ static int __init pmac_declare_of_platform_devices(void)
>
> return 0;
> }
> -
> -device_initcall(pmac_declare_of_platform_devices);
> +machine_device_initcall(powermac, pmac_declare_of_platform_devices);
>
> /*
> * Called very early, MMU is off, device-tree isn't unflattened
^ permalink raw reply
* [PATCHv2] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2008-01-02 19:52 UTC (permalink / raw)
To: Jon Smirl; +Cc: Jean Delvare, linuxppc-dev, linux-kernel, Scott Wood
Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.
Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
arch/powerpc/boot/dts/mpc8272ads.dts | 10 +
arch/powerpc/boot/dts/mpc866ads.dts | 10 +
arch/powerpc/boot/dts/mpc885ads.dts | 10 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 5 +
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-cpm.c | 786 ++++++++++++++++++++++++++
7 files changed, 832 insertions(+), 0 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-cpm.c
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 7285ca1..7273996 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -215,6 +215,16 @@
linux,network-index = <1>;
fsl,cpm-command = <16200300>;
};
+
+ i2c@11860 {
+ compatible = "fsl,mpc8248-i2c",
+ "fsl,cpm2-i2c",
+ "fsl,cpm-i2c";
+ reg = <11860 20 8afc 2>;
+ interrupts = <1 8>;
+ interrupt-parent = <&PIC>;
+ fsl,cpm-command = <29600000>;
+ };
};
PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index daf9433..80c08bf 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -169,6 +169,16 @@
fsl,cpm-command = <0000>;
linux,network-index = <1>;
};
+
+ i2c@860 {
+ compatible = "fsl,mpc866-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10 3>;
+ interrupt-parent = <&Cpm_pic>;
+ fsl,cpm-command = <0010>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
fsl,cpm-command = <0080>;
linux,network-index = <2>;
};
+
+ i2c@860 {
+ compatible = "fsl,mpc885-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10>;
+ interrupt-parent = <&CPM_PIC>;
+ fsl,cpm-command = <0010>;
+ };
};
};
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..4377521 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
{CPM_PORTE, 28, CPM_PIN_OUTPUT},
{CPM_PORTE, 29, CPM_PIN_OUTPUT},
#endif
+ /* I2C */
+#ifdef CONFIG_I2C_8XX
+ {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+ {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
};
static void __init init_ioports(void)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c466c6c..5950172 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
help
The unit of the TWI clock is kHz.
+config I2C_CPM
+ tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+ depends on (CPM1 || CPM2) && I2C && PPC_OF
+ help
+ This supports the use of the I2C interface on Freescale
+ processors with CPM1 or CPM2.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-cpm.
+
config I2C_DAVINCI
tristate "DaVinci I2C driver"
depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 81d43c2..a395555 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..f5371c6
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,786 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update: There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board. The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/ */
+#undef I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ 513
+#define CPM_MAXBD 4
+
+#define CPM_CR_INIT_TRX (0x00)
+#define CPM_CR_CLOSE_RXBD (0x07)
+
+#define I2C_EB (0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+ ushort rbase; /* Rx Buffer descriptor base address */
+ ushort tbase; /* Tx Buffer descriptor base address */
+ u_char rfcr; /* Rx function code */
+ u_char tfcr; /* Tx function code */
+ ushort mrblr; /* Max receive buffer length */
+ uint rstate; /* Internal */
+ uint rdp; /* Internal */
+ ushort rbptr; /* Rx Buffer descriptor pointer */
+ ushort rbc; /* Internal */
+ uint rxtmp; /* Internal */
+ uint tstate; /* Internal */
+ uint tdp; /* Internal */
+ ushort tbptr; /* Tx Buffer descriptor pointer */
+ ushort tbc; /* Internal */
+ uint txtmp; /* Internal */
+ char res1[4]; /* Reserved */
+ ushort rpbase; /* Relocation pointer */
+ char res2[2]; /* Reserved */
+};
+
+/* I2C Registers */
+struct i2c_reg {
+ u8 i2mod;
+ u8 res1[3];
+ u8 i2add;
+ u8 res2[3];
+ u8 i2brg;
+ u8 res3[3];
+ u8 i2com;
+ u8 res4[3];
+ u8 i2cer;
+ u8 res5[3];
+ u8 i2cmr;
+};
+
+struct cpm_i2c {
+ char *base;
+ struct of_device *ofdev;
+ struct i2c_adapter adap;
+ uint dp_addr;
+ int version; /* CPM1=1, CPM2=2 */
+ int irq;
+ int cp_command;
+ struct i2c_reg __iomem *i2c_reg;
+ struct i2c_ram __iomem *i2c_ram;
+ u16 i2c_addr;
+ wait_queue_head_t i2c_wait;
+ struct mutex i2c_mutex; /* Protects I2C CPM */
+ u_char *txbuf[CPM_MAXBD];
+ u_char *rxbuf[CPM_MAXBD];
+ u32 txdma[CPM_MAXBD];
+ u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+ struct i2c_adapter *adap;
+ struct cpm_i2c *cpm;
+ struct i2c_reg __iomem *i2c_reg;
+ int i;
+
+ adap = (struct i2c_adapter *) dev_id;
+ cpm = i2c_get_adapdata(adap);
+ i2c_reg = cpm->i2c_reg;
+
+ /* Clear interrupt.
+ */
+ i = in_8(&i2c_reg->i2cer);
+ out_8(&i2c_reg->i2cer, i);
+
+ dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+ /* Get 'me going again.
+ */
+ wake_up_interruptible(&cpm->i2c_wait);
+
+ return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+ struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+ /* Set up the IIC parameters in the parameter ram.
+ */
+ out_be16(&i2c_ram->tbase, cpm->dp_addr);
+ out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+ out_8(&i2c_ram->tfcr, I2C_EB);
+ out_8(&i2c_ram->rfcr, I2C_EB);
+
+ out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+ out_be32(&i2c_ram->rstate, 0);
+ out_be32(&i2c_ram->rdp, 0);
+ out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+ out_be16(&i2c_ram->rbc, 0);
+ out_be32(&i2c_ram->rxtmp, 0);
+ out_be32(&i2c_ram->tstate, 0);
+ out_be32(&i2c_ram->tdp, 0);
+ out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+ out_be16(&i2c_ram->tbc, 0);
+ out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+ dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+ cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+ out_8(&i2c_reg->i2cmr, 0x00); /* Disable all interrupts */
+ out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+ struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+ cbd_t *tbdf, *rbdf;
+ u_char addr;
+ u_char *tb;
+ u_char *rb;
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+ int i, dscan;
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ /* This chip can't do zero length writes. However, the i2c core uses
+ them to scan for devices. The best we can do is to convert them
+ into 1 byte reads */
+
+ dscan = ((pmsg->len == 0) && (num == 1));
+
+ addr = pmsg->addr << 1;
+ if ((pmsg->flags & I2C_M_RD) || dscan)
+ addr |= 1;
+
+ tb = cpm->txbuf[tx];
+ rb = cpm->rxbuf[rx];
+
+ /* Align read buffer */
+ rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+ if ((pmsg->flags & I2C_M_RD) || dscan) {
+ /* To read, we need an empty buffer of the proper length.
+ * All that is used is the first byte for address, the remainder
+ * is just used for timing (and doesn't really have to exist).
+ */
+ tb[0] = addr; /* Device address byte w/rw flag */
+
+ dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+ if (dscan)
+ tbdf[tx].cbd_datlen = 2;
+ else
+ tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+ tbdf[tx].cbd_sc = 0;
+
+ if (!(pmsg->flags & I2C_M_NOSTART))
+ tbdf[tx].cbd_sc |= BD_I2C_START;
+ if (tx + 1 == num)
+ tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+ rbdf[rx].cbd_datlen = 0;
+ rbdf[rx].cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+
+ if (rx + 1 == CPM_MAXBD)
+ tbdf[rx].cbd_sc |= BD_SC_WRAP;
+
+ eieio();
+ tbdf[tx].cbd_sc |= BD_SC_READY;
+ } else {
+ tb[0] = addr; /* Device address byte w/rw flag */
+ for (i = 0; i < pmsg->len; i++)
+ tb[i+1] = pmsg->buf[i];
+
+ dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+ tbdf[tx].cbd_datlen = pmsg->len + 1;
+ tbdf[tx].cbd_sc = 0;
+
+ if (!(pmsg->flags & I2C_M_NOSTART))
+ tbdf[tx].cbd_sc |= BD_I2C_START;
+
+ if (tx + 1 == num)
+ tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+ eieio();
+ tbdf[tx].cbd_sc |= BD_SC_READY | BD_SC_INTRPT;
+
+ dev_dbg(&adap->dev, "tx sc %d %04x\n",
+ tx, tbdf[tx].cbd_sc);
+ }
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+ struct i2c_msg *pmsg, int tx, int rx)
+{
+ cbd_t *tbdf, *rbdf;
+ u_char *tb;
+ u_char *rb;
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+ int i;
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ tb = cpm->txbuf[tx];
+ rb = cpm->rxbuf[rx];
+
+ /* Align read buffer */
+ rb = (u_char *) (((uint) rb + 1) & ~1);
+
+ if (pmsg->flags & I2C_M_RD) {
+ dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+ tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+ if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+ dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+ if (pmsg->flags & I2C_M_IGNORE_NAK)
+ return 0;
+ else
+ return -EIO;
+ }
+ if (rbdf[rx].cbd_sc & BD_SC_EMPTY) {
+ dev_dbg(&adap->dev,
+ "IIC read; complete but rbuf empty\n");
+ return -EREMOTEIO;
+ }
+ if (rbdf[rx].cbd_sc & BD_SC_OV) {
+ dev_dbg(&adap->dev, "IIC read; Overrun\n");
+ return -EREMOTEIO;
+ }
+ for (i = 0; i < pmsg->len; i++)
+ pmsg->buf[i] = rb[i];
+ } else {
+ dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+ if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+ dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+ if (pmsg->flags & I2C_M_IGNORE_NAK)
+ return 0;
+ else
+ return -EIO;
+ }
+ if (tbdf[tx].cbd_sc & BD_SC_UN) {
+ dev_dbg(&adap->dev, "IIC write; Underrun\n");
+ return -EIO;
+ }
+ if (tbdf[tx].cbd_sc & BD_SC_CL) {
+ dev_dbg(&adap->dev, "IIC write; Collision\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+ struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+ struct i2c_msg *pmsg, *rmsg;
+ int ret, i;
+ int tptr;
+ int rptr;
+ cbd_t *tbdf, *rbdf;
+
+ if (num > CPM_MAXBD)
+ return -EINVAL;
+
+ /* Check if we have any oversized READ requests */
+ for (i = 0; i < num; i++) {
+ pmsg = &msgs[i];
+ if (pmsg->len >= CPM_MAX_READ)
+ return -EINVAL;
+ }
+
+ mutex_lock(&cpm->i2c_mutex);
+
+ /* Reset to use first buffer */
+ out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+ out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ tptr = 0;
+ rptr = 0;
+
+ while (tptr < num) {
+ pmsg = &msgs[tptr];
+ dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+ rptr, tptr);
+
+ cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+ if (pmsg->flags & I2C_M_RD)
+ rptr++;
+ tptr++;
+ }
+ /* Start transfer now */
+ /* Chip bug, set enable here */
+ out_8(&i2c_reg->i2cmr, 0x13); /* Enable RX/TX/Error interupts */
+ out_8(&i2c_reg->i2cer, 0xff); /* Clear interrupt status */
+ out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1); /* Enable */
+ /* Begin transmission */
+ out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+ tptr = 0;
+ rptr = 0;
+
+ while (tptr < num) {
+ /* Check for outstanding messages */
+ dev_dbg(&adap->dev, "test ready.\n");
+ if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+ dev_dbg(&adap->dev, "ready.\n");
+ rmsg = &msgs[tptr];
+ ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+ tptr++;
+ if (rmsg->flags & I2C_M_RD)
+ rptr++;
+ if (ret) {
+ cpm_i2c_force_close(adap);
+ mutex_unlock(&cpm->i2c_mutex);
+ return ret;
+ }
+ } else {
+ dev_dbg(&adap->dev, "not ready.\n");
+ ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+ !(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+ if (ret == 0) {
+ cpm_i2c_force_close(adap);
+ dev_dbg(&adap->dev, "I2C read: timeout!\n");
+ mutex_unlock(&cpm->i2c_mutex);
+ return -EREMOTEIO;
+ }
+ }
+ }
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+ mutex_unlock(&cpm->i2c_mutex);
+ return (num);
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: ------------------------------------- */
+
+static struct i2c_algorithm cpm_i2c_algo = {
+ .master_xfer = cpm_i2c_xfer,
+ .functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+ .owner = THIS_MODULE,
+ .name = "i2c-cpm",
+ .id = I2C_HW_MPC8XX_EPON,
+ .algo = &cpm_i2c_algo,
+ .class = I2C_CLASS_HWMON,
+};
+
+static int cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+ struct of_device *ofdev = cpm->ofdev;
+ const u32 *data;
+ int len, ret, i;
+ void __iomem *i2c_base;
+ cbd_t *tbdf, *rbdf;
+ unsigned char brg;
+
+ pr_debug("i2c-cpm: cpm_i2c_setup()\n");
+
+ init_waitqueue_head(&cpm->i2c_wait);
+ mutex_init(&cpm->i2c_mutex);
+
+ cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+ if (cpm->irq == NO_IRQ)
+ return -EINVAL;
+
+ /* Install interrupt handler.
+ */
+ ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+ &cpm->adap);
+ if (ret)
+ goto out_irq;
+
+ /* IIC parameter RAM */
+ i2c_base = of_iomap(ofdev->node, 1);
+ if (i2c_base == NULL) {
+ ret = -EINVAL;
+ goto out_irq;
+ }
+
+ if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+ /* Check for and use a microcode relocation patch. */
+ cpm->i2c_ram = i2c_base;
+ cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+ /* Maybe should use cpm_muram_alloc instead of hardcoding
+ * this in micropatch.c */
+ if (cpm->i2c_addr) {
+ cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+ iounmap(i2c_base);
+ }
+
+ cpm->version = 1;
+
+ } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+ cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+ cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+ out_be16(i2c_base, cpm->i2c_addr);
+ iounmap(i2c_base);
+
+ cpm->version = 2;
+
+ } else {
+ iounmap(i2c_base);
+ ret = -EINVAL;
+ goto out_irq;
+ }
+
+ /* I2C control/status registers */
+ cpm->i2c_reg = of_iomap(ofdev->node, 0);
+ if (cpm->i2c_reg == NULL) {
+ ret = -EINVAL;
+ goto out_ram;
+ }
+
+ data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+ if (!data || len != 4) {
+ ret = -EINVAL;
+ goto out_reg;
+ }
+ cpm->cp_command = *data;
+
+ /* Allocate space for CPM_MAXBD transmit and receive buffer
+ * descriptors in the DP ram.
+ */
+ cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+ if (!cpm->dp_addr) {
+ ret = -ENOMEM;
+ goto out_reg;
+ }
+
+ /* Initialize Tx/Rx parameters. */
+
+ cpm_reset_i2c_params(cpm);
+
+ pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+ cpm->dp_addr);
+ pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+ in_be16(&cpm->i2c_ram->tbase), in_be16(&cpm->i2c_ram->rbase));
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->rbase));
+
+ /* Allocate TX and RX buffers */
+
+ for (i = 0; i < CPM_MAXBD; i++) {
+ cpm->rxbuf[i] = dma_alloc_coherent(
+ NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+ if (!cpm->rxbuf[i]) {
+ ret = -ENOMEM;
+ goto out_muram;
+ }
+ rbdf[i].cbd_bufaddr = ((cpm->rxdma[i] + 1) & ~1);
+ cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+ NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+ if (!cpm->txbuf[i]) {
+ ret = -ENOMEM;
+ goto out_muram;
+ }
+ tbdf[i].cbd_bufaddr = cpm->txdma[i];
+ }
+
+ cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+ /* Select an invalid address. Just make sure we don't use loopback mode
+ */
+ out_8(&cpm->i2c_reg->i2add, 0xfe);
+
+ /* Make clock run at 60 kHz. */
+
+ brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+ out_8(&cpm->i2c_reg->i2brg, brg);
+
+ out_8(&cpm->i2c_reg->i2mod, 0x00);
+ out_8(&cpm->i2c_reg->i2com, 0x01); /* Master mode */
+
+ /* Disable interrupts. */
+ out_8(&cpm->i2c_reg->i2cmr, 0);
+ out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+ return 0;
+
+out_muram:
+ for (i = 0; i < CPM_MAXBD; i++) {
+ if (cpm->rxbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->rxbuf[i], cpm->rxdma[i]);
+ if (cpm->txbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->txbuf[i], cpm->txdma[i]);
+ }
+ cpm_muram_free(cpm->dp_addr);
+out_reg:
+ iounmap(cpm->i2c_reg);
+out_ram:
+ if ((cpm->version == 1) && (!cpm->i2c_addr))
+ iounmap(cpm->i2c_ram);
+ if (cpm->version == 2)
+ cpm_muram_free(cpm->i2c_addr);
+out_irq:
+ free_irq(cpm->irq, &cpm->adap);
+ return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+ int i;
+
+ /* Shut down I2C. */
+ out_8(&cpm->i2c_reg->i2mod, in_8(&cpm->i2c_reg->i2mod) | ~1);
+
+ /* Disable interrupts */
+ out_8(&cpm->i2c_reg->i2cmr, 0);
+ out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+ free_irq(cpm->irq, &cpm->adap);
+
+ /* Free all memory */
+ for (i = 0; i < CPM_MAXBD; i++) {
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->rxbuf[i], cpm->rxdma[i]);
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->txbuf[i], cpm->txdma[i]);
+ }
+
+ cpm_muram_free(cpm->dp_addr);
+ iounmap(cpm->i2c_reg);
+
+ if ((cpm->version == 1) && (!cpm->i2c_addr))
+ iounmap(cpm->i2c_ram);
+ if (cpm->version == 2)
+ cpm_muram_free(cpm->i2c_addr);
+
+ return;
+}
+
+static void of_register_i2c_devices(struct i2c_adapter *adap,
+ struct device_node *adap_node)
+{
+ struct device_node *node = NULL;
+
+ while ((node = of_get_next_child(adap_node, node))) {
+ struct i2c_board_info info;
+ const u32 *addr;
+ const char *compatible;
+ int len;
+
+ addr = of_get_property(node, "reg", &len);
+ if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+ printk(KERN_ERR "i2c-cpm.c: invalid entry, "
+ "missing reg attribute\n");
+ continue;
+ }
+
+ info.irq = irq_of_parse_and_map(node, 0);
+ if (info.irq == NO_IRQ)
+ info.irq = -1;
+
+ compatible = of_get_property(node, "compatible", &len);
+ if (!compatible) {
+ printk(KERN_ERR "i2c-cpm.c: invalid entry, "
+ "missing compatible attribute\n");
+ continue;
+ }
+
+ /* need full alias i2c:NOF,vendor,device */
+ strcpy(info.driver_name, I2C_OF_MODULE_PREFIX);
+ strncat(info.driver_name, compatible, sizeof(info.driver_name));
+ request_module(info.driver_name);
+
+ /* need module alias OF,vendor,device */
+ strcpy(info.driver_name, OF_I2C_PREFIX);
+ strncat(info.driver_name, compatible, sizeof(info.driver_name));
+
+ info.type[0] = '\0';
+ info.platform_data = NULL;
+ info.addr = *addr;
+
+ if (!i2c_new_device(adap, &info)) {
+ printk(KERN_ERR "i2c-cpm.c: Failed to load driver for "
+ "%s\n", info.driver_name);
+ continue;
+ }
+ }
+}
+
+static int cpm_i2c_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int result;
+ struct cpm_i2c *cpm;
+
+ cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+ if (!cpm)
+ return -ENOMEM;
+
+ cpm->ofdev = ofdev;
+
+ dev_set_drvdata(&ofdev->dev, cpm);
+
+ cpm->adap = cpm_ops;
+ i2c_set_adapdata(&cpm->adap, cpm);
+ cpm->adap.dev.parent = &ofdev->dev;
+
+ result = cpm_i2c_setup(cpm);
+ if (result) {
+ printk(KERN_ERR "i2c-cpm: Unable to init hardware\n");
+ goto out;
+ }
+
+ /* register new adapter to i2c module... */
+
+ result = i2c_add_adapter(&cpm->adap);
+ if (result < 0) {
+ printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+ goto out2;
+ }
+
+ pr_debug("i2c-cpm: hw routines for %s registered.\n", cpm->adap.name);
+
+ of_register_i2c_devices(&cpm->adap, ofdev->node);
+
+ return 0;
+out2:
+ cpm_i2c_shutdown(cpm);
+out:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(cpm);
+
+ return result;
+}
+
+static int cpm_i2c_remove(struct of_device *ofdev)
+{
+ struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+ i2c_del_adapter(&cpm->adap);
+
+ cpm_i2c_shutdown(cpm);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(cpm);
+
+ return 0;
+}
+
+static struct of_device_id cpm_i2c_match[] = {
+ {
+ .compatible = "fsl,cpm-i2c",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+ .match_table = cpm_i2c_match,
+ .probe = cpm_i2c_probe,
+ .remove = __devexit_p(cpm_i2c_remove),
+ .driver = {
+ .name = "fsl-i2c-cpm",
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init cpm_i2c_init(void)
+{
+ return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+ of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
--
1.5.3.7
^ permalink raw reply related
* Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Jon Smirl @ 2008-01-02 19:49 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <477BE8F8.9030804@scram.de>
On 1/2/08, Jochen Friedrich <jochen@scram.de> wrote:
>
> Should this go into some central file? Else we would have to copy it in any i2c bus driver that supports powerpc.
> This would at least be i2c-cpm and i2c-gpio.
I can change that in the next rev. I'm waiting to see if there are any
more changes.
> IMHO, there should be a node attribute to override i2c_adapter.class. Legacy i2c drivers (in particular v4l and dvb drivers) use this class to decide which adapter to bind to. dbox2 needs I2C_CLASS_TV_DIGITAL (4).
I hadn't paid any attention to i2c_adapter.class. Now that you mention
it I wonder why i2c has it. It appears to be a holdover from the
older mechanism of searching for devices and it is used as a filter to
reduce the number of device being searched. I would think a new style
driver could just ignore it.
It is probably best to fix it in a successive patch.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Jochen Friedrich @ 2008-01-02 19:41 UTC (permalink / raw)
To: Jon Smirl; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <20071220044144.20091.35917.stgit@terra.home>
Hi Jon,
> Convert MPC i2c driver from being a platform_driver to an open firmware version. Error returns were improved. Routine names were changed from fsl_ to mpc_ to make them match the file name
I did the same for my i2c-cpm. Tested with the frontprocessor driver (dbox2 specific) converted to new style. I'll post the new i2c-cpm, as well.
> +static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node)
> +{
> + struct device_node *node = NULL;
> +
> + while ((node = of_get_next_child(adap_node, node))) {
> + struct i2c_board_info info;
> + const u32 *addr;
> + const char *compatible;
> + int len;
> +
> + addr = of_get_property(node, "reg", &len);
> + if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
> + printk(KERN_ERR "i2c-mpc.c: invalid entry, missing reg attribute\n");
> + continue;
> + }
> +
> + info.irq = irq_of_parse_and_map(node, 0);
> + if (info.irq == NO_IRQ)
> + info.irq = -1;
> +
> + compatible = of_get_property(node, "compatible", &len);
> + if (!compatible) {
> + printk(KERN_ERR "i2c-mpc.c: invalid entry, missing compatible attribute\n");
> + continue;
> + }
> +
> + /* need full alias i2c:NOF,vendor,device */
> + strcpy(info.driver_name, I2C_OF_MODULE_PREFIX);
> + strncat(info.driver_name, compatible, sizeof(info.driver_name));
> + request_module(info.driver_name);
> +
> + /* need module alias OF,vendor,device */
> + strcpy(info.driver_name, OF_I2C_PREFIX);
> + strncat(info.driver_name, compatible, sizeof(info.driver_name));
> +
> + info.type[0] = '\0';
> + info.platform_data = NULL;
> + info.addr = *addr;
> +
> + if (!i2c_new_device(adap, &info)) {
> + printk(KERN_ERR "i2c-mpc.c: Failed to load driver for %s\n", info.driver_name);
> + continue;
> + }
> + }
> +}
Should this go into some central file? Else we would have to copy it in any i2c bus driver that supports powerpc.
This would at least be i2c-cpm and i2c-gpio.
> +static int mpc_i2c_probe(struct of_device *op, const struct of_device_id *match)
> +{
> + int result = 0;
> + struct mpc_i2c *i2c;
> +
> + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
> + if (!i2c)
> + return -ENOMEM;
> +
> + if (of_get_property(op->node, "dfsrr", NULL))
> + i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
> +
> + if (of_device_is_compatible(op->node, "mpc5200-i2c"))
> + i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
> +
> + init_waitqueue_head(&i2c->queue);
> +
> + i2c->base = of_iomap(op->node, 0);
> + if (!i2c->base) {
> + printk(KERN_ERR "i2c-mpc - failed to map controller\n");
> + result = -ENOMEM;
> + goto fail_map;
> + }
> +
> + i2c->irq = irq_of_parse_and_map(op->node, 0);
> + if (i2c->irq == NO_IRQ) {
> + result = -ENXIO;
> + goto fail_irq;
> + }
> +
> + result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c);
> + if (result < 0) {
> + printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
> + goto fail_request;
> + }
> +
> + mpc_i2c_setclock(i2c);
> +
> + dev_set_drvdata(&op->dev, i2c);
> +
> + i2c->adap = mpc_ops;
> + i2c_set_adapdata(&i2c->adap, i2c);
> + i2c->adap.dev.parent = &op->dev;
> +
> + result = i2c_add_adapter(&i2c->adap);
> + if (result < 0) {
> + printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
> + goto fail_add;
> + }
> +
> + of_register_i2c_devices(&i2c->adap, op->node);
> +
> + return result;
> +
> +fail_add:
> + free_irq(i2c->irq, i2c);
> +fail_request:
> + irq_dispose_mapping(i2c->irq);
> +fail_irq:
> + iounmap(i2c->base);
> +fail_map:
> + kfree(i2c);
> + return result;
> +};
IMHO, there should be a node attribute to override i2c_adapter.class. Legacy i2c drivers (in particular v4l and dvb drivers) use this class to decide which adapter to bind to. dbox2 needs I2C_CLASS_TV_DIGITAL (4).
Thanks,
Jochen
^ permalink raw reply
* [PATCH 5/5] [POWERPC] 8xxx and embedded6xx: Use machine_*_initcall() hooks in platform code
From: Grant Likely @ 2008-01-02 19:33 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
In-Reply-To: <20080102191135.24178.99973.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/82xx/mpc8272_ads.c | 5 +----
arch/powerpc/platforms/82xx/pq2fads.c | 5 +----
arch/powerpc/platforms/83xx/mpc832x_mds.c | 5 +----
arch/powerpc/platforms/83xx/mpc832x_rdb.c | 11 ++---------
arch/powerpc/platforms/83xx/mpc834x_mds.c | 5 +----
arch/powerpc/platforms/83xx/mpc836x_mds.c | 5 +----
arch/powerpc/platforms/83xx/mpc837x_mds.c | 5 +----
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 5 +----
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 6 +-----
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 5 +----
arch/powerpc/platforms/8xx/mpc86xads_setup.c | 5 ++---
arch/powerpc/platforms/embedded6xx/ls_uart.c | 5 +----
12 files changed, 14 insertions(+), 53 deletions(-)
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index fd83440..3fce6b3 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -165,14 +165,11 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
- if (!machine_is(mpc8272_ads))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(mpc8272_ads, declare_of_platform_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 1be5005..68196e3 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -176,14 +176,11 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
- if (!machine_is(pq2fads))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(pq2fads, declare_of_platform_devices);
define_machine(pq2fads)
{
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 1e570bb..dbdd4ad 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -110,15 +110,12 @@ static struct of_device_id mpc832x_ids[] = {
static int __init mpc832x_declare_of_platform_devices(void)
{
- if (!machine_is(mpc832x_mds))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL, mpc832x_ids, NULL);
return 0;
}
-device_initcall(mpc832x_declare_of_platform_devices);
+machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices);
static void __init mpc832x_sys_init_IRQ(void)
{
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index ffb2e93..1b57028 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -63,9 +63,6 @@ static struct spi_board_info mpc832x_spi_boardinfo = {
static int __init mpc832x_spi_init(void)
{
- if (!machine_is(mpc832x_rdb))
- return 0;
-
par_io_config_pin(3, 0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */
par_io_config_pin(3, 1, 3, 0, 1, 0); /* SPI1 MISO, I/O */
par_io_config_pin(3, 2, 3, 0, 1, 0); /* SPI1 CLK, I/O */
@@ -79,8 +76,7 @@ static int __init mpc832x_spi_init(void)
mpc83xx_spi_activate_cs,
mpc83xx_spi_deactivate_cs);
}
-
-device_initcall(mpc832x_spi_init);
+machine_device_initcall(mpc832x_rdb, mpc832x_spi_init);
/* ************************************************************************
*
@@ -123,15 +119,12 @@ static struct of_device_id mpc832x_ids[] = {
static int __init mpc832x_declare_of_platform_devices(void)
{
- if (!machine_is(mpc832x_rdb))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL, mpc832x_ids, NULL);
return 0;
}
-device_initcall(mpc832x_declare_of_platform_devices);
+machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices);
void __init mpc832x_rdb_init_IRQ(void)
{
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 459fb72..2b8a0a3 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -115,13 +115,10 @@ static struct of_device_id mpc834x_ids[] = {
static int __init mpc834x_declare_of_platform_devices(void)
{
- if (!machine_is(mpc834x_mds))
- return 0;
-
of_platform_bus_probe(NULL, mpc834x_ids, NULL);
return 0;
}
-device_initcall(mpc834x_declare_of_platform_devices);
+machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices);
/*
* Called very early, MMU is off, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 2ac9890..db491ec 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -141,15 +141,12 @@ static struct of_device_id mpc836x_ids[] = {
static int __init mpc836x_declare_of_platform_devices(void)
{
- if (!machine_is(mpc836x_mds))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL, mpc836x_ids, NULL);
return 0;
}
-device_initcall(mpc836x_declare_of_platform_devices);
+machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices);
static void __init mpc836x_mds_init_IRQ(void)
{
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
index 9cdc32b..cfd0548 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -50,15 +50,12 @@ static struct of_device_id mpc837x_ids[] = {
static int __init mpc837x_declare_of_platform_devices(void)
{
- if (!machine_is(mpc837x_mds))
- return 0;
-
/* Publish of_device */
of_platform_bus_probe(NULL, mpc837x_ids, NULL);
return 0;
}
-device_initcall(mpc837x_declare_of_platform_devices);
+machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices);
static void __init mpc837x_mds_init_IRQ(void)
{
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index bccdc25..a3fa1b0 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -233,13 +233,10 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
- if (!machine_is(mpc85xx_ads))
- return 0;
-
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(mpc85xx_ads, declare_of_platform_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 4d063ee..8b1de78 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -222,9 +222,6 @@ static int mpc85xx_cds_8259_attach(void)
struct device_node *cascade_node = NULL;
int cascade_irq;
- if (!machine_is(mpc85xx_cds))
- return 0;
-
/* Initialize the i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
if (of_device_is_compatible(np, "chrp,iic")) {
@@ -262,8 +259,7 @@ static int mpc85xx_cds_8259_attach(void)
return 0;
}
-
-device_initcall(mpc85xx_cds_8259_attach);
+machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach);
#endif /* CONFIG_PPC_I8259 */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e6c63a5..9f4f3aa 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -144,15 +144,12 @@ static struct of_device_id mpc85xx_ids[] = {
static int __init mpc85xx_publish_devices(void)
{
- if (!machine_is(mpc85xx_mds))
- return 0;
-
/* Publish the QE devices */
of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
return 0;
}
-device_initcall(mpc85xx_publish_devices);
+machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
static void __init mpc85xx_mds_pic_init(void)
{
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index d2927a4..d7965f8 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -128,12 +128,11 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
- if (machine_is(mpc86x_ads))
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(mpc86x_ads, declare_of_platform_devices);
define_machine(mpc86x_ads) {
.name = "MPC86x ADS",
diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c
index c99264c..9d891bd 100644
--- a/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -117,9 +117,6 @@ static int __init ls_uarts_init(void)
phys_addr_t phys_addr;
int len;
- if (!machine_is(linkstation))
- return 0;
-
avr = of_find_node_by_path("/soc10x/serial@80004500");
if (!avr)
return -EINVAL;
@@ -142,4 +139,4 @@ static int __init ls_uarts_init(void)
return 0;
}
-late_initcall(ls_uarts_init);
+machine_late_initcall(linkstation, ls_uarts_init);
^ permalink raw reply related
* [PATCH 4/5] [POWERPC] 8xx: Use machine_*_initcall() hooks in platform code
From: Grant Likely @ 2008-01-02 19:32 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
In-Reply-To: <20080102191135.24178.99973.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/8xx/ep88xc.c | 5 ++---
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 5 ++---
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c
index c518b6c..88afa35 100644
--- a/arch/powerpc/platforms/8xx/ep88xc.c
+++ b/arch/powerpc/platforms/8xx/ep88xc.c
@@ -155,12 +155,11 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
/* Publish the QE devices */
- if (machine_is(ep88xc))
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(ep88xc, declare_of_platform_devices);
define_machine(ep88xc) {
.name = "Embedded Planet EP88xC",
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..6ef8e9e 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -264,12 +264,11 @@ static struct of_device_id __initdata of_bus_ids[] = {
static int __init declare_of_platform_devices(void)
{
/* Publish the QE devices */
- if (machine_is(mpc885_ads))
- of_platform_bus_probe(NULL, of_bus_ids, NULL);
+ of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
-device_initcall(declare_of_platform_devices);
+machine_device_initcall(mpc885_ads, declare_of_platform_devices);
define_machine(mpc885_ads) {
.name = "Freescale MPC885 ADS",
^ permalink raw reply related
* [PATCH 3/5] [POWERPC] pasemi: Use machine_*_initcall() hooks in platform code
From: Grant Likely @ 2008-01-02 19:32 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
In-Reply-To: <20080102191135.24178.99973.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/pasemi/idle.c | 5 +----
arch/powerpc/platforms/pasemi/setup.c | 10 ++--------
2 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c
index d8e1fcc..43911d8 100644
--- a/arch/powerpc/platforms/pasemi/idle.c
+++ b/arch/powerpc/platforms/pasemi/idle.c
@@ -74,9 +74,6 @@ static int pasemi_system_reset_exception(struct pt_regs *regs)
static int __init pasemi_idle_init(void)
{
- if (!machine_is(pasemi))
- return -ENODEV;
-
#ifndef CONFIG_PPC_PASEMI_CPUFREQ
printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n");
current_mode = 0;
@@ -88,7 +85,7 @@ static int __init pasemi_idle_init(void)
return 0;
}
-late_initcall(pasemi_idle_init);
+machine_late_initcall(pasemi, pasemi_idle_init);
static int __init idle_param(char *p)
{
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 1940e67..98c7f3b 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -135,9 +135,6 @@ static int __init pas_setup_mce_regs(void)
struct pci_dev *dev;
int reg;
- if (!machine_is(pasemi))
- return -ENODEV;
-
/* Remap various SoC status registers for use by the MCE handler */
reg = 0;
@@ -181,7 +178,7 @@ static int __init pas_setup_mce_regs(void)
return 0;
}
-device_initcall(pas_setup_mce_regs);
+machine_device_initcall(pasemi, pas_setup_mce_regs);
static __init void pas_init_IRQ(void)
{
@@ -405,9 +402,6 @@ static struct of_device_id pasemi_bus_ids[] = {
static int __init pasemi_publish_devices(void)
{
- if (!machine_is(pasemi))
- return 0;
-
pasemi_pcmcia_init();
/* Publish OF platform devices for SDC and other non-PCI devices */
@@ -415,7 +409,7 @@ static int __init pasemi_publish_devices(void)
return 0;
}
-device_initcall(pasemi_publish_devices);
+machine_device_initcall(pasemi, pasemi_publish_devices);
/*
^ permalink raw reply related
* Re: [PATCH 2/5] [POWERPC] cell: Use machine_*_initcall() hooks in platform code
From: Arnd Bergmann @ 2008-01-02 19:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: olof
In-Reply-To: <20080102191433.24178.68793.stgit@trillian.secretlab.ca>
On Wednesday 02 January 2008, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Looks good, thanks!
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* [PATCH 2/5] [POWERPC] cell: Use machine_*_initcall() hooks in platform code
From: Grant Likely @ 2008-01-02 19:14 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
In-Reply-To: <20080102191135.24178.99973.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/cell/io-workarounds.c | 5 +----
arch/powerpc/platforms/cell/iommu.c | 7 ++-----
arch/powerpc/platforms/cell/pmu.c | 5 +----
arch/powerpc/platforms/cell/setup.c | 5 +----
arch/powerpc/platforms/celleb/iommu.c | 5 +----
arch/powerpc/platforms/celleb/setup.c | 7 ++-----
6 files changed, 8 insertions(+), 26 deletions(-)
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index b86076e..979d4b6 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -309,9 +309,6 @@ static int __init spider_pci_workaround_init(void)
{
struct pci_controller *phb;
- if (!machine_is(cell))
- return 0;
-
/* Find spider bridges. We assume they have been all probed
* in setup_arch(). If that was to change, we would need to
* update this code to cope with dynamically added busses
@@ -343,4 +340,4 @@ static int __init spider_pci_workaround_init(void)
return 0;
}
-arch_initcall(spider_pci_workaround_init);
+machine_arch_initcall(cell, spider_pci_workaround_init);
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 1221c6d..bceb5e1 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -700,10 +700,6 @@ static int __init cell_iommu_init(void)
{
struct device_node *np;
- if (!machine_is(cell) &&
- !machine_is(celleb_native))
- return -ENODEV;
-
/* If IOMMU is disabled or we have little enough RAM to not need
* to enable it, we setup a direct mapping.
*
@@ -746,5 +742,6 @@ static int __init cell_iommu_init(void)
return 0;
}
-arch_initcall(cell_iommu_init);
+machine_arch_initcall(cell, cell_iommu_init);
+machine_arch_initcall(celleb_native, cell_iommu_init);
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index 99d688e..69ed0d7 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -381,9 +381,6 @@ static int __init cbe_init_pm_irq(void)
unsigned int irq;
int rc, node;
- if (!machine_is(cell))
- return 0;
-
for_each_node(node) {
irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
(node << IIC_IRQ_NODE_SHIFT));
@@ -404,7 +401,7 @@ static int __init cbe_init_pm_irq(void)
return 0;
}
-arch_initcall(cbe_init_pm_irq);
+machine_arch_initcall(cell, cbe_init_pm_irq);
void cbe_sync_irq(int node)
{
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 4f6347c..e6534b5 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -85,9 +85,6 @@ static int __init cell_publish_devices(void)
{
int node;
- if (!machine_is(cell))
- return 0;
-
/* Publish OF platform devices for southbridge IOs */
of_platform_bus_probe(NULL, NULL, NULL);
@@ -101,7 +98,7 @@ static int __init cell_publish_devices(void)
}
return 0;
}
-device_initcall(cell_publish_devices);
+machine_device_initcall(cell, cell_publish_devices);
static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
index fbe718d..41e1e6f 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/celleb/iommu.c
@@ -92,9 +92,6 @@ static struct notifier_block celleb_of_bus_notifier = {
static int __init celleb_init_iommu(void)
{
- if (!machine_is(celleb_beat))
- return -ENODEV;
-
celleb_init_direct_mapping();
set_pci_dma_ops(&dma_direct_ops);
bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
@@ -102,4 +99,4 @@ static int __init celleb_init_iommu(void)
return 0;
}
-arch_initcall(celleb_init_iommu);
+machine_arch_initcall(celleb_beat, celleb_init_iommu);
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/celleb/setup.c
index 0f0c468..f27ae1e 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/celleb/setup.c
@@ -111,10 +111,6 @@ static struct of_device_id celleb_bus_ids[] __initdata = {
static int __init celleb_publish_devices(void)
{
- if (!machine_is(celleb_beat) &&
- !machine_is(celleb_native))
- return -ENODEV;
-
/* Publish OF platform devices for southbridge IOs */
of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
@@ -122,7 +118,8 @@ static int __init celleb_publish_devices(void)
return 0;
}
-device_initcall(celleb_publish_devices);
+machine_device_initcall(celleb_beat, celleb_publish_devices);
+machine_device_initcall(celleb_native, celleb_publish_devices);
/*
^ permalink raw reply related
* [PATCH 1/5] [POWERPC] powermac: Use machine_*_initcall() hooks in platform code
From: Grant Likely @ 2008-01-02 19:14 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
In-Reply-To: <20080102191135.24178.99973.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/powermac/low_i2c.c | 7 ++-----
arch/powerpc/platforms/powermac/pfunc_base.c | 3 +--
arch/powerpc/platforms/powermac/pic.c | 3 +--
arch/powerpc/platforms/powermac/setup.c | 12 ++----------
4 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index da2007e..9c9299c 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1462,9 +1462,6 @@ int __init pmac_i2c_init(void)
return 0;
i2c_inited = 1;
- if (!machine_is(powermac))
- return 0;
-
/* Probe keywest-i2c busses */
kw_i2c_probe();
@@ -1483,7 +1480,7 @@ int __init pmac_i2c_init(void)
return 0;
}
-arch_initcall(pmac_i2c_init);
+machine_arch_initcall(powermac, pmac_i2c_init);
/* Since pmac_i2c_init can be called too early for the platform device
* registration, we need to do it at a later time. In our case, subsys
@@ -1515,4 +1512,4 @@ static int __init pmac_i2c_create_platform_devices(void)
return 0;
}
-subsys_initcall(pmac_i2c_create_platform_devices);
+machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index 45d54b9..db20de5 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -363,8 +363,7 @@ int __init pmac_pfunc_base_install(void)
return 0;
}
-
-arch_initcall(pmac_pfunc_base_install);
+machine_arch_initcall(powermac, pmac_pfunc_base_install);
#ifdef CONFIG_PM
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 999f5e1..cd72164 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -690,6 +690,5 @@ static int __init init_pmacpic_sysfs(void)
sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
return 0;
}
-
-subsys_initcall(init_pmacpic_sysfs);
+machine_subsys_initcall(powermac, init_pmacpic_sysfs);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index adad4e9..36ff1b6 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -397,17 +397,13 @@ static int initializing = 1;
static int pmac_late_init(void)
{
- if (!machine_is(powermac))
- return -ENODEV;
-
initializing = 0;
/* this is udbg (which is __init) and we can later use it during
* cpu hotplug (in smp_core99_kick_cpu) */
ppc_md.progress = NULL;
return 0;
}
-
-late_initcall(pmac_late_init);
+machine_late_initcall(powermac, pmac_late_init);
/*
* This is __init_refok because we check for "initializing" before
@@ -534,9 +530,6 @@ static int __init pmac_declare_of_platform_devices(void)
if (machine_is(chrp))
return -1;
- if (!machine_is(powermac))
- return 0;
-
np = of_find_node_by_name(NULL, "valkyrie");
if (np)
of_platform_device_create(np, "valkyrie", NULL);
@@ -551,8 +544,7 @@ static int __init pmac_declare_of_platform_devices(void)
return 0;
}
-
-device_initcall(pmac_declare_of_platform_devices);
+machine_device_initcall(powermac, pmac_declare_of_platform_devices);
/*
* Called very early, MMU is off, device-tree isn't unflattened
^ permalink raw reply related
* [PATCH 0/5] Make platform code use machine_*_initcall() macros
From: Grant Likely @ 2008-01-02 19:14 UTC (permalink / raw)
To: linuxppc-dev, benh, vitb, galak, olof
This series makes the platform code use the new machine-specific initcall
hooks. This has the advantage of not needing to explicitly test
machine_is() at the top of every initcall function.
This time I split the changes out into separate patches so each platform
maintainer can pick up the ones they are responsible for. Please note;
these are untested as I don't have any of the hardware.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox