* cbe_cpufreq crashes my machine
From: Olof Johansson @ 2007-04-26 6:56 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Christian Krafft
In-Reply-To: <200704260147.35878.arnd@arndb.de>
On Thu, Apr 26, 2007 at 01:47:35AM +0200, Arnd Bergmann wrote:
> I can't see any check in here that finds out if you are actually running on
> the right hardware.
Seems like this came along with our use of cbe_cpufreq.c as a basis. You
don't do it either! :-)
Enabling CONFIG_CBE_CPUFREQ makes my machine die a horrible death,
see below. I'd post a patch if I knew what machine compatible fields to
compare with, but I have no clue what's considered approprate to check
for on cell.
Unable to handle kernel paging request for data at address 0x00000888
Faulting instruction address: 0xc000000000036b14
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=2
Modules linked in:
NIP: C000000000036B14 LR: C000000000036B08 CTR: C000000000036A60
REGS: c00000007fd83830 TRAP: 0300 Not tainted (2.6.20)
MSR: 9000000000009032 <EE,ME,IR,DR> CR: 82000022 XER: 20000000
DAR: 0000000000000888, DSISR: 0000000040000000
TASK = c00000000ffc5820[1] 'swapper' THREAD: c00000007fd80000 CPU: 0
GPR00: C00000000093F940 C00000007FD83AB0 C000000000916EC0 0000000000000000
GPR04: C00000000068343F C0000000009C1208 C00000007F8FAE00 0000000000000000
GPR08: C000000000859720 0000000000000888 C0000000009C3DE0 0000000000000000
GPR12: 0000000000000000 C000000000779600 0000000000000000 C000000000684808
GPR16: 4000000000000000 C0000000006834E0 0000000000000000 0000000000000000
GPR20: 0000000000764880 C000000000764880 C000000000764AF0 0000000000764AF0
GPR24: C000000000684308 C00000000085FAE8 C0000000025DD028 0000000000000000
GPR28: FFFFFFFFFFFFFFF4 C00000007F8FAC38 C000000000784B58 C00000007F8FAC00
NIP [C000000000036B14] .cbe_cpufreq_cpu_init+0xb4/0x12c
LR [C000000000036B08] .cbe_cpufreq_cpu_init+0xa8/0x12c
Call Trace:
[C00000007FD83AB0] [C000000000036AA8] .cbe_cpufreq_cpu_init+0x48/0x12c (unreliable)
[C00000007FD83B40] [C0000000004831FC] .cpufreq_add_dev+0x158/0x4f4
[C00000007FD83D00] [C00000000033A5E4] .sysdev_driver_register+0xbc/0x158
[C00000007FD83D90] [C000000000482FF0] .cpufreq_register_driver+0xd0/0x184
[C00000007FD83E40] [C0000000007421B4] .cbe_cpufreq_init+0x1c/0x34
[C00000007FD83EC0] [C0000000000093B4] .init+0x1c4/0x39c
[C00000007FD83F90] [C000000000022E10] .kernel_thread+0x4c/0x68
Instruction dump:
800b0000 2f80fffe 409effe4 e93e8038 380061a8 e87f000e 901f0018 f93f0030
4bffe239 60000000 39230888 7c0004ac <e9230888> 0c090000 4c00012c ebbe8008
-Olof
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Mark A. Greer @ 2007-04-26 6:48 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260402.17248.arnd@arndb.de>
On Thu, Apr 26, 2007 at 04:02:16AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > > location is the smaller part of the problem. Even if it was the right
> > > thing to scan the tree and then create platform_data instead of using
> > > the of_device, that code would still belong into the device driver.
> >
> > I don't think of_device is going to work very well on MIPS.
>
> Ok, I see your point there. But after looking at the i2c and net drivers,
> I believe that they can easily be split into an architecture dependent
> part that is either an of_platform_driver or a platform_driver, and
> a common part that does not know about either of these.
Back when I originally did the mpsc driver I did something similar.
The lkml folks told me pretty clearly to get rid of the arch-specific
code and use platform data. All-in-all, I think that's the best solution
(until all arch's move to a device tree model). So, I think we'll have
to agree to disagree on this.
There does seem to be a lot of duplicate code, though, so we should try
to clean that up (if possible).
Mark
^ permalink raw reply
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
From: Dale Farnsworth @ 2007-04-26 6:33 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260225.27740.arnd@arndb.de>
On Thu, Apr 26, 2007 at 12:25:27AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +void __init mv64x60_pci_init(void)
> > +{
> > + struct device_node *np = NULL;
> > +
> > + ppc_md.pci_exclude_device = mv64x60_exclude_device;
> > +
> > + while ((np = of_find_compatible_node(np, "pci", "mv64x60-pci")))
> > + mv64x60_add_bridge(np);
> > +}
>
> This is a similar mistake to the previous two, but somewhat different:
>
> You actually duplicate code that is already present in of_platform.c.
> AFAICS, all you should need to do is implement the ppc_md.pci_setup_phb()
> function instead of your own handmade device tree scanning.
I find this comment in of_platform.c troubling:
> /* The probing of PCI controllers from of_platform is currently
> * 64 bits only, mostly due to gratuitous differences between
> * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
> * lacking some bits needed here.
> */
Is this comment incorrect?
I agree that this is more code duplication than I like, and we could
benefit from some refactoring. However, I find 15 other places in
arch/powerpc that largely duplicate this pci initialization code.
That doesn't make a 16th right, but at least I'm in good company. :)
-Dale
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Dale Farnsworth @ 2007-04-26 6:08 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260402.17248.arnd@arndb.de>
On Thu, Apr 26, 2007 at 02:02:16AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > > location is the smaller part of the problem. Even if it was the right
> > > thing to scan the tree and then create platform_data instead of using
> > > the of_device, that code would still belong into the device driver.
> >
> > I don't think of_device is going to work very well on MIPS.
>
> Ok, I see your point there. But after looking at the i2c and net drivers,
> I believe that they can easily be split into an architecture dependent
> part that is either an of_platform_driver or a platform_driver, and
> a common part that does not know about either of these.
Oh, it's certainly possible, but it doesn't seem desirable to me. Why
should the drivers carry the burden of supporting both platform_driver
and of_platform_driver interfaces?
-Dale
^ permalink raw reply
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
From: Dale Farnsworth @ 2007-04-26 6:00 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260218.45503.arnd@arndb.de>
On Thu, Apr 26, 2007 at 12:18:45AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > --- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
> > +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > @@ -511,3 +511,138 @@ ret_node_put:
> > }
> >
> >arch_initcall(mv64x60_mpsc_platform_device_init);
> > +
> > +/*
> > + * Create mv64x60_eth platform device
> > + */
> > +static int __init eth_register_shared_pdev(struct device_node *np)
> > +{
> > + struct platform_device *pdev;
>
> No need to put this into architecture specific code, just register
> the of_platform_driver from mv643xx_init_module and use the device
> you get passed in there.
>
> Once arch/ppc is dead, you can remove the platform_driver from mv643xx
> entirely.
Like with the mpsc driver, there is an existing platform-driver-based
ethernet driver used by MIPS and powerpc platforms. OF isn't universal yet.
-Dale
^ permalink raw reply
* Re: [PATCH 3/6] Consolidate of_find_property
From: David Miller @ 2007-04-26 5:58 UTC (permalink / raw)
To: sfr; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070426155449.187f3252.sfr@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 26 Apr 2007 15:54:49 +1000
> Seems the Linus has fixed this problem for us :-)
Yep :-)
> If you and Paul can get your for-2.6.22 trees pulled by Linus, I can
> submit the remaining patches to Linus (with your and Paul's blessing, of
> course).
For sure, I'll be pushing my tree soon.
^ permalink raw reply
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
From: Dale Farnsworth @ 2007-04-26 5:57 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260214.08329.arnd@arndb.de>
On Thu, Apr 26, 2007 at 12:14:07AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +static int __init mv64x60_mpsc_platform_device_init(void)
> > +{
> > + struct device_node *np = NULL;
> > + unsigned int i;
> > + struct platform_device *pdev;
> > + int err;
> > +
> > + for (i = 0; (np = of_find_compatible_node(np, "serial", "mpsc")); i++) {
> > + struct resource r[5];
> > + struct mpsc_pdata pdata;
> > + const unsigned int *prop;
> > + const phandle *ph;
> > + struct device_node *sdma, *brg;
>
> This looks wrong to me. See drivers/serial/of_serial.c to find how we do it for
> 8250 compatible serial ports. You should probably just add your serial port
> stuff in there as well, instead of doing your own scanning of the device tree.
Unfortunately, this hardware is very much non-8250 compatible.
> > + pdev = platform_device_register_simple(MPSC_CTLR_NAME, i, r, 5);
> > + if (IS_ERR(pdev)) {
> > + err = PTR_ERR(pdev);
> > + goto ret_node_put;
> > + }
>
> Now this really needs some explanation.
>
> Why the heck do you have a platform device that gets its resources from
> nonstandard properties of a serial port?
There is an existing mpsc driver usable on both MIPS and powerpc platforms
that requires these non-standard properties.
-Dale
^ permalink raw reply
* Re: [PATCH 3/6] Consolidate of_find_property
From: Stephen Rothwell @ 2007-04-26 5:54 UTC (permalink / raw)
To: David Miller; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070425.161309.02297897.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 594 bytes --]
Hi Dave,
On Wed, 25 Apr 2007 16:13:09 -0700 (PDT) David Miller <davem@davemloft.net> wrote:
>
> Meanwhile any feedback on the idea of pushing all of this
> consolidation and cleanup work through one of our trees
> instead of having all of these difficult dependencies
> between the two?
Seems the Linus has fixed this problem for us :-)
If you and Paul can get your for-2.6.22 trees pulled by Linus, I can
submit the remaining patches to Linus (with your and Paul's blessing, of
course).
--
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 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge
From: Dale Farnsworth @ 2007-04-26 5:49 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260242.39993.arnd@arndb.de>
On Thu, Apr 26, 2007 at 12:42:39AM +0000, Arnd Bergmann wrote:
> > Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > ===================================================================
> > --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> > +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c 2007-04-17 12:48:22.000000000 -0700
> > @@ -0,0 +1,343 @@
> > +/*
> > + * Common routines for the Marvell mv64360/mv64460 host bridges (Discovery)
> > + *
> > +/* Interrupt Controller Interface Registers */
>
> I'd make this a file that _only_ deals with the interrupt controller
> code, and has a respective name, e.g. mv64x60_irq.c
Does anyone else feel strongly about this? I can go either way.
On the one hand, separating out the irq handling might make it
marginally easier to understand. On the other hand, it's nice
to keep all of the mv64x60 support together. I see examples
doing it both ways currently in arch/powerpc/sysdev.
> > +/*
> > + * The bootwrapper sets the coherency of the DMA windows according to
> > + * the setting in the device tree. For the kernel, coherency is a
> > + * compile-time configuration option. Fail if there is a mismatch.
> > + */
> > +
> > +#ifdef CONFIG_NOT_COHERENT_CACHE
> > +#define KERNEL_COHERENCY 0
> > +#else
> > +#define KERNEL_COHERENCY 1
> > +#endif
> > +
> > +int __init mv64x60_verify_cache_coherency(void)
> > +{
> > + struct device_node *np;
> > + const void *prop;
> > + int devtree_coherency;
> > +
> > + np = of_find_node_by_path("/");
> > + prop = of_get_property(np, "coherency-off", NULL);
> > + of_node_put(np);
> > +
> > + devtree_coherency = prop ? 0 : 1;
> > +
> > + if (devtree_coherency != KERNEL_COHERENCY) {
> > + printk(KERN_ERR
> > + "kernel coherency:%s != device tree_coherency:%s\n",
> > + KERNEL_COHERENCY ? "on" : "off",
> > + devtree_coherency ? "on" : "off");
> > + BUG();
> > + }
> > +
> > + return 0;
> > +
> > +late_initcall(mv64x60_verify_cache_coherency);
>
> Not sure where to best put this function, but probably not in the same file as
> your interrupt handling code.
>
> Note that the way your function is written, there is nothing specific to
> mv64x60 in it, and it will actually get called on other machines when the
> file is built-in.
>
> Maybe just rename it to verify_cache_coherency() and put it into
> arch/powerpc/kernel/setup-common.c.
Good point. I'll break it out and submit it separately.
Thanks,
-Dale
^ permalink raw reply
* [PATCH v2] [2.6.22] pasemi: hardware rng driver
From: Olof Johansson @ 2007-04-26 5:37 UTC (permalink / raw)
To: mb; +Cc: linuxppc-dev, egor, arnd
In-Reply-To: <20070425204512.GB19781@lixom.net>
Driver for the on-chip hardware random number generator on PA Semi
PA6T-1682M.
Signed-off-by: Egor Martovetsky <egor@pasemi.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
---
Changes since last version:
* Moved register pointer to hwrng->priv
* Cleanups (__init/__exit, module_init/exit)
Index: powerpc/drivers/char/hw_random/Kconfig
===================================================================
--- powerpc.orig/drivers/char/hw_random/Kconfig
+++ powerpc/drivers/char/hw_random/Kconfig
@@ -91,3 +91,17 @@ config HW_RANDOM_OMAP
module will be called omap-rng.
If unsure, say Y.
+
+config HW_RANDOM_PASEMI
+ tristate "PA Semi HW Random Number Generator support"
+ depends on HW_RANDOM && PPC_PASEMI
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on PA6T-1682M processor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pasemi-rng.
+
+ If unsure, say Y.
+
Index: powerpc/drivers/char/hw_random/Makefile
===================================================================
--- powerpc.orig/drivers/char/hw_random/Makefile
+++ powerpc/drivers/char/hw_random/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_HW_RANDOM_GEODE) += geode-r
obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
+obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
Index: powerpc/drivers/char/hw_random/pasemi-rng.c
===================================================================
--- /dev/null
+++ powerpc/drivers/char/hw_random/pasemi-rng.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2006-2007 PA Semi, Inc
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Driver for the PWRficient onchip rng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <asm/of_platform.h>
+#include <asm/io.h>
+
+#define SDCRNG_CTL_REG 0x00
+#define SDCRNG_CTL_FVLD_M 0x0000f000
+#define SDCRNG_CTL_FVLD_S 12
+#define SDCRNG_CTL_KSZ 0x00000800
+#define SDCRNG_CTL_RSRC_CRG 0x00000010
+#define SDCRNG_CTL_RSRC_RRG 0x00000000
+#define SDCRNG_CTL_CE 0x00000004
+#define SDCRNG_CTL_RE 0x00000002
+#define SDCRNG_CTL_DR 0x00000001
+#define SDCRNG_CTL_SELECT_RRG_RNG (SDCRNG_CTL_RE | SDCRNG_CTL_RSRC_RRG)
+#define SDCRNG_CTL_SELECT_CRG_RNG (SDCRNG_CTL_CE | SDCRNG_CTL_RSRC_CRG)
+#define SDCRNG_VAL_REG 0x20
+
+#define MODULE_NAME "pasemi_rng"
+
+static int pasemi_rng_data_present(struct hwrng *rng)
+{
+ void __iomem *rng_regs = (void __iomem *)rng->priv;
+
+ return (in_le32(rng_regs + SDCRNG_CTL_REG)
+ & SDCRNG_CTL_FVLD_M) ? 1 : 0;
+}
+
+static int pasemi_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ void __iomem *rng_regs = (void __iomem *)rng->priv;
+ *data = in_le32(rng_regs + SDCRNG_VAL_REG);
+ return 4;
+}
+
+static int pasemi_rng_init(struct hwrng *rng)
+{
+ void __iomem *rng_regs = (void __iomem *)rng->priv;
+ u32 ctl;
+
+ ctl = SDCRNG_CTL_DR | SDCRNG_CTL_SELECT_RRG_RNG | SDCRNG_CTL_KSZ;
+ out_le32(rng_regs + SDCRNG_CTL_REG, ctl);
+ out_le32(rng_regs + SDCRNG_CTL_REG, ctl & ~SDCRNG_CTL_DR);
+
+ return 0;
+}
+
+static void pasemi_rng_cleanup(struct hwrng *rng)
+{
+ void __iomem *rng_regs = (void __iomem *)rng->priv;
+ u32 ctl;
+
+ ctl = SDCRNG_CTL_RE | SDCRNG_CTL_CE;
+ out_le32(rng_regs + SDCRNG_CTL_REG,
+ in_le32(rng_regs + SDCRNG_CTL_REG) & ~ctl);
+}
+
+static struct hwrng pasemi_rng = {
+ .name = MODULE_NAME,
+ .init = pasemi_rng_init,
+ .cleanup = pasemi_rng_cleanup,
+ .data_present = pasemi_rng_data_present,
+ .data_read = pasemi_rng_data_read,
+};
+
+static int __devinit rng_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *rng_np = ofdev->node;
+ struct resource res;
+ int err = 0;
+
+ err = of_address_to_resource(rng_np, 0, &res);
+ if (err)
+ return -EINVAL;
+
+ pasemi_rng.priv = (unsigned long)ioremap(res.start, 0x100);
+
+ if (pasemi_rng.priv == 0)
+ return -EPERM;
+
+ printk(KERN_INFO "Registering PA Semi RNG\n");
+
+ return hwrng_register(&pasemi_rng);
+}
+
+static int __devexit rng_remove(struct of_device *dev)
+{
+ void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv;
+
+ iounmap(rng_regs);
+ hwrng_unregister(&pasemi_rng);
+
+ return 0;
+}
+
+static struct of_device_id rng_match[] =
+{
+ {
+ .compatible = "1682m-rng",
+ },
+ {},
+};
+
+static struct of_platform_driver rng_driver =
+{
+ .name = "pasemi-rng",
+ .match_table = rng_match,
+ .probe = rng_probe,
+ .remove = rng_remove,
+};
+
+static int __init rng_init(void)
+{
+ return of_register_platform_driver(&rng_driver);
+}
+module_init(rng_init);
+
+static void __exit rng_exit(void)
+{
+ of_unregister_platform_driver(&rng_driver);
+}
+module_exit(rng_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
+MODULE_DESCRIPTION("H/W RNG driver for PA Semi processor");
^ permalink raw reply
* [PATCH v2] [2.6.22] pasemi: cpufreq driver
From: Olof Johansson @ 2007-04-26 5:37 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev, egor, arnd, cpufreq
In-Reply-To: <20070425204633.GC19781@lixom.net>
Cpufreq driver for PA Semi PWRficient processors.
Signed-off-by: Egor Martovetsky <egor@pasemi.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
---
Changes since last version:
* Attributed copyright correctly to cbe_cpufreq.c and adjust license
to match (this was my mistake)
* Lookup the SDC and Gizmo device nodes to get register bases
* machine_is_compatible checks
* Cleanups as suggested by Arnd + misc whitespace
* Rebased on top of MDIO config patch
I chose not to do this as an of_platform driver since it doesn't fit
that well with the cpufreq driver model; having 3 levels of init/probe
functions is excessive.
Index: powerpc/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pasemi/Makefile
+++ powerpc/arch/powerpc/platforms/pasemi/Makefile
@@ -1,2 +1,3 @@
obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o
obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
+obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
Index: powerpc/arch/powerpc/platforms/pasemi/cpufreq.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Authors: Egor Martovetsky <egor@pasemi.com>
+ * Olof Johansson <olof@lixom.net>
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/cell/cbe_cpufreq.c:
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * 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, 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.
+ *
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/timer.h>
+
+#include <asm/hw_irq.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+#define SDCASR_REG 0x0100
+#define SDCASR_REG_STRIDE 0x1000
+#define SDCPWR_CFGA0_REG 0x0100
+#define SDCPWR_PWST0_REG 0x0000
+#define SDCPWR_GIZTIME_REG 0x0440
+
+/* SDCPWR_GIZTIME_REG fields */
+#define SDCPWR_GIZTIME_GR 0x80000000
+#define SDCPWR_GIZTIME_LONGLOCK 0x000000ff
+
+/* Offset of ASR registers from SDC base */
+#define SDCASR_OFFSET 0x120000
+
+static void __iomem *sdcpwr_mapbase;
+static void __iomem *sdcasr_mapbase;
+
+static DEFINE_MUTEX(pas_switch_mutex);
+
+/* Current astate, is used when waking up from power savings on
+ * one core, in case the other core has switched states during
+ * the idle time.
+ */
+static int current_astate;
+
+/* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */
+static struct cpufreq_frequency_table pas_freqs[] = {
+ {0, 0},
+ {1, 0},
+ {2, 0},
+ {3, 0},
+ {4, 0},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr *pas_cpu_freqs_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+/*
+ * hardware specific functions
+ */
+
+static int get_astate_freq(int astate)
+{
+ u32 ret;
+ ret = in_le32(sdcpwr_mapbase + SDCPWR_CFGA0_REG + (astate * 0x10));
+
+ return ret & 0x3f;
+}
+
+static int get_cur_astate(int cpu)
+{
+ u32 ret;
+
+ ret = in_le32(sdcpwr_mapbase + SDCPWR_PWST0_REG);
+ ret = (ret >> (cpu * 4)) & 0x7;
+
+ return ret;
+}
+
+static int get_gizmo_latency(void)
+{
+ u32 giztime, ret;
+
+ giztime = in_le32(sdcpwr_mapbase + SDCPWR_GIZTIME_REG);
+
+ /* just provide the upper bound */
+ if (giztime & SDCPWR_GIZTIME_GR)
+ ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 128000;
+ else
+ ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 1000;
+
+ return ret;
+}
+
+static void set_astate(int cpu, unsigned int astate)
+{
+ u64 flags;
+
+ /* Return if called before init has run */
+ if (unlikely(!sdcasr_mapbase))
+ return;
+
+ local_irq_save(flags);
+
+ out_le32(sdcasr_mapbase + SDCASR_REG + SDCASR_REG_STRIDE*cpu, astate);
+
+ local_irq_restore(flags);
+}
+
+void restore_astate(int cpu)
+{
+ set_astate(cpu, current_astate);
+}
+
+/*
+ * cpufreq functions
+ */
+
+static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ u32 *max_freq;
+ int i, cur_astate;
+ struct resource res;
+ struct device_node *cpu, *dn;
+ int err = -ENODEV;
+
+ cpu = of_get_cpu_node(policy->cpu, NULL);
+
+ if (!cpu)
+ goto out;
+
+ dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc");
+ if (!dn)
+ goto out;
+ err = of_address_to_resource(dn, 0, &res);
+ of_node_put(dn);
+ if (err)
+ goto out;
+ sdcasr_mapbase = ioremap(res.start + SDCASR_OFFSET, 0x2000);
+ if (!sdcasr_mapbase) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo");
+ if (!dn) {
+ err = -ENODEV;
+ goto out_unmap_sdcasr;
+ }
+ err = of_address_to_resource(dn, 0, &res);
+ of_node_put(dn);
+ if (err)
+ goto out_unmap_sdcasr;
+ sdcpwr_mapbase = ioremap(res.start, 0x1000);
+ if (!sdcpwr_mapbase) {
+ err = -EINVAL;
+ goto out_unmap_sdcasr;
+ }
+
+ pr_debug("init cpufreq on CPU %d\n", policy->cpu);
+
+ max_freq = (u32*) get_property(cpu, "clock-frequency", NULL);
+ if (!max_freq) {
+ err = -EINVAL;
+ goto out_unmap_sdcpwr;
+ }
+
+ /* we need the freq in kHz */
+ *max_freq /= 1000;
+
+ pr_debug("max clock-frequency is at %u kHz\n", *max_freq);
+ pr_debug("initializing frequency table\n");
+
+ /* initialize frequency table */
+ for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
+ pas_freqs[i].frequency = get_astate_freq(pas_freqs[i].index) * 100000;
+ pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
+ }
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = get_gizmo_latency();
+
+ cur_astate = get_cur_astate(policy->cpu);
+ pr_debug("current astate is at %d\n",cur_astate);
+
+ policy->cur = pas_freqs[cur_astate].frequency;
+ policy->cpus = cpu_possible_map;
+
+ cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu);
+
+ /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max
+ * are set correctly
+ */
+ return cpufreq_frequency_table_cpuinfo(policy, pas_freqs);
+
+out_unmap_sdcpwr:
+ iounmap(sdcpwr_mapbase);
+
+out_unmap_sdcasr:
+ iounmap(sdcasr_mapbase);
+out:
+ return err;
+}
+
+static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ if (sdcasr_mapbase)
+ iounmap(sdcasr_mapbase);
+ if (sdcpwr_mapbase)
+ iounmap(sdcpwr_mapbase);
+
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static int pas_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, pas_freqs);
+}
+
+static int pas_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ int pas_astate_new;
+ int i;
+
+ cpufreq_frequency_table_target(policy,
+ pas_freqs,
+ target_freq,
+ relation,
+ &pas_astate_new);
+
+ freqs.old = policy->cur;
+ freqs.new = pas_freqs[pas_astate_new].frequency;
+ freqs.cpu = policy->cpu;
+
+ mutex_lock(&pas_switch_mutex);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
+ policy->cpu,
+ pas_freqs[pas_astate_new].frequency,
+ pas_freqs[pas_astate_new].index);
+
+ current_astate = pas_astate_new;
+
+ for_each_online_cpu(i)
+ set_astate(i, pas_astate_new);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&pas_switch_mutex);
+
+ return 0;
+}
+
+static struct cpufreq_driver pas_cpufreq_driver = {
+ .name = "pas-cpufreq",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = pas_cpufreq_cpu_init,
+ .exit = pas_cpufreq_cpu_exit,
+ .verify = pas_cpufreq_verify,
+ .target = pas_cpufreq_target,
+ .attr = pas_cpu_freqs_attr,
+};
+
+/*
+ * module init and destoy
+ */
+
+static int __init pas_cpufreq_init(void)
+{
+ if (!machine_is_compatible("PA6T-1682M"))
+ return 0;
+
+ return cpufreq_register_driver(&pas_cpufreq_driver);
+}
+
+static void __exit pas_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&pas_cpufreq_driver);
+}
+
+module_init(pas_cpufreq_init);
+module_exit(pas_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>, Olof Johansson <olof@lixom.net>");
Index: powerpc/arch/powerpc/platforms/pasemi/idle.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pasemi/idle.c
+++ powerpc/arch/powerpc/platforms/pasemi/idle.c
@@ -61,6 +61,10 @@ static int pasemi_system_reset_exception
/* do system reset */
return 0;
}
+
+ /* Set higher astate since we come out of power savings at 0 */
+ restore_astate(hard_smp_processor_id());
+
/* everything handled */
regs->msr |= MSR_RI;
return 1;
@@ -68,6 +72,11 @@ static int pasemi_system_reset_exception
void __init pasemi_idle_init(void)
{
+#ifndef CONFIG_PPC_PASEMI_CPUFREQ
+ printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n");
+ current_mode = 0;
+#endif
+
ppc_md.system_reset_exception = pasemi_system_reset_exception;
ppc_md.power_save = modes[current_mode].entry;
printk(KERN_INFO "Using PA6T idle loop (%s)\n", modes[current_mode].name);
Index: powerpc/arch/powerpc/platforms/pasemi/pasemi.h
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pasemi/pasemi.h
+++ powerpc/arch/powerpc/platforms/pasemi/pasemi.h
@@ -14,6 +14,14 @@ extern void __init pasemi_idle_init(void
extern void idle_spin(void);
extern void idle_doze(void);
+/* Restore astate to last set */
+#ifdef CONFIG_PPC_PASEMI_CPUFREQ
+extern void restore_astate(int cpu);
+#else
+static inline void restore_astate(int cpu)
+{
+}
+#endif
#endif /* _PASEMI_PASEMI_H */
Index: powerpc/arch/powerpc/platforms/Kconfig
===================================================================
--- powerpc.orig/arch/powerpc/platforms/Kconfig
+++ powerpc/arch/powerpc/platforms/Kconfig
@@ -169,6 +169,16 @@ config CPU_FREQ_PMAC64
help
This adds support for frequency switching on Apple iMac G5,
and some of the more recent desktop G5 machines as well.
+
+config PPC_PASEMI_CPUFREQ
+ bool "Support for PA Semi PWRficient"
+ depends on PPC_PASEMI
+ default y
+ select CPU_FREQ_TABLE
+ help
+ This adds the support for frequency switching on PA Semi
+ PWRficient processors.
+
endmenu
config PPC601_SYNC_FIX
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Arnd Bergmann @ 2007-04-26 2:02 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070426011328.GR4046@mag.az.mvista.com>
On Thursday 26 April 2007, Mark A. Greer wrote:
> > location is the smaller part of the problem. Even if it was the right
> > thing to scan the tree and then create platform_data instead of using
> > the of_device, that code would still belong into the device driver.
>
> I don't think of_device is going to work very well on MIPS.
Ok, I see your point there. But after looking at the i2c and net drivers,
I believe that they can easily be split into an architecture dependent
part that is either an of_platform_driver or a platform_driver, and
a common part that does not know about either of these.
With the example of the i2c driver, you can have something like:
i2c-mv64xxx.c:
=============
int __devinit mv64xxx_i2c_probe(struct device *dev, struct mv64xxx_i2c_pdata *data,
struct resource *regs, int irq)
{
...
}
EXPORT_SYMBOL_GPL(mv64xxx_i2c_probe);
int __devexit mv64xxx_i2c_remove(struct device *dev)
{
...
}
EXPORT_SYMBOL_GPL(mv64xxx_i2c_remove);
i2c-mv64xxx-pdev.c:
========================
static int __devinit mv64xxx_i2c_probe_pdev(struct platform_device *pd)
{
return mv64xxx_i2c_probe(&pd->dev, &pd->dev.platform_data,
platform_get_resource(pd, IORESOURCE_MEM, 0)),
platform_get_irq(pd, 0));
}
static int __devexit mv64xxx_i2c_remove_pdev(struct platform_device *pd)
{
return mv64xxx_i2c_remove(&pd->dev);
}
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe_pdev,
.remove = mv64xxx_i2c_remove_pdev,
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
},
};
static int __init
mv64xxx_i2c_init_pdev(void)
{
return platform_driver_register(&mv64xxx_i2c_driver);
}
static void __exit
mv64xxx_i2c_exit_pdev(void)
{
platform_driver_unregister(&mv64xxx_i2c_driver);
}
module_init(mv64xxx_i2c_init_pdev);
module_exit(mv64xxx_i2c_exit_pdev);
i2c-mv64xxx-of.c:
========================
static int __devinit mv64xxx_i2c_probe_of(struct of_device *dev)
{
struct mv64xxx_i2c_pdata pdata;
struct resource resource;
int irq;
of_address_to_resource(&dev->node, 0, &resource);
of_map_irq(&dev->node, 0, &irq);
return mv64xxx_i2c_probe(&dev->dev, &pdata, &resource, irq);
}
static int __devexit mv64xxx_i2c_remove_pdev(struct of_device *dev)
{
return mv64xxx_i2c_remove(&dev->dev);
}
static struct of_device_id mv64xxx_i2c_device_ids = {
{ .type = "i2c", .compatible = "mv64x60-i2c" },
{ },
};
static struct of_platform_driver mv64xxx_i2c_of_driver = {
.probe = mv64xxx_i2c_probe_of,
.remove = mv64xxx_i2c_remove_of,
.ids = &mv64xxx_i2c_device_ids,
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
},
};
static int __init
mv64xxx_i2c_init_of(void)
{
return of_platform_driver_register(&mv64xxx_i2c_of_driver);
}
static void __exit
mv64xxx_i2c_exit_of(void)
{
of_platform_driver_unregister(&mv64xxx_i2c_driver);
}
module_init(mv64xxx_i2c_init_of);
module_exit(mv64xxx_i2c_exit_of);
^ permalink raw reply
* Re: [PATCH] [2.6.22] pasemi: cpufreq driver
From: Olof Johansson @ 2007-04-26 1:57 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, egor, paulus, cpufreq
In-Reply-To: <20070425235757.GA20905@lixom.net>
On Wed, Apr 25, 2007 at 06:57:57PM -0500, olof wrote:
> 2) See the idle loop interaction: It can go tristate once we have runtime
> selection of idle loop, but until then we need it for idle=doze.
Grmbl. Looks like I posted a stale patch that actually won't build with
PPC_PASEMI_CPUFREQ=n. I'll repost with the correct version.
-Olof
^ permalink raw reply
* Re: [PATCH 4/6] Consolidate of_get_parent
From: Stephen Rothwell @ 2007-04-26 1:34 UTC (permalink / raw)
To: Loeliger Jon-LOELIGER; +Cc: ppc-dev, paulus, David S. Miller
In-Reply-To: <AF0367BA48C55940A43CCF08DF35553C011ECCC9@az33exm24.fsl.freescale.net>
[-- Attachment #1: Type: text/plain, Size: 375 bytes --]
On Tue, 24 Apr 2007 07:42:56 -0700 "Loeliger Jon-LOELIGER" <jdl@freescale.com> wrote:
>
> > sparc64. It also adds a readlocal around the parent accesses.
> >
> > Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
>
> Perhaps a read lock?
Yeah, just a small typo :-)
--
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 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
From: Mark A. Greer @ 2007-04-26 1:15 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070426005853.GQ4046@mag.az.mvista.com>
On Wed, Apr 25, 2007 at 05:58:53PM -0700, Mark A. Greer wrote:
> Well, its not really the ctlr init. That is done in the kernel
> driver(s). What's being set up are the windows that allow the ctlrs to
> access system memory. This should really be done the the firmware but
^^^ "by"
> isn't so I think the bootwrapper is the proper place to do it.
>
> AFA PCI, its setting up the window from cpu phys->PCI MEM & I/O,
> and PCI MEM->system mem. I think its better to not have that in the
> kernel--bloats the kernel and mv64x60 with better fw (which is most of
^ "platforms"
Mark
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Mark A. Greer @ 2007-04-26 1:13 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260255.04490.arnd@arndb.de>
On Thu, Apr 26, 2007 at 02:55:03AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > of_find_compatible_node() is not being called from a driver, its being
> > called from platform code. Its extracting info from the device tree and
> > setting up the platform_data required by the driver.
>
> Well, the idea of putting the device driver code into a platform specific
It isn't device driver code. It providing the driver with some info
that it needs but doesn't have the ability to get, in general.
> location is the smaller part of the problem. Even if it was the right
> thing to scan the tree and then create platform_data instead of using
> the of_device, that code would still belong into the device driver.
I don't think of_device is going to work very well on MIPS.
Mark
^ permalink raw reply
* Re: [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
From: Mark A. Greer @ 2007-04-26 0:58 UTC (permalink / raw)
To: Mark A. Greer, Paul Mackerras, linuxppc-dev
In-Reply-To: <20070426004514.GC2193@localhost.localdomain>
On Thu, Apr 26, 2007 at 10:45:14AM +1000, David Gibson wrote:
> On Wed, Apr 25, 2007 at 04:46:30PM -0700, Mark A. Greer wrote:
> > The following set of patches add support for the Motorola prpmc2800/f101e platform.
> > To support that platform, several other patches are required that can be grouped as
> > follows:
> >
> > - 1 patch to add Makefile rules that automatically compile & wrap a dts into
> > a zImage
> > - 1 patch to add a new interface to the dt_xlate code.
> > - 3 mv64x60 bootwrapper patches
> > - 5 mv64x60 kernel patches
> > - 3 prpmc2800 patches
>
> Hrm. This series adds an awful lot of code to the bootwrapper. Is
> there really no reasonable way to trim it, perhaps moving some of the
> initialization to the kernel driver proper? I can see that memory
> controller setup and serial might need to be in the wrapper, but PCI
> and I2C initialization?
Well, its not really the ctlr init. That is done in the kernel
driver(s). What's being set up are the windows that allow the ctlrs to
access system memory. This should really be done the the firmware but
isn't so I think the bootwrapper is the proper place to do it.
AFA PCI, its setting up the window from cpu phys->PCI MEM & I/O,
and PCI MEM->system mem. I think its better to not have that in the
kernel--bloats the kernel and mv64x60 with better fw (which is most of
them hopefully) don't need it.
Another thing to remember is that the marvell bridges are used on MIPS
platforms and therefore the drivers can potentially be used there too.
That makes it doubly important to not dump setup that should be done by
the fw into kernel drivers.
Mark
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Arnd Bergmann @ 2007-04-26 0:55 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070426004302.GP4046@mag.az.mvista.com>
On Thursday 26 April 2007, Mark A. Greer wrote:
> of_find_compatible_node() is not being called from a driver, its being
> called from platform code. =A0Its extracting info from the device tree and
> setting up the platform_data required by the driver.
Well, the idea of putting the device driver code into a platform specific
location is the smaller part of the problem. Even if it was the right
thing to scan the tree and then create platform_data instead of using
the of_device, that code would still belong into the device driver.
Note that the interrupt controller code in patch 6 is different, because
it is not possible to probe interrupt controllers using the Linux
driver model -- any device driver that gets initialized must assume
that the interrupt controller code and some other infrastructure is
already running.
Arnd <><
^ permalink raw reply
* Re: [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
From: David Gibson @ 2007-04-26 0:45 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070425234630.GA4046@mag.az.mvista.com>
On Wed, Apr 25, 2007 at 04:46:30PM -0700, Mark A. Greer wrote:
> The following set of patches add support for the Motorola prpmc2800/f101e platform.
> To support that platform, several other patches are required that can be grouped as
> follows:
>
> - 1 patch to add Makefile rules that automatically compile & wrap a dts into
> a zImage
> - 1 patch to add a new interface to the dt_xlate code.
> - 3 mv64x60 bootwrapper patches
> - 5 mv64x60 kernel patches
> - 3 prpmc2800 patches
Hrm. This series adds an awful lot of code to the bootwrapper. Is
there really no reasonable way to trim it, perhaps moving some of the
initialization to the kernel driver proper? I can see that memory
controller setup and serial might need to be in the wrapper, but PCI
and I2C initialization?
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge
From: Arnd Bergmann @ 2007-04-26 0:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20070425235858.GH4046@mag.az.mvista.com>
> Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c 2007-04-17 12:48:22.000000000 -0700
> @@ -0,0 +1,343 @@
> +/*
> + * Common routines for the Marvell mv64360/mv64460 host bridges (Discovery)
> + *
> +/* Interrupt Controller Interface Registers */
I'd make this a file that _only_ deals with the interrupt controller
code, and has a respective name, e.g. mv64x60_irq.c
> +/*
> + * The bootwrapper sets the coherency of the DMA windows according to
> + * the setting in the device tree. For the kernel, coherency is a
> + * compile-time configuration option. Fail if there is a mismatch.
> + */
> +
> +#ifdef CONFIG_NOT_COHERENT_CACHE
> +#define KERNEL_COHERENCY 0
> +#else
> +#define KERNEL_COHERENCY 1
> +#endif
> +
> +int __init mv64x60_verify_cache_coherency(void)
> +{
> + struct device_node *np;
> + const void *prop;
> + int devtree_coherency;
> +
> + np = of_find_node_by_path("/");
> + prop = of_get_property(np, "coherency-off", NULL);
> + of_node_put(np);
> +
> + devtree_coherency = prop ? 0 : 1;
> +
> + if (devtree_coherency != KERNEL_COHERENCY) {
> + printk(KERN_ERR
> + "kernel coherency:%s != device tree_coherency:%s\n",
> + KERNEL_COHERENCY ? "on" : "off",
> + devtree_coherency ? "on" : "off");
> + BUG();
> + }
> +
> + return 0;
> +
> +late_initcall(mv64x60_verify_cache_coherency);
Not sure where to best put this function, but probably not in the same file as
your interrupt handling code.
Note that the way your function is written, there is nothing specific to
mv64x60 in it, and it will actually get called on other machines when the
file is built-in.
Maybe just rename it to verify_cache_coherency() and put it into
arch/powerpc/kernel/setup-common.c.
Arnd <><
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Mark A. Greer @ 2007-04-26 0:43 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200704260221.20150.arnd@arndb.de>
On Thu, Apr 26, 2007 at 02:21:19AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +static int __init mv64x60_i2c_platform_device_init(void)
> > +{
> > + struct device_node *np = NULL;
> > + int i;
> > + struct platform_device *pdev;
> > + int err;
> > +
> > + for (i = 0;
> > + (np = of_find_compatible_node(np, "i2c", "mv64x60-i2c"));
>
> Same comment as about the ethernet driver: You should register an
> of_platform_driver from drivers/i2c/busses/i2c-mv64xxx.c.
>
> Repeat after me:
>
> I will not call of_find_compatible_node() from device drivers.
> I will not call of_find_compatible_node() from device drivers.
> I will not call of_find_compatible_node() from device drivers.
Well, your comments are for Dale's patches so I'll leave it to him to
answer your questions in detail but...
of_find_compatible_node() is not being called from a driver, its being
called from platform code. Its extracting info from the device tree and
setting up the platform_data required by the driver.
Mark
^ permalink raw reply
* Re: [PATCH] powerpc: Add EDAC platform devices for 85xx
From: Dave Jiang @ 2007-04-26 0:37 UTC (permalink / raw)
To: linuxppc-dev, galak, afleming; +Cc: bluesmoke-devel, david
In-Reply-To: <20070426000852.GA2193@localhost.localdomain>
Add memory controller and l2-cache controller entries in the dts files for 85xx
platforms. Also adding code to create the platform devices used by EDAC drivers
to claim the resources in order to access the error registers and interrupts.
Signed-off-by: Dave Jiang <djiang@mvista.com>
---
Removed explicit phandles as suggested by David Gibson.
arch/powerpc/boot/dts/mpc8540ads.dts | 19 ++++++
arch/powerpc/boot/dts/mpc8548cds.dts | 19 ++++++
arch/powerpc/boot/dts/mpc8560ads.dts | 21 ++++++-
arch/powerpc/sysdev/fsl_soc.c | 115 ++++++++++++++++++++++++++++++++++
4 files changed, 173 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index f261d64..63c274d 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -48,6 +48,25 @@
reg = <e0000000 00100000>; // CCSRBAR 1M
bus-frequency = <0>;
+ mem-ctrl@2000 {
+ device_type = "mem-ctrl";
+ compatible = "85xx";
+ reg = <2000 1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <2 2>;
+ };
+
+ l2-cache@20000 {
+ device_type = "l2-cache";
+ compatible = "85xx";
+ reg = <20000 1000>;
+ cache-line-size = <20>; // 32 bytes
+ cache-size = <40000>; // L2, 256K
+ 32-bit;
+ interrupt-parent = <&mpic>;
+ interrupts = <0 2>;
+ };
+
i2c@3000 {
device_type = "i2c";
compatible = "fsl-i2c";
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index b2b2200..f8a9f3f 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -48,6 +48,25 @@
reg = <e0000000 00100000>; // CCSRBAR 1M
bus-frequency = <0>;
+ mem-ctrl@2000 {
+ device_type = "mem-ctrl";
+ compatible = "85xx";
+ reg = <2000 1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <2 2>;
+ };
+
+ l2-cache@20000 {
+ device_type = "l2-cache";
+ compatible = "85xx";
+ reg = <20000 1000>;
+ cache-line-size = <20>; // 32 bytes
+ cache-size = <40000>; // L2, 256K
+ 32-bit;
+ interrupt-parent = <&mpic>;
+ interrupts = <0 2>;
+ };
+
i2c@3000 {
device_type = "i2c";
compatible = "fsl-i2c";
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 1f2afe9..43ee847 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -48,6 +48,25 @@
reg = <e0000000 00000200>;
bus-frequency = <13ab6680>;
+ mem-ctrl@2000 {
+ device_type = "mem-ctrl";
+ compatible = "85xx";
+ reg = <2000 1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <2 2>;
+ };
+
+ l2-cache@20000 {
+ device_type = "l2-cache";
+ compatible = "85xx";
+ reg = <20000 1000>;
+ cache-line-size = <20>; // 32 bytes
+ cache-size = <40000>; // L2, 256K
+ 32-bit;
+ interrupt-parent = <&mpic>;
+ interrupts = <0 2>;
+ };
+
mdio@24520 {
device_type = "mdio";
compatible = "gianfar";
@@ -110,7 +129,7 @@
#address-cells = <3>;
compatible = "85xx";
device_type = "pci";
- reg = <8000 400>;
+ reg = <8000 1000>;
clock-frequency = <3f940aa>;
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 8a123c7..a0beb8b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1103,3 +1103,118 @@ err:
arch_initcall(cpm_smc_uart_of_init);
#endif /* CONFIG_8xx */
+
+/* platform device setup for EDAC */
+#ifdef CONFIG_PPC_85xx
+static int __init mpc85xx_mc_err_init(void)
+{
+ struct resource r[2];
+ struct device_node *np;
+ struct platform_device *pdev;
+ int ret = 0;
+
+ memset(r, 0, sizeof(r));
+
+ np = of_find_compatible_node(NULL, "mem-ctrl", "85xx");
+ if (!np)
+ return 0;
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ of_irq_to_resource(np, 0, &r[1]);
+
+ of_node_put(np);
+
+ pdev = platform_device_register_simple("mpc85xx_mc_err", 0, r, 2);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+
+err:
+ of_node_put(np);
+ printk(KERN_WARNING "mpc85xx-mem-ctrl setup failed\n");
+ return 0;
+}
+arch_initcall(mpc85xx_mc_err_init);
+
+static int __init mpc85xx_l2_err_init(void)
+{
+ struct resource r[2];
+ struct device_node *np;
+ struct platform_device *pdev;
+ int ret = 0;
+
+ memset(r, 0, sizeof(r));
+
+ np = of_find_compatible_node(NULL, "l2-cache", "85xx");
+ if (!np)
+ return 0;
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ /* we only need access to the error registers */
+ r[0].start += 0xe00;
+
+ of_irq_to_resource(np, 0, &r[1]);
+
+ of_node_put(np);
+
+ pdev = platform_device_register_simple("mpc85xx_l2_err", 0, r, 2);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+
+err:
+ of_node_put(np);
+ printk(KERN_WARNING "mpc85xx-l2 setup failed\n");
+ return 0;
+}
+arch_initcall(mpc85xx_l2_err_init);
+
+static int __init mpc85xx_pci_err_init(void)
+{
+ struct resource r[2];
+ struct device_node *np = NULL;
+ struct platform_device *pdev;
+ int i;
+ int ret = 0;
+
+ for (i = 0;
+ (np = of_find_compatible_node(np, "pci", "85xx"));
+ i++) {
+ memset(r, 0, sizeof(r));
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ /* we only need access to the error registers */
+ r[0].start += 0xe00;
+
+ of_irq_to_resource(np, 0, &r[1]);
+
+ pdev = platform_device_register_simple("mpc85xx_pci_err",
+ i, r, 2);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto err;
+ }
+
+ }
+
+ return 0;
+
+err:
+ of_node_put(np);
+ printk(KERN_WARNING "mpc85xx-pci setup failed\n");
+ return ret;
+}
+arch_initcall(mpc85xx_pci_err_init);
+
+#endif /* CONFIG_PPC_85xx */
^ permalink raw reply related
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
From: Arnd Bergmann @ 2007-04-26 0:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20070426000107.GL4046@mag.az.mvista.com>
On Thursday 26 April 2007, Mark A. Greer wrote:
> +void __init mv64x60_pci_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct device_node *np =3D NULL;
> +
> +=A0=A0=A0=A0=A0=A0=A0ppc_md.pci_exclude_device =3D mv64x60_exclude_devic=
e;
> +
> +=A0=A0=A0=A0=A0=A0=A0while ((np =3D of_find_compatible_node(np, "pci", "=
mv64x60-pci")))
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0mv64x60_add_bridge(np);
> +}
This is a similar mistake to the previous two, but somewhat different:
You actually duplicate code that is already present in of_platform.c.
AFAICS, all you should need to do is implement the ppc_md.pci_setup_phb()
function instead of your own handmade device tree scanning.
Arnd <><
^ permalink raw reply
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Arnd Bergmann @ 2007-04-26 0:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20070426000043.GK4046@mag.az.mvista.com>
On Thursday 26 April 2007, Mark A. Greer wrote:
> +static int __init mv64x60_i2c_platform_device_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct device_node *np =3D NULL;
> +=A0=A0=A0=A0=A0=A0=A0int i;
> +=A0=A0=A0=A0=A0=A0=A0struct platform_device *pdev;
> +=A0=A0=A0=A0=A0=A0=A0int err;
> +
> +=A0=A0=A0=A0=A0=A0=A0for (i =3D 0;
> +=A0=A0=A0=A0=A0=A0=A0 =A0 =A0 (np =3D of_find_compatible_node(np, "i2c",=
"mv64x60-i2c"));
Same comment as about the ethernet driver: You should register an
of_platform_driver from drivers/i2c/busses/i2c-mv64xxx.c.
Repeat after me:=20
I will not call of_find_compatible_node() from device drivers.
I will not call of_find_compatible_node() from device drivers.
I will not call of_find_compatible_node() from device drivers.
Arnd <><
^ permalink raw reply
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
From: Arnd Bergmann @ 2007-04-26 0:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20070426000009.GJ4046@mag.az.mvista.com>
On Thursday 26 April 2007, Mark A. Greer wrote:
> Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> =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=3D=3D=3D=3D=3D=3D=3D=3D
> --- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
> +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> @@ -511,3 +511,138 @@ ret_node_put:
> =A0}
> =A0
> =A0arch_initcall(mv64x60_mpsc_platform_device_init);
> +
> +/*
> + * Create mv64x60_eth platform device
> + */
> +static int __init eth_register_shared_pdev(struct device_node *np)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct platform_device *pdev;
No need to put this into architecture specific code, just register
the of_platform_driver from mv643xx_init_module and use the device
you get passed in there.
Once arch/ppc is dead, you can remove the platform_driver from mv643xx
entirely.
Arnd <><
^ 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