* Re: [PATCH 2/2] [POWERPC] MPC8349E-mITX: use platform IDE driver for CF interface
From: Alan Cox @ 2007-07-31 23:56 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, linux-ide, linux-kernel
In-Reply-To: <a414f3b506b7802a717e6e2c08befd1e@kernel.crashing.org>
> The hardware is called (E)IDE, the protocol is called ATA.
> Or that's what I was told -- I think there's some historic
> revisionism involved, too.
ATA is the interface and standards for the ANSI standards based disk
attachment. IDE "Integrated Drive Electronics" is a marketing name used
to cover all sorts of ST412 compatible-ish early interfaces that moved
the brains onto the disk. IDE doesn't really mean much but "brains on
disk", ATA is a real standard.
^ permalink raw reply
* Re: [PATCH 1/3] Add a new member name to structure irq_host
From: Segher Boessenkool @ 2007-07-31 23:42 UTC (permalink / raw)
To: michael; +Cc: linuxppc-dev, Chen Gong, paulus
In-Reply-To: <1185923183.5380.0.camel@concordia.ozlabs.ibm.com>
>>> In that case, I would display the node full path.
>>
>> Those tend to be quite long, in the cases where there are
>> multiple interrupt controllers in the system; and really
>> useless otherwise. I think the interrupt controllers should
>> still just fill in the names "manually".
>
> They tend to be long, but they're unique, which is what you want,
Yeah -- easy enough to add a sequence number to just about
anything though.
> and they're only for debugging anyway.
Oh, I thought it would be used wherever the user gets told something
about the interrupt controller -- like when the interrupt tree would
be shown in sysfs (yes that's hypothetical still ;-) )
>> It's a good thing to have an of_node in the irq_host struct
>> anyway, though :-)
>
> I posted patches for that last week.
I know, and thank you :-)
Segher
^ permalink raw reply
* Re: [PATCH 1/3] Add a new member name to structure irq_host
From: Michael Ellerman @ 2007-07-31 23:06 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Chen Gong, paulus, linuxppc-dev
In-Reply-To: <91856a9e02132d2deb4368eee954c931@kernel.crashing.org>
[-- Attachment #1: Type: text/plain, Size: 1609 bytes --]
On Wed, 2007-08-01 at 00:13 +0200, Segher Boessenkool wrote:
> >>> Which makes me think (again) that we should have an optional
> >>> device_node
> >>> pointer in irq_host. I know you said you wanted the irq stuff to be
> >>> OF
> >>> agnostic, but the reality is most of the implementations do have an
> >>> OF
> >>> node. And all of the newer irq_host implementations do, with the
> >>> exception of PS3 and celleb - which are special.
> >>
> >> How do you suggest to get a reasonable display name out of
> >> the device tree? The recommended human-readable name for
> >> interrupt controller nodes is "interrupt-controller"...
> >> You cannot use "device_type" either, and using "compatible"
> >> requires selecting one of its string entries, and likely
> >> using a lookup table after that, too.
> >
> > In that case, I would display the node full path.
>
> Those tend to be quite long, in the cases where there are
> multiple interrupt controllers in the system; and really
> useless otherwise. I think the interrupt controllers should
> still just fill in the names "manually".
They tend to be long, but they're unique, which is what you want, and
they're only for debugging anyway.
> It's a good thing to have an of_node in the irq_host struct
> anyway, though :-)
I posted patches for that last week.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc: Add of_register_i2c_devices()
From: Segher Boessenkool @ 2007-07-31 22:55 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <Pine.LNX.4.60.0707202219340.3946@poirot.grange>
>>> + strncpy(info->driver_name, i2c_devices[i].i2c_driver,
>>> KOBJ_NAME_LEN);
>>> + strncpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE);
>>
>> Why not just strcpy(), btw?
>
> Because target strings are finite length, and sources are just
> pointers to
> some constant strings, which one might make arbitrarily long.
So it's no problem if the name or type string gets cut short?
Just checking :-)
Segher
^ permalink raw reply
* Re: [PATCH 2/2] [POWERPC] MPC8349E-mITX: use platform IDE driver for CF interface
From: Segher Boessenkool @ 2007-07-31 22:47 UTC (permalink / raw)
To: Scott Wood; +Cc: linux-ide, linux-kernel, linuxppc-dev
In-Reply-To: <46A798D8.7020906@freescale.com>
>> I never suggested that -- what I did suggest was make of_serial.c
>> recognize certain chip types and register them with 8250 driver.
>
> What would be the advantage of maintaining a list of chips whose only
> difference is register spacing, rather than just using reg-shift and
> being done with it?
reg-shift alone isn't enough to know how to access the device
registers. In the case of UARTs, they typically are internal
to some SoC, so the device driver can just look up what SoC it
is and will then know what to do. For IDE though, as far as I
understand it typically is board-specific, done by some glue
logic off of some GPIOs or on an FPGA; I think detection is best
handled by platform code in this case, an "mmio-ide" shim driver
would be helpful of course.
Segher
^ permalink raw reply
* Re: [PATCH 2/2] [POWERPC] MPC8349E-mITX: use platform IDE driver for CF interface
From: Segher Boessenkool @ 2007-07-31 22:36 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linux-ide, linuxppc-dev, linux-kernel
In-Reply-To: <46A78E3F.1030904@ru.mvista.com>
>>> + ide@f0000000 {
>>> + compatible = "mmio-ide";
>>> + device_type = "ide";
>
>> Why not "ata"?
The hardware is called (E)IDE, the protocol is called ATA.
Or that's what I was told -- I think there's some historic
revisionism involved, too.
> Also, what mmio-ide in the compat properly means in the context of
> ide_platform which is able to handle both port and memory mapped IDE.
> I think
> we must get rid with this crap, and since this IDE register mapping is
> pretty
> much board specific, call it something like "mpc8349emitx-ide" instead.
"mmio-ide" simply is not specific enough. The device_type
should go, too.
If this IDE interface is board-specific, thee "compatible"
property should include the board vendor name and board
name. Oh, that's what "emitx" tries to do -- it could be
a bit clearer perhaps ;-)
Segher
^ permalink raw reply
* Re: [PATCH 1/2] [IDE] Platform IDE driver
From: Segher Boessenkool @ 2007-07-31 22:31 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev, linux-kernel, linux-ide
In-Reply-To: <46A7A5E4.4090105@ru.mvista.com>
> This doesn't mean that shift is better anyway. If everyone
> considers it
> better, I give up. But be warned that shift (stride) is not the only
> property
> characterizing register accesses -- the regs might be only accessible
> as
> 16/32-bit quantities, for example (16-bit is a real world example --
> from
> Amiga or smth of that sort, IIRC).
More importantly, "reg-shift" doesn't say what part of
the bigger words to access. A common example is byte-wide
registers on a 32-bit-only bus; it's about 50%-50% between
connecting the registers to the low byte vs. connecting it
to the byte with the lowest address.
The only realistic way to handle all this is to put some
knowledge into the device driver. This does of course
also mean that no "reg-shift" property is needed; the
device driver can look at your "compatible" property,
instead.
>>> Why the heck should we care about the UART code taling about IDE?!
>
>> Consistency?
>
> We're not obliged to be consistent with every piece of the kernel
> code.
It would be nice to not name similar properties in the
device tree dissimilarly. Kernel code doesn't come into
the picture here.
Segher
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Arnd Bergmann @ 2007-07-31 22:25 UTC (permalink / raw)
To: Dave Jiang; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <46AFB686.40508@mvista.com>
On Wednesday 01 August 2007, Dave Jiang wrote:
> Doh! I sent out the reworked patches right before your comments. Do you happen
> to know where I can find an example of how to do this? In regards to making a
> platform_device a child of the PCI host bridge that is.... Thanks!
>
When you use an open-coded version of platform_device_register_simple(),
you can set dev->parent before calling platform_device_add.
Arnd <><
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-31 22:24 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <200708010007.12922.arnd@arndb.de>
Arnd Bergmann wrote:
> On Tuesday 31 July 2007, Dave Jiang wrote:
>> Actually it seems that for me to grab the interrupt number I have to do the
>> platform device creation in fsl_soc.c and call arch_init() instead of doing it
>> from fsl_add_bridge(). fsl_add_bridge() is called way too early and the mpic
>> interrupt mapping has not been setup yet for me to acquire the interrupt number
>> from of_interrupt_to_resource() call.
>
> I think in general, it would be a better solution to have the add_bridge
> code called much later, like we do with the 64 bit PCI code when
> using an of_device for the PCI bridge. I don't think it's easy to
> do though, so that shouldn't stop you from doing it the other way.
>
> Please make the platform_device a child of the PCI host bridge though,
> so it doesn't need to change if/when the PCI initialization gets changed
> to allow doing it from fsl_pci.
>
Doh! I sent out the reworked patches right before your comments. Do you happen
to know where I can find an example of how to do this? In regards to making a
platform_device a child of the PCI host bridge that is.... Thanks!
--
------------------------------------------------------
Dave Jiang
Software Engineer
MontaVista Software, Inc.
http://www.mvista.com
------------------------------------------------------
^ permalink raw reply
* Re: [PATCH 1/3] Add a new member name to structure irq_host
From: Segher Boessenkool @ 2007-07-31 22:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Chen Gong, paulus
In-Reply-To: <1185918267.5495.505.camel@localhost.localdomain>
>>> Which makes me think (again) that we should have an optional
>>> device_node
>>> pointer in irq_host. I know you said you wanted the irq stuff to be
>>> OF
>>> agnostic, but the reality is most of the implementations do have an
>>> OF
>>> node. And all of the newer irq_host implementations do, with the
>>> exception of PS3 and celleb - which are special.
>>
>> How do you suggest to get a reasonable display name out of
>> the device tree? The recommended human-readable name for
>> interrupt controller nodes is "interrupt-controller"...
>> You cannot use "device_type" either, and using "compatible"
>> requires selecting one of its string entries, and likely
>> using a lookup table after that, too.
>
> In that case, I would display the node full path.
Those tend to be quite long, in the cases where there are
multiple interrupt controllers in the system; and really
useless otherwise. I think the interrupt controllers should
still just fill in the names "manually".
It's a good thing to have an of_node in the irq_host struct
anyway, though :-)
Segher
^ permalink raw reply
* Re: [RFC][PATCH] MPC832x_RDB: update dts to use spi, register mmc_spi stub
From: Segher Boessenkool @ 2007-07-31 22:10 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20070726135738.GB5643@localhost.localdomain>
> + spi1pio:spi_pin@01 {
There should be whitespace after the label. @01 should be
spelled @1. Except there is no "reg" property. What is this
stuff, anyway?
> + pio-map = <
> + /* port pin dir open_drain assignment has_irq */
> + 3 0 3 0 1 0 /* SPI1 MOSI, I/O */
> + 3 1 3 0 1 0 /* SPI1 MISO, I/O */
> + 3 2 3 0 1 0 /* SPI1 CLK, I/O */
> + 3 3 2 0 1 0>; /* SPI1 SEL, I */
> + };
Segher
^ permalink raw reply
* [PATCH 75] drivers/macintosh/therm_adt746x.c: kmalloc + memset conversion to kzalloc
From: Mariusz Kozlowski @ 2007-07-31 22:10 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, Andrew Morton, kernel-janitors
In-Reply-To: <200707311845.48807.m.kozlowski@tuxland.pl>
Signed-off-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl>
drivers/macintosh/therm_adt746x.c | 17298 -> 17244 (-54 bytes)
drivers/macintosh/therm_adt746x.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- linux-2.6.23-rc1-mm1-a/drivers/macintosh/therm_adt746x.c 2007-07-26 13:07:42.000000000 +0200
+++ linux-2.6.23-rc1-mm1-b/drivers/macintosh/therm_adt746x.c 2007-07-31 11:18:55.000000000 +0200
@@ -379,13 +379,10 @@ static int attach_one_thermostat(struct
if (thermostat)
return 0;
- th = (struct thermostat *)
- kmalloc(sizeof(struct thermostat), GFP_KERNEL);
-
+ th = kzalloc(sizeof(struct thermostat), GFP_KERNEL);
if (!th)
return -ENOMEM;
- memset(th, 0, sizeof(*th));
th->clt.addr = addr;
th->clt.adapter = adapter;
th->clt.driver = &thermostat_driver;
^ permalink raw reply
* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Arnd Bergmann @ 2007-07-31 22:07 UTC (permalink / raw)
To: Dave Jiang; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <46AFA040.7070303@mvista.com>
On Tuesday 31 July 2007, Dave Jiang wrote:
> Actually it seems that for me to grab the interrupt number I have to do the
> platform device creation in fsl_soc.c and call arch_init() instead of doing it
> from fsl_add_bridge(). fsl_add_bridge() is called way too early and the mpic
> interrupt mapping has not been setup yet for me to acquire the interrupt number
> from of_interrupt_to_resource() call.
I think in general, it would be a better solution to have the add_bridge
code called much later, like we do with the 64 bit PCI code when
using an of_device for the PCI bridge. I don't think it's easy to
do though, so that shouldn't stop you from doing it the other way.
Please make the platform_device a child of the PCI host bridge though,
so it doesn't need to change if/when the PCI initialization gets changed
to allow doing it from fsl_pci.
Arnd <><
^ permalink raw reply
* [PATCH v2 3/3] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-31 22:10 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <20070726222021.GA10427@blade.az.mvista.com>
Freescale MPC85xx SoC support for EDAC. Used on PPC platforms. Development
and testing done on PPC Freescale MPC8548CDS.
The driver provides error reporting for L2 cache error registers, the
memory controller error registers, and the PCI error registers. The error
reporting can be done two ways, via interrupts or polling.
Signed-off-by: Dave Jiang <djiang@mvista.com>
Signed-off-by: Douglas Thompson <dougthompson@xmission.com>
---
Made PCI error devices as platform devices as per suggestion.
Also fixed up init routine error handling so that some sort of warning is
posted if failure to register one of the devices is detected.
Kconfig | 6
Makefile | 1
mpc85xx_edac.c | 1043 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mpc85xx_edac.h | 162 ++++++++
4 files changed, 1212 insertions(+)
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 1724c41..cc50ab6 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -131,5 +131,11 @@ config EDAC_PASEMI
Support for error detection and correction on PA Semi
PWRficient.
+config EDAC_MPC85XX
+ tristate "Freescale MPC85xx"
+ depends on EDAC_MM_EDAC && FSL_SOC && MPC85xx
+ help
+ Support for error detection and correction on the Freescale
+ MPC8560, MPC8540, MPC8548
endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 02c09f0..62696aa 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_EDAC_I3000) += i3000_edac.o
obj-$(CONFIG_EDAC_I82860) += i82860_edac.o
obj-$(CONFIG_EDAC_R82600) += r82600_edac.o
obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o
+obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac.o
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
new file mode 100644
index 0000000..4c7fc6d
--- /dev/null
+++ b/drivers/edac/mpc85xx_edac.c
@@ -0,0 +1,1043 @@
+/*
+ * Freescale MPC85xx Memory Controller kenel module
+ *
+ * Author: Dave Jiang <djiang@mvista.com>
+ *
+ * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/edac.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <asm/mpc85xx.h>
+#include "edac_module.h"
+#include "edac_core.h"
+#include "mpc85xx_edac.h"
+
+static int edac_dev_idx;
+static int edac_pci_idx;
+static int edac_mc_idx;
+
+static u32 orig_ddr_err_disable;
+static u32 orig_ddr_err_sbe;
+
+/*
+ * PCI Err defines
+ */
+#ifdef CONFIG_PCI
+static u32 orig_pci_err_cap_dr;
+static u32 orig_pci_err_en;
+#endif
+
+static u32 orig_l2_err_disable;
+static u32 orig_hid1;
+
+const char *mpc85xx_ctl_name = "MPC85xx";
+
+/************************ MC SYSFS parts ***********************************/
+
+static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci,
+ char *data)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->mc_vbase +
+ MPC85XX_MC_DATA_ERR_INJECT_HI));
+}
+
+static ssize_t mpc85xx_mc_inject_data_lo_show(struct mem_ctl_info *mci,
+ char *data)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->mc_vbase +
+ MPC85XX_MC_DATA_ERR_INJECT_LO));
+}
+
+static ssize_t mpc85xx_mc_inject_ctrl_show(struct mem_ctl_info *mci, char *data)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT));
+}
+
+static ssize_t mpc85xx_mc_inject_data_hi_store(struct mem_ctl_info *mci,
+ const char *data, size_t count)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_HI,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static ssize_t mpc85xx_mc_inject_data_lo_store(struct mem_ctl_info *mci,
+ const char *data, size_t count)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_DATA_ERR_INJECT_LO,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static ssize_t mpc85xx_mc_inject_ctrl_store(struct mem_ctl_info *mci,
+ const char *data, size_t count)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ECC_ERR_INJECT,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static struct mcidev_sysfs_attribute mpc85xx_mc_sysfs_attributes[] = {
+ {
+ .attr = {
+ .name = "inject_data_hi",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_mc_inject_data_hi_show,
+ .store = mpc85xx_mc_inject_data_hi_store},
+ {
+ .attr = {
+ .name = "inject_data_lo",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_mc_inject_data_lo_show,
+ .store = mpc85xx_mc_inject_data_lo_store},
+ {
+ .attr = {
+ .name = "inject_ctrl",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_mc_inject_ctrl_show,
+ .store = mpc85xx_mc_inject_ctrl_store},
+
+ /* End of list */
+ {
+ .attr = {.name = NULL}
+ }
+};
+
+static void mpc85xx_set_mc_sysfs_attributes(struct mem_ctl_info *mci)
+{
+ mci->mc_driver_sysfs_attributes = mpc85xx_mc_sysfs_attributes;
+}
+
+/**************************** PCI Err device ***************************/
+#ifdef CONFIG_PCI
+
+static void mpc85xx_pci_check(struct edac_pci_ctl_info *pci)
+{
+ struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+ u32 err_detect;
+
+ err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
+
+ /* master aborts can happen during PCI config cycles */
+ if (!(err_detect & ~(PCI_EDE_MULTI_ERR | PCI_EDE_MST_ABRT))) {
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
+ return;
+ }
+
+ printk(KERN_ERR "PCI error(s) detected\n");
+ printk(KERN_ERR "PCI/X ERR_DR register: %#08x\n", err_detect);
+
+ printk(KERN_ERR "PCI/X ERR_ATTRIB register: %#08x\n",
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ATTRIB));
+ printk(KERN_ERR "PCI/X ERR_ADDR register: %#08x\n",
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR));
+ printk(KERN_ERR "PCI/X ERR_EXT_ADDR register: %#08x\n",
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EXT_ADDR));
+ printk(KERN_ERR "PCI/X ERR_DL register: %#08x\n",
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DL));
+ printk(KERN_ERR "PCI/X ERR_DH register: %#08x\n",
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DH));
+
+ /* clear error bits */
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
+
+ if (err_detect & PCI_EDE_PERR_MASK)
+ edac_pci_handle_pe(pci, pci->ctl_name);
+
+ if ((err_detect & ~PCI_EDE_MULTI_ERR) & ~PCI_EDE_PERR_MASK)
+ edac_pci_handle_npe(pci, pci->ctl_name);
+}
+
+static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
+{
+ struct edac_pci_ctl_info *pci = dev_id;
+ struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+ u32 err_detect;
+
+ err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
+
+ if (!err_detect)
+ return IRQ_NONE;
+
+ mpc85xx_pci_check(pci);
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit mpc85xx_pci_err_probe(struct platform_device *pdev)
+{
+ struct edac_pci_ctl_info *pci;
+ struct mpc85xx_pci_pdata *pdata;
+ struct resource *r;
+ int res = 0;
+
+ if (!devres_open_group(&pdev->dev, mpc85xx_pci_err_probe, GFP_KERNEL))
+ return -ENOMEM;
+
+ pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mpc85xx_pci_err");
+ if (!pci)
+ return -ENOMEM;
+
+ pdata = pci->pvt_info;
+ pdata->name = "mpc85xx_pci_err";
+ pdata->irq = NO_IRQ;
+ platform_set_drvdata(pdev, pci);
+ pci->dev = &pdev->dev;
+ pci->mod_name = EDAC_MOD_STR;
+ pci->ctl_name = pdata->name;
+ pci->dev_name = pdev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ pci->edac_check = mpc85xx_pci_check;
+
+ pdata->edac_idx = edac_pci_idx++;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ printk(KERN_ERR "%s: Unable to get resource for "
+ "PCI err regs\n", __func__);
+ goto err;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, r->start,
+ r->end - r->start + 1, pdata->name)) {
+ printk(KERN_ERR "%s: Error while requesting mem region\n",
+ __func__);
+ res = -EBUSY;
+ goto err;
+ }
+
+ pdata->pci_vbase = devm_ioremap(&pdev->dev, r->start,
+ r->end - r->start + 1);
+ if (!pdata->pci_vbase) {
+ printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
+ res = -ENOMEM;
+ goto err;
+ }
+
+ orig_pci_err_cap_dr =
+ in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
+
+ /* PCI master abort is expected during config cycles */
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);
+
+ orig_pci_err_en = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
+
+ /* disable master abort reporting */
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);
+
+ /* clear error bits */
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);
+
+ if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
+ debugf3("%s(): failed edac_pci_add_device()\n", __func__);
+ goto err;
+ }
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ pdata->irq = platform_get_irq(pdev, 0);
+ res = devm_request_irq(&pdev->dev, pdata->irq,
+ mpc85xx_pci_isr, IRQF_DISABLED,
+ "[EDAC] PCI err", pci);
+ if (res < 0) {
+ printk(KERN_ERR
+ "%s: Unable to requiest irq %d for "
+ "MPC85xx PCI err\n", __func__, pdata->irq);
+ res = -ENODEV;
+ goto err2;
+ }
+
+ printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
+ pdata->irq);
+ }
+
+ devres_remove_group(&pdev->dev, mpc85xx_pci_err_probe);
+ debugf3("%s(): success\n", __func__);
+ printk(KERN_INFO EDAC_MOD_STR " PCI err registered\n");
+
+ return 0;
+
+err2:
+ edac_pci_del_device(&pdev->dev);
+err:
+ edac_pci_free_ctl_info(pci);
+ devres_release_group(&pdev->dev, mpc85xx_pci_err_probe);
+ return res;
+}
+
+static int mpc85xx_pci_err_remove(struct platform_device *pdev)
+{
+ struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);
+ struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
+
+ debugf0("%s()\n", __func__);
+
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR,
+ orig_pci_err_cap_dr);
+
+ out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en);
+
+ edac_pci_del_device(pci->dev);
+
+ if (edac_op_state == EDAC_OPSTATE_INT)
+ irq_dispose_mapping(pdata->irq);
+
+ edac_pci_free_ctl_info(pci);
+
+ return 0;
+}
+
+static struct platform_driver mpc85xx_pci_err_driver = {
+ .probe = mpc85xx_pci_err_probe,
+ .remove = __devexit_p(mpc85xx_pci_err_remove),
+ .driver = {
+ .name = "mpc85xx_pci_err",
+ }
+};
+
+#endif /* CONFIG_PCI */
+
+/**************************** L2 Err device ***************************/
+
+/************************ L2 SYSFS parts ***********************************/
+
+static ssize_t mpc85xx_l2_inject_data_hi_show(struct edac_device_ctl_info
+ *edac_dev, char *data)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI));
+}
+
+static ssize_t mpc85xx_l2_inject_data_lo_show(struct edac_device_ctl_info
+ *edac_dev, char *data)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO));
+}
+
+static ssize_t mpc85xx_l2_inject_ctrl_show(struct edac_device_ctl_info
+ *edac_dev, char *data)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ return sprintf(data, "0x%08x",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJCTL));
+}
+
+static ssize_t mpc85xx_l2_inject_data_hi_store(struct edac_device_ctl_info
+ *edac_dev, const char *data,
+ size_t count)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static ssize_t mpc85xx_l2_inject_data_lo_store(struct edac_device_ctl_info
+ *edac_dev, const char *data,
+ size_t count)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static ssize_t mpc85xx_l2_inject_ctrl_store(struct edac_device_ctl_info
+ *edac_dev, const char *data,
+ size_t count)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ if (isdigit(*data)) {
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJCTL,
+ simple_strtoul(data, NULL, 0));
+ return count;
+ }
+ return 0;
+}
+
+static struct edac_dev_sysfs_attribute mpc85xx_l2_sysfs_attributes[] = {
+ {
+ .attr = {
+ .name = "inject_data_hi",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_l2_inject_data_hi_show,
+ .store = mpc85xx_l2_inject_data_hi_store},
+ {
+ .attr = {
+ .name = "inject_data_lo",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_l2_inject_data_lo_show,
+ .store = mpc85xx_l2_inject_data_lo_store},
+ {
+ .attr = {
+ .name = "inject_ctrl",
+ .mode = (S_IRUGO | S_IWUSR)
+ },
+ .show = mpc85xx_l2_inject_ctrl_show,
+ .store = mpc85xx_l2_inject_ctrl_store},
+
+ /* End of list */
+ {
+ .attr = {.name = NULL}
+ }
+};
+
+static void mpc85xx_set_l2_sysfs_attributes(struct edac_device_ctl_info
+ *edac_dev)
+{
+ edac_dev->sysfs_attributes = mpc85xx_l2_sysfs_attributes;
+}
+
+/***************************** L2 ops ***********************************/
+
+static void mpc85xx_l2_check(struct edac_device_ctl_info *edac_dev)
+{
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ u32 err_detect;
+
+ err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
+
+ if (!(err_detect & L2_EDE_MASK))
+ return;
+
+ printk(KERN_ERR "ECC Error in CPU L2 cache\n");
+ printk(KERN_ERR "L2 Error Detect Register: 0x%08x\n", err_detect);
+ printk(KERN_ERR "L2 Error Capture Data High Register: 0x%08x\n",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATAHI));
+ printk(KERN_ERR "L2 Error Capture Data Lo Register: 0x%08x\n",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATALO));
+ printk(KERN_ERR "L2 Error Syndrome Register: 0x%08x\n",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTECC));
+ printk(KERN_ERR "L2 Error Attributes Capture Register: 0x%08x\n",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_ERRATTR));
+ printk(KERN_ERR "L2 Error Address Capture Register: 0x%08x\n",
+ in_be32(pdata->l2_vbase + MPC85XX_L2_ERRADDR));
+
+ /* clear error detect register */
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, err_detect);
+
+ if (err_detect & L2_EDE_CE_MASK)
+ edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+
+ if (err_detect & L2_EDE_UE_MASK)
+ edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+}
+
+static irqreturn_t mpc85xx_l2_isr(int irq, void *dev_id)
+{
+ struct edac_device_ctl_info *edac_dev = dev_id;
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+ u32 err_detect;
+
+ err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
+
+ if (!(err_detect & L2_EDE_MASK))
+ return IRQ_NONE;
+
+ mpc85xx_l2_check(edac_dev);
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ struct edac_device_ctl_info *edac_dev;
+ struct mpc85xx_l2_pdata *pdata;
+ struct resource r;
+ int res;
+
+ if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
+ return -ENOMEM;
+
+ edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
+ "cpu", 1, "L", 1, 2, NULL, 0,
+ edac_dev_idx);
+ if (!edac_dev) {
+ devres_release_group(&op->dev, mpc85xx_l2_err_probe);
+ return -ENOMEM;
+ }
+
+ pdata = edac_dev->pvt_info;
+ pdata->name = "mpc85xx_l2_err";
+ pdata->irq = NO_IRQ;
+ edac_dev->dev = &op->dev;
+ dev_set_drvdata(edac_dev->dev, edac_dev);
+ edac_dev->ctl_name = pdata->name;
+ edac_dev->dev_name = pdata->name;
+
+ res = of_address_to_resource(op->node, 0, &r);
+ if (res) {
+ printk(KERN_ERR "%s: Unable to get resource for "
+ "L2 err regs\n", __func__);
+ goto err;
+ }
+
+ /* we only need the error registers */
+ r.start += 0xe00;
+
+ if (!devm_request_mem_region(&op->dev, r.start,
+ r.end - r.start + 1, pdata->name)) {
+ printk(KERN_ERR "%s: Error while requesting mem region\n",
+ __func__);
+ res = -EBUSY;
+ goto err;
+ }
+
+ pdata->l2_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
+ if (!pdata->l2_vbase) {
+ printk(KERN_ERR "%s: Unable to setup L2 err regs\n", __func__);
+ res = -ENOMEM;
+ goto err;
+ }
+
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);
+
+ orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);
+
+ /* clear the err_dis */
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);
+
+ edac_dev->mod_name = EDAC_MOD_STR;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ edac_dev->edac_check = mpc85xx_l2_check;
+
+ mpc85xx_set_l2_sysfs_attributes(edac_dev);
+
+ pdata->edac_idx = edac_dev_idx++;
+
+ if (edac_device_add_device(edac_dev) > 0) {
+ debugf3("%s(): failed edac_device_add_device()\n", __func__);
+ goto err;
+ }
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ pdata->irq = irq_of_parse_and_map(op->node, 0);
+ res = devm_request_irq(&op->dev, pdata->irq,
+ mpc85xx_l2_isr, IRQF_DISABLED,
+ "[EDAC] L2 err", edac_dev);
+ if (res < 0) {
+ printk(KERN_ERR
+ "%s: Unable to requiest irq %d for "
+ "MPC85xx L2 err\n", __func__, pdata->irq);
+ irq_dispose_mapping(pdata->irq);
+ res = -ENODEV;
+ goto err2;
+ }
+
+ printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for L2 Err\n",
+ pdata->irq);
+
+ edac_dev->op_state = OP_RUNNING_INTERRUPT;
+
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
+ }
+
+ devres_remove_group(&op->dev, mpc85xx_l2_err_probe);
+
+ debugf3("%s(): success\n", __func__);
+ printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");
+
+ return 0;
+
+err2:
+ edac_device_del_device(&op->dev);
+err:
+ devres_release_group(&op->dev, mpc85xx_l2_err_probe);
+ edac_device_free_ctl_info(edac_dev);
+ return res;
+}
+
+static int mpc85xx_l2_err_remove(struct of_device *op)
+{
+ struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
+ struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
+
+ debugf0("%s()\n", __func__);
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
+ irq_dispose_mapping(pdata->irq);
+ }
+
+ out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable);
+ edac_device_del_device(&op->dev);
+ edac_device_free_ctl_info(edac_dev);
+ return 0;
+}
+
+static struct of_device_id mpc85xx_l2_err_of_match[] = {
+ {
+ .compatible = "fsl,8540-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,8541-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,8544-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,8548-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,8555-l2-cache-controller",
+ },
+ {
+ .compatible = "fsl,8568-l2-cache-controller",
+ },
+ {},
+};
+
+static struct of_platform_driver mpc85xx_l2_err_driver = {
+ .owner = THIS_MODULE,
+ .name = "mpc85xx_l2_err",
+ .match_table = mpc85xx_l2_err_of_match,
+ .probe = mpc85xx_l2_err_probe,
+ .remove = mpc85xx_l2_err_remove,
+ .driver = {
+ .name = "mpc85xx_l2_err",
+ .owner = THIS_MODULE,
+ },
+};
+
+/**************************** MC Err device ***************************/
+
+static void mpc85xx_mc_check(struct mem_ctl_info *mci)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ struct csrow_info *csrow;
+ u32 err_detect;
+ u32 syndrome;
+ u32 err_addr;
+ u32 pfn;
+ int row_index;
+
+ err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
+ if (err_detect)
+ return;
+
+ mpc85xx_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n",
+ err_detect);
+
+ /* no more processing if not ECC bit errors */
+ if (!(err_detect & (DDR_EDE_SBE | DDR_EDE_MBE))) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, err_detect);
+ return;
+ }
+
+ syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC);
+ err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS);
+ pfn = err_addr >> PAGE_SHIFT;
+
+ for (row_index = 0; row_index < mci->nr_csrows; row_index++) {
+ csrow = &mci->csrows[row_index];
+ if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page))
+ break;
+ }
+
+ mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n",
+ in_be32(pdata->mc_vbase +
+ MPC85XX_MC_CAPTURE_DATA_HI));
+ mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n",
+ in_be32(pdata->mc_vbase +
+ MPC85XX_MC_CAPTURE_DATA_LO));
+ mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#8.8x\n", syndrome);
+ mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr);
+ mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn);
+
+ /* we are out of range */
+ if (row_index == mci->nr_csrows)
+ mpc85xx_mc_printk(mci, KERN_ERR, "PFN out of range!\n");
+
+ if (err_detect & DDR_EDE_SBE)
+ edac_mc_handle_ce(mci, pfn, err_addr & PAGE_MASK,
+ syndrome, row_index, 0, mci->ctl_name);
+
+ if (err_detect & DDR_EDE_MBE)
+ edac_mc_handle_ue(mci, pfn, err_addr & PAGE_MASK,
+ row_index, mci->ctl_name);
+
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, err_detect);
+}
+
+static irqreturn_t mpc85xx_mc_isr(int irq, void *dev_id)
+{
+ struct mem_ctl_info *mci = dev_id;
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ u32 err_detect;
+
+ err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
+ if (!err_detect)
+ return IRQ_NONE;
+
+ mpc85xx_mc_check(mci);
+
+ return IRQ_HANDLED;
+}
+
+static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci)
+{
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+ struct csrow_info *csrow;
+ u32 sdram_ctl;
+ u32 sdtype;
+ enum mem_type mtype;
+ u32 cs_bnds;
+ int index;
+
+ sdram_ctl = in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG);
+
+ sdtype = sdram_ctl & DSC_SDTYPE_MASK;
+ if (sdram_ctl & DSC_RD_EN) {
+ switch (sdtype) {
+ case DSC_SDTYPE_DDR:
+ mtype = MEM_RDDR;
+ break;
+ case DSC_SDTYPE_DDR2:
+ mtype = MEM_RDDR2;
+ break;
+ default:
+ mtype = MEM_UNKNOWN;
+ break;
+ }
+ } else {
+ switch (sdtype) {
+ case DSC_SDTYPE_DDR:
+ mtype = MEM_DDR;
+ break;
+ case DSC_SDTYPE_DDR2:
+ mtype = MEM_DDR2;
+ break;
+ default:
+ mtype = MEM_UNKNOWN;
+ break;
+ }
+ }
+
+ for (index = 0; index < mci->nr_csrows; index++) {
+ u32 start;
+ u32 end;
+
+ csrow = &mci->csrows[index];
+ cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
+ (index * MPC85XX_MC_CS_BNDS_OFS));
+ start = (cs_bnds & 0xfff0000) << 4;
+ end = ((cs_bnds & 0xfff) << 20);
+ if (start)
+ start |= 0xfffff;
+ if (end)
+ end |= 0xfffff;
+
+ if (start == end)
+ continue; /* not populated */
+
+ csrow->first_page = start >> PAGE_SHIFT;
+ csrow->last_page = end >> PAGE_SHIFT;
+ csrow->nr_pages = csrow->last_page + 1 - csrow->first_page;
+ csrow->grain = 8;
+ csrow->mtype = mtype;
+ csrow->dtype = DEV_UNKNOWN;
+ if (sdram_ctl & DSC_X32_EN)
+ csrow->dtype = DEV_X32;
+ csrow->edac_mode = EDAC_SECDED;
+ }
+}
+
+static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ struct mem_ctl_info *mci;
+ struct mpc85xx_mc_pdata *pdata;
+ struct resource r;
+ u32 sdram_ctl;
+ int res;
+
+ if (!devres_open_group(&op->dev, mpc85xx_mc_err_probe, GFP_KERNEL))
+ return -ENOMEM;
+
+ mci = edac_mc_alloc(sizeof(*pdata), 4, 1, edac_mc_idx);
+ if (!mci) {
+ devres_release_group(&op->dev, mpc85xx_mc_err_probe);
+ return -ENOMEM;
+ }
+
+ pdata = mci->pvt_info;
+ pdata->name = "mpc85xx_mc_err";
+ pdata->irq = NO_IRQ;
+ mci->dev = &op->dev;
+ pdata->edac_idx = edac_mc_idx++;
+ dev_set_drvdata(mci->dev, mci);
+ mci->ctl_name = pdata->name;
+ mci->dev_name = pdata->name;
+
+ res = of_address_to_resource(op->node, 0, &r);
+ if (res) {
+ printk(KERN_ERR "%s: Unable to get resource for MC err regs\n",
+ __func__);
+ goto err;
+ }
+
+ if (!devm_request_mem_region(&op->dev, r.start,
+ r.end - r.start + 1, pdata->name)) {
+ printk(KERN_ERR "%s: Error while requesting mem region\n",
+ __func__);
+ res = -EBUSY;
+ goto err;
+ }
+
+ pdata->mc_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
+ if (!pdata->mc_vbase) {
+ printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__);
+ res = -ENOMEM;
+ goto err;
+ }
+
+ sdram_ctl = in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG);
+ if (!(sdram_ctl & DSC_ECC_EN)) {
+ /* no ECC */
+ printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
+ res = -ENODEV;
+ goto err;
+ }
+
+ debugf3("%s(): init mci\n", __func__);
+ mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_RDDR2 |
+ MEM_FLAG_DDR | MEM_FLAG_DDR2;
+ mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
+ mci->edac_cap = EDAC_FLAG_SECDED;
+ mci->mod_name = EDAC_MOD_STR;
+ mci->mod_ver = MPC85XX_REVISION;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ mci->edac_check = mpc85xx_mc_check;
+
+ mci->ctl_page_to_phys = NULL;
+
+ mci->scrub_mode = SCRUB_SW_SRC;
+
+ mpc85xx_set_mc_sysfs_attributes(mci);
+
+ mpc85xx_init_csrows(mci);
+
+#ifdef CONFIG_EDAC_DEBUG
+ edac_mc_register_mcidev_debug((struct attribute **)debug_attr);
+#endif
+
+ /* store the original error disable bits */
+ orig_ddr_err_disable =
+ in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE);
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE, 0);
+
+ /* clear all error bits */
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT, ~0);
+
+ if (edac_mc_add_mc(mci)) {
+ debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
+ goto err;
+ }
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN,
+ DDR_EIE_MBEE | DDR_EIE_SBEE);
+
+ /* store the original error management threshold */
+ orig_ddr_err_sbe = in_be32(pdata->mc_vbase +
+ MPC85XX_MC_ERR_SBE) & 0xff0000;
+
+ /* set threshold to 1 error per interrupt */
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000);
+
+ /* register interrupts */
+ pdata->irq = irq_of_parse_and_map(op->node, 0);
+ res = devm_request_irq(&op->dev, pdata->irq,
+ mpc85xx_mc_isr, IRQF_DISABLED,
+ "[EDAC] MC err", mci);
+ if (res < 0) {
+ printk(KERN_ERR "%s: Unable to request irq %d for "
+ "MPC85xx DRAM ERR\n", __func__, pdata->irq);
+ irq_dispose_mapping(pdata->irq);
+ res = -ENODEV;
+ goto err2;
+ }
+
+ printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC\n",
+ pdata->irq);
+ }
+
+ devres_remove_group(&op->dev, mpc85xx_mc_err_probe);
+ debugf3("%s(): success\n", __func__);
+ printk(KERN_INFO EDAC_MOD_STR " MC err registered\n");
+
+ return 0;
+
+err2:
+ edac_mc_del_mc(&op->dev);
+err:
+ devres_release_group(&op->dev, mpc85xx_mc_err_probe);
+ edac_mc_free(mci);
+ return res;
+}
+
+static int mpc85xx_mc_err_remove(struct of_device *op)
+{
+ struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
+ struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
+
+ debugf0("%s()\n", __func__);
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN, 0);
+ irq_dispose_mapping(pdata->irq);
+ }
+
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE,
+ orig_ddr_err_disable);
+ out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);
+
+ edac_mc_del_mc(&op->dev);
+ edac_mc_free(mci);
+ return 0;
+}
+
+static struct of_device_id mpc85xx_mc_err_of_match[] = {
+ {
+ .compatible = "fsl,8540-memory-controller",
+ },
+ {
+ .compatible = "fsl,8541-memory-controller",
+ },
+ {
+ .compatible = "fsl,8544-memory-controller",
+ },
+ {
+ .compatible = "fsl,8548-memory-controller",
+ },
+ {
+ .compatible = "fsl,8555-memory-controller",
+ },
+ {
+ .compatible = "fsl,8568-memory-controller",
+ },
+ {},
+};
+
+static struct of_platform_driver mpc85xx_mc_err_driver = {
+ .owner = THIS_MODULE,
+ .name = "mpc85xx_mc_err",
+ .match_table = mpc85xx_mc_err_of_match,
+ .probe = mpc85xx_mc_err_probe,
+ .remove = mpc85xx_mc_err_remove,
+ .driver = {
+ .name = "mpc85xx_mc_err",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mpc85xx_mc_init(void)
+{
+ int res = 0;
+
+ printk(KERN_INFO "Freescale(R) MPC85xx EDAC driver, "
+ "(C) 2006 Montavista Software\n");
+
+ /* make sure error reporting method is sane */
+ switch (edac_op_state) {
+ case EDAC_OPSTATE_POLL:
+ case EDAC_OPSTATE_INT:
+ break;
+ default:
+ edac_op_state = EDAC_OPSTATE_INT;
+ break;
+ }
+
+ res = of_register_platform_driver(&mpc85xx_mc_err_driver);
+ if (res)
+ printk(KERN_WARNING EDAC_MOD_STR "MC fails to register\n");
+
+ res = of_register_platform_driver(&mpc85xx_l2_err_driver);
+ if (res)
+ printk(KERN_WARNING EDAC_MOD_STR "L2 fails to register\n");
+
+#ifdef CONFIG_PCI
+ res = platform_driver_register(&mpc85xx_pci_err_driver);
+ if (res)
+ printk(KERN_WARNING EDAC_MOD_STR "PCI fails to register\n");
+#endif
+
+ /*
+ * need to clear HID1[RFXE] to disable machine check int
+ * so we can catch it
+ */
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ orig_hid1 = mfspr(SPRN_HID1);
+ mtspr(SPRN_HID1, (orig_hid1 & ~0x20000));
+ }
+
+ return 0;
+}
+
+module_init(mpc85xx_mc_init);
+
+static void __exit mpc85xx_mc_exit(void)
+{
+ mtspr(SPRN_HID1, orig_hid1);
+#ifdef CONFIG_PCI
+ platform_driver_unregister(&mpc85xx_pci_err_driver);
+#endif
+ of_unregister_platform_driver(&mpc85xx_l2_err_driver);
+ of_unregister_platform_driver(&mpc85xx_mc_err_driver);
+}
+
+module_exit(mpc85xx_mc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Montavista Software, Inc.");
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state,
+ "EDAC Error Reporting state: 0=Poll, 2=Interrupt");
diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h
new file mode 100644
index 0000000..135b353
--- /dev/null
+++ b/drivers/edac/mpc85xx_edac.h
@@ -0,0 +1,162 @@
+/*
+ * Freescale MPC85xx Memory Controller kenel module
+ * Author: Dave Jiang <djiang@mvista.com>
+ *
+ * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+#ifndef _MPC85XX_EDAC_H_
+#define _MPC85XX_EDAC_H_
+
+#define MPC85XX_REVISION " Ver: 2.0.0 " __DATE__
+#define EDAC_MOD_STR "MPC85xx_edac"
+
+#define mpc85xx_printk(level, fmt, arg...) \
+ edac_printk(level, "MPC85xx", fmt, ##arg)
+
+#define mpc85xx_mc_printk(mci, level, fmt, arg...) \
+ edac_mc_chipset_printk(mci, level, "MPC85xx", fmt, ##arg)
+
+/*
+ * DRAM error defines
+ */
+
+/* DDR_SDRAM_CFG */
+#define MPC85XX_MC_DDR_SDRAM_CFG 0x0110
+#define MPC85XX_MC_CS_BNDS_0 0x0000
+#define MPC85XX_MC_CS_BNDS_1 0x0008
+#define MPC85XX_MC_CS_BNDS_2 0x0010
+#define MPC85XX_MC_CS_BNDS_3 0x0018
+#define MPC85XX_MC_CS_BNDS_OFS 0x0008
+
+#define MPC85XX_MC_DATA_ERR_INJECT_HI 0x0e00
+#define MPC85XX_MC_DATA_ERR_INJECT_LO 0x0e04
+#define MPC85XX_MC_ECC_ERR_INJECT 0x0e08
+#define MPC85XX_MC_CAPTURE_DATA_HI 0x0e20
+#define MPC85XX_MC_CAPTURE_DATA_LO 0x0e24
+#define MPC85XX_MC_CAPTURE_ECC 0x0e28
+#define MPC85XX_MC_ERR_DETECT 0x0e40
+#define MPC85XX_MC_ERR_DISABLE 0x0e44
+#define MPC85XX_MC_ERR_INT_EN 0x0e48
+#define MPC85XX_MC_CAPTURE_ATRIBUTES 0x0e4c
+#define MPC85XX_MC_CAPTURE_ADDRESS 0x0e50
+#define MPC85XX_MC_ERR_SBE 0x0e58
+
+#define DSC_MEM_EN 0x80000000
+#define DSC_ECC_EN 0x20000000
+#define DSC_RD_EN 0x10000000
+
+#define DSC_SDTYPE_MASK 0x07000000
+
+#define DSC_SDTYPE_DDR 0x02000000
+#define DSC_SDTYPE_DDR2 0x03000000
+#define DSC_X32_EN 0x00000020
+
+/* Err_Int_En */
+#define DDR_EIE_MSEE 0x1 /* memory select */
+#define DDR_EIE_SBEE 0x4 /* single-bit ECC error */
+#define DDR_EIE_MBEE 0x8 /* multi-bit ECC error */
+
+/* Err_Detect */
+#define DDR_EDE_MSE 0x1 /* memory select */
+#define DDR_EDE_SBE 0x4 /* single-bit ECC error */
+#define DDR_EDE_MBE 0x8 /* multi-bit ECC error */
+#define DDR_EDE_MME 0x80000000 /* multiple memory errors */
+
+/* Err_Disable */
+#define DDR_EDI_MSED 0x1 /* memory select disable */
+#define DDR_EDI_SBED 0x4 /* single-bit ECC error disable */
+#define DDR_EDI_MBED 0x8 /* multi-bit ECC error disable */
+
+/*
+ * L2 Err defines
+ */
+#define MPC85XX_L2_ERRINJHI 0x0000
+#define MPC85XX_L2_ERRINJLO 0x0004
+#define MPC85XX_L2_ERRINJCTL 0x0008
+#define MPC85XX_L2_CAPTDATAHI 0x0020
+#define MPC85XX_L2_CAPTDATALO 0x0024
+#define MPC85XX_L2_CAPTECC 0x0028
+#define MPC85XX_L2_ERRDET 0x0040
+#define MPC85XX_L2_ERRDIS 0x0044
+#define MPC85XX_L2_ERRINTEN 0x0048
+#define MPC85XX_L2_ERRATTR 0x004c
+#define MPC85XX_L2_ERRADDR 0x0050
+#define MPC85XX_L2_ERRCTL 0x0058
+
+/* Error Interrupt Enable */
+#define L2_EIE_L2CFGINTEN 0x1
+#define L2_EIE_SBECCINTEN 0x4
+#define L2_EIE_MBECCINTEN 0x8
+#define L2_EIE_TPARINTEN 0x10
+#define L2_EIE_MASK (L2_EIE_L2CFGINTEN | L2_EIE_SBECCINTEN | \
+ L2_EIE_MBECCINTEN | L2_EIE_TPARINTEN)
+
+/* Error Detect */
+#define L2_EDE_L2CFGERR 0x1
+#define L2_EDE_SBECCERR 0x4
+#define L2_EDE_MBECCERR 0x8
+#define L2_EDE_TPARERR 0x10
+#define L2_EDE_MULL2ERR 0x80000000
+
+#define L2_EDE_CE_MASK L2_EDE_SBECCERR
+#define L2_EDE_UE_MASK (L2_EDE_L2CFGERR | L2_EDE_MBECCERR | \
+ L2_EDE_TPARERR)
+#define L2_EDE_MASK (L2_EDE_L2CFGERR | L2_EDE_SBECCERR | \
+ L2_EDE_MBECCERR | L2_EDE_TPARERR | L2_EDE_MULL2ERR)
+
+/*
+ * PCI Err defines
+ */
+#define PCI_EDE_TOE 0x00000001
+#define PCI_EDE_SCM 0x00000002
+#define PCI_EDE_IRMSV 0x00000004
+#define PCI_EDE_ORMSV 0x00000008
+#define PCI_EDE_OWMSV 0x00000010
+#define PCI_EDE_TGT_ABRT 0x00000020
+#define PCI_EDE_MST_ABRT 0x00000040
+#define PCI_EDE_TGT_PERR 0x00000080
+#define PCI_EDE_MST_PERR 0x00000100
+#define PCI_EDE_RCVD_SERR 0x00000200
+#define PCI_EDE_ADDR_PERR 0x00000400
+#define PCI_EDE_MULTI_ERR 0x80000000
+
+#define PCI_EDE_PERR_MASK (PCI_EDE_TGT_PERR | PCI_EDE_MST_PERR | \
+ PCI_EDE_ADDR_PERR)
+
+#define MPC85XX_PCI_ERR_DR 0x0000
+#define MPC85XX_PCI_ERR_CAP_DR 0x0004
+#define MPC85XX_PCI_ERR_EN 0x0008
+#define MPC85XX_PCI_ERR_ATTRIB 0x000c
+#define MPC85XX_PCI_ERR_ADDR 0x0010
+#define MPC85XX_PCI_ERR_EXT_ADDR 0x0014
+#define MPC85XX_PCI_ERR_DL 0x0018
+#define MPC85XX_PCI_ERR_DH 0x001c
+#define MPC85XX_PCI_GAS_TIMR 0x0020
+#define MPC85XX_PCI_PCIX_TIMR 0x0024
+
+struct mpc85xx_mc_pdata {
+ char *name;
+ int edac_idx;
+ void __iomem *mc_vbase;
+ int irq;
+};
+
+struct mpc85xx_l2_pdata {
+ char *name;
+ int edac_idx;
+ void __iomem *l2_vbase;
+ int irq;
+};
+
+struct mpc85xx_pci_pdata {
+ char *name;
+ int edac_idx;
+ void __iomem *pci_vbase;
+ int irq;
+};
+
+#endif
^ permalink raw reply related
* Re: [RFC][PATCH] MPC832x_RDB: update dts to use spi, register mmc_spi stub
From: Segher Boessenkool @ 2007-07-31 22:06 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev
In-Reply-To: <20070727114559.GB11463@localhost.localdomain>
>>> spi@4c0 {
>>> device_type = "spi";
>>> + device-id = <1>;
>>
>> Can we just use the reg value for bus_num in the kernel.
>
> Sure, technically nothing prevents this. But, QE specs names
> SPIs by these ids.
As a minimum the property name should start with "fsl," then.
> Plus, from the kernel side spi name will be
> not pretty, it will be spi1216.1.
What, the kernel cannot implement a counter itself?
>>> + max-chipselect = <1>;
>>
>> I'm not sure how I feel about this in here, I'm thinking it should go.
>
> It's board-specific, i.e. how much chips connected to this SPI bus.
It is misnamed then. It should be automatically derived from
the child nodes, though.
>>> + mmc@01 {
@01 should be @1. Except that it is wrong, since there is
no "reg" property.
>>> + device_type = "mmc";
No device_type please.
>>> + compatible = "mmc-spi";
Needs to be more specific.
>>> + device-id = <1>;
Get rid of this.
>>> + max-speed-hz = <bebc20>; /* 12500000 Hz */
Just max-speed.
>>> + chip-select = <0>;
This should be named "reg". And the parent needs #address-cells
and #size-cells properties.
>>> + pio-handle = <&mmc1pio>;
What is this for?
>> we should do this in board code and not the device tree.
>
> Well, I've done this initially. But Vitaly hinted that this could
> be done in the DT instead, which made sense to me - mmc is the child
> device of SPI bus. Why do you think it shouldn't be in the DT? I'm
> not arguing, just want understand this.
The hardware should be described in the device tree. This isn't
the same as simply copying all your Linux code into it ;-)
Segher
^ permalink raw reply
* [PATCH v2 2/3] powerpc: create pci err platform device for EDAC on mpc85xx
From: Dave Jiang @ 2007-07-31 22:07 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <20070726222021.GA10427@blade.az.mvista.com>
Creating a platform device for the PCI error registers in order for the
mpc85xx EDAC driver to pick up proper resources. This is to prevent the EDAC
driver from monopolizing the of_device and thus preventing future PCI code from
using the PCI of_device(s).
Signed-off-by: Dave Jiang <djiang@mvista.com>
---
fsl_soc.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 727453d..fff7c91 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1186,3 +1186,32 @@ err:
arch_initcall(cpm_smc_uart_of_init);
#endif /* CONFIG_8xx */
+
+#ifdef CONFIG_85xx
+
+/* setting up 85xx PCI error platform device for EDAC consumption */
+static int __init mpc85xx_pcierr_setup(void)
+{
+ struct device_node *np = NULL;
+ int id = 0;
+ struct resource res[2];
+
+ for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") {
+ memset(res, 0, sizeof(struct resource) * 2);
+ if (of_address_to_resource(np, 0, &res[0])) {
+ printk(KERN_WARNING "Can't get pci register base!\n");
+ continue;
+ }
+
+ /* move start to where the error registers are */
+ res[0].start += 0xe00;
+
+ of_irq_to_resource(np, 0, &res[1]);
+ platform_device_register_simple("mpc85xx_pci_err", id, res, 2);
+ id++;
+ }
+ return 0;
+}
+arch_initcall(mpc85xx_pcierr_setup);
+
+#endif
^ permalink raw reply related
* [PATCH v2 1/3] powerpc: publish 85xx soc dts entries as of_device on cds and ads platforms
From: Dave Jiang @ 2007-07-31 22:05 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <20070726222021.GA10427@blade.az.mvista.com>
Publish the devices listed in dts under SOC as of_device just like what
mpc85xx_mds platforms do. The 85xx cds and ads platforms currently do not
export the devices in dts as of_device.
I need the memory controller, L2 cache-controller, and the PCI controller
published as of_device so the mpc85xx EDAC driver can claim them for usage.
Signed-off-by: Dave Jiang <djiang@mvista.com>
---
Same as the earlier posted patch. Reposting to keep patch numbers consistent
since there are 3 patches in the series now.
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 19 +++++++++++++++++++
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 19 +++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 40a8286..599d7f7 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -18,6 +18,8 @@
#include <linux/delay.h>
#include <linux/seq_file.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -254,6 +256,23 @@ static int __init mpc85xx_ads_probe(void)
return of_flat_dt_is_compatible(root, "MPC85xxADS");
}
+static struct of_device_id mpc85xx_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ {},
+};
+
+static int __init mpc85xx_publish_devices(void)
+{
+ if (!machine_is(mpc85xx_ads))
+ return 0;
+
+ of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
+
+ return 0;
+}
+device_initcall(mpc85xx_publish_devices);
+
define_machine(mpc85xx_ads) {
.name = "MPC85xx ADS",
.probe = mpc85xx_ads_probe,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 6a171e9..5294884 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -27,6 +27,8 @@
#include <linux/interrupt.h>
#include <linux/fsl_devices.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -342,6 +344,23 @@ static int __init mpc85xx_cds_probe(void)
return of_flat_dt_is_compatible(root, "MPC85xxCDS");
}
+static struct of_device_id mpc85xx_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ {},
+};
+
+static int __init mpc85xx_publish_devices(void)
+{
+ if (!machine_is(mpc85xx_cds))
+ return 0;
+
+ of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
+
+ return 0;
+}
+device_initcall(mpc85xx_publish_devices);
+
define_machine(mpc85xx_cds) {
.name = "MPC85xx CDS",
.probe = mpc85xx_cds_probe,
^ permalink raw reply related
* Re: [RFC][PATCH] MPC832x_RDB: update dts to use spi, register mmc_spi stub
From: Segher Boessenkool @ 2007-07-31 22:00 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070727164047.GB26893@ld0162-tx32.am.freescale.net>
> Naming devices for human consumption is a more general problem than
> device-id addresses; I'd like to see a standard "label" property added
> to
> the device tree spec that software could use to present a
> human-friendly
> label that corresponds to markings on the case, position on the board,
> etc.
For some buses, there is a "slot-names" property; some (non-core)
bindings seem to define a "location" property.
For "random" human-readable labelling, i.e. not corresponding to
physical markings on the hardware, I recommend you look for a
matching entry in /aliases. It won't ever be _exactly_ what you
want though, the Linux device namespace is separate from the
device tree.
Segher
^ permalink raw reply
* Re: [RFC][PATCH] MPC832x_RDB: update dts to use spi, registermmc_spi stub
From: Segher Boessenkool @ 2007-07-31 21:47 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linuxppc-dev
In-Reply-To: <02bd01c7cfbc$cf213610$02ac10ac@Jocke>
> Unless the DTS guys thinks otherwise, just rename to "cpu_qe".
> "qe" would then be reserved for true QE mode.
If I understand it correctly, this is a property of how the
driver works, not how the hardware works / is connected; so
there should be _no_ such property in the device tree.
If I understand that wrong :-), just keep mode = "cpu", but
add an extra (empty) property representing that you need some
quirky mode special thing.
Either way, don't use underscores.
Segher
^ permalink raw reply
* Re: [PATCH 1/3] Add a new member name to structure irq_host
From: Benjamin Herrenschmidt @ 2007-07-31 21:44 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Chen Gong, paulus
In-Reply-To: <f55fea27ac3a248cc99d52462d413e1e@kernel.crashing.org>
On Tue, 2007-07-31 at 21:42 +0200, Segher Boessenkool wrote:
> > Which makes me think (again) that we should have an optional
> > device_node
> > pointer in irq_host. I know you said you wanted the irq stuff to be OF
> > agnostic, but the reality is most of the implementations do have an OF
> > node. And all of the newer irq_host implementations do, with the
> > exception of PS3 and celleb - which are special.
>
> How do you suggest to get a reasonable display name out of
> the device tree? The recommended human-readable name for
> interrupt controller nodes is "interrupt-controller"...
> You cannot use "device_type" either, and using "compatible"
> requires selecting one of its string entries, and likely
> using a lookup table after that, too.
In that case, I would display the node full path.
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: Pegasos keyboard detection
From: Segher Boessenkool @ 2007-07-31 21:26 UTC (permalink / raw)
To: Alan Curry; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <200707250128.l6P1SWSF1336935@shell01.TheWorld.com>
> As of 2.6.22 the kernel doesn't recognize the i8042 keyboard/mouse
> controller
> on the PegasosPPC. This is because of a feature/bug in the OF device
> tree:
> the "device_type" attribute is an empty string instead of "8042" as the
> kernel expects. This patch (against 2.6.22.1) adds a secondary
> detection
> which looks for a device whose *name* is "8042" if there is no device
> whose
> *type* is "8042".
>
> Signed-off-by: Alan Curry <pacman@world.std.com>
>
> --- arch/powerpc/kernel/setup-common.c.orig 2007-07-24
> 19:04:17.000000000 -0500
> +++ arch/powerpc/kernel/setup-common.c 2007-07-24 19:06:36.000000000
> -0500
> @@ -487,6 +487,10 @@ int check_legacy_ioport(unsigned long ba
> switch(base_port) {
> case I8042_DATA_REG:
> np = of_find_node_by_type(NULL, "8042");
> + /* Pegasos has no device_type on its 8042 node, look for the
> + * name instead */
> + if (!np)
> + np = of_find_node_by_name(NULL, "8042");
[I know it already got merged, I'm behind on mail, but anyway...]
Could board-specific quirks like this please always include a
check for that board? Or, even better, do a fixup in the
bootwrapper.
In this case the workaround won't likely trigger on the wrong
boards, but "just a little bit" more dangerous workarounds
_will_, and the law of big numbers works against us...
Segher
^ permalink raw reply
* Re: DTC 1.0.0 Release Coming?
From: Segher Boessenkool @ 2007-07-31 21:11 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, Jon Loeliger
In-Reply-To: <20070727020041.GC1561@localhost.localdomain>
> Ok, figured out why. When I push, then pop a quilt patch some of the
> files end up with their original contents, but changed timestamps.
> That altered stat information causes git-diff-index to give false
> indications of changed files, so setlocalversion adds the -dirty.
> Running git status, or gitool or various other things causes git to
> notice that the files aren't really changed, updates the index and
> then the version is generated correctly again.
>
> Not very robust though.
Well you can't blame that on DTC's build system, nor on the
setlocalversion script, and not on Git either; it's a Quilt
problem...
Segher
^ permalink raw reply
* Re: DTC 1.0.0 Release Coming?
From: Segher Boessenkool @ 2007-07-31 21:09 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
In-Reply-To: <E1IDjSy-0003eC-T4@jdl.com>
> I'd like to make an official DTC Version 1.0.0 release soon!
> To that end, I've published a repo on jdl.com with a v1.0.0-rc1
> tag on it. I anticipate some updates to the Documentation before
> a final 1.0.0 release still. However, if you have something
> you would like to have be in The Real 1.0.0 release, please
> let me know soon!
It would be nice it it would compile on non-Linux systems.
Not a showstopper, but it would be nice :-)
Segher
^ permalink raw reply
* Re: ipv6 in yaboot
From: Doug Maxey @ 2007-07-31 21:08 UTC (permalink / raw)
To: Paul Nasrat; +Cc: Linux PowerPC List, yaboot-devel
In-Reply-To: <1185912661.9310.143.camel@enki.eridu>
On Tue, 31 Jul 2007 21:11:01 BST, Paul Nasrat wrote:
>On Tue, 2007-07-31 at 14:21 -0500, Doug Maxey wrote:
>> Howdy!
>>
>> I just got asked about ipv6 support in yaboot and a quick investigation
>> showed _no_ knowledge of the address formats in the code.
>
>We really just use OF for obp-tftp and don't have our own ip stack,
True. Was just curious about the handling of the address formats,
where the xxxx:... will probably be used. Several spots already make
lots of assumptions that the colons are only in the disklabel.
> as
>there is no 1275 standard for ipv6 (although some modern IBM firmwares
>which also have iscsi support it) it's somewhat hard.
Oh, I agree completely. Publication is still being worked. The good
news is that the description is already there. Once folks can see the
whole enchilada.
>
>> Should I be submitting an RFC for a full parser that can pick that
>> apart? Or does has someone have code lurking in the shadows, that
>> just needed some prompting? :)
>
>Have you tried it with firmware that supports obp-tftp over ipv6?
Heh. Not yet, but RSN.
^ permalink raw reply
* Embedded linux FTP Server
From: khollan @ 2007-07-31 21:03 UTC (permalink / raw)
To: linuxppc-embedded
Hey
Im looking for a basic ftp server to run on my ML410 Xilinx board, I was
looking on the net and couldn't find anything that stands out. Does anyone
have suggestions, or know of something that works well.
Thanks
kholland
--
View this message in context: http://www.nabble.com/Embedded-linux-FTP-Server-tf4196501.html#a11935088
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ 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