* Re: Parsing a bus fault message?
From: tiejun.chen @ 2010-09-29 8:49 UTC (permalink / raw)
To: Scott Wood; +Cc: david.hagood, linuxppc-dev, Ira W. Snyder
In-Reply-To: <20100928134554.323667e5@udp111988uds.am.freescale.net>
Scott Wood wrote:
> On Tue, 28 Sep 2010 08:31:54 -0700
> "Ira W. Snyder" <iws@ovro.caltech.edu> wrote:
>
>> On Tue, Sep 28, 2010 at 09:26:51AM -0500, david.hagood@gmail.com wrote:
>>> Alternatively, can somebody see a hint in the message that I don't know
>>> enough to pick out? At this point, my code is trying to memcpy() from the
>>> PCIe bus (mapped via the outbound ATMU) to local memory, so the fault is
>>> either a) the ATMU is not accessible b) the ATMU is accessible but not
>>> mapped (which I would have thought the ioremap call I made would have
>>> handled) or c) the chip is not able to bus master on the PCI bus.
>
> Check the LAWs, the outbound ATMU, and the PCI device's BAR. Make sure
I also meet machine check exception if configure LAW improperly for PCI. (i.e.
unmatched PCIe controller id.)
>From you log looks 0xexxxxxxx should be your PCI space. So you can check if that
fall into appropriate LAW configuration. Maybe you can post your boot log and
error log here.
> the address goes where you're expecting at each level.
>
>>> Machine check in kernel mode.
>>> Caused by (from SRR1=149030): Transfer error ack signal
>> ^^^ this is the line that contains some critical info
>>
>> In the 86xx CPU manual, you should be able to find information about the
>> SRR1 register. Decoding the hex SRR1=0x149030 may help.
Actually 'Transfer error ack signal' is the result just after kernel decode
SRR1/MSSSR0.
>>
>> The kernel is telling you this is a TEA (transfer error acknowledge)
>> error. I've only seen this when I get an unhandled timeout on the local
>> bus. For example, a FPGA that has died in the middle of a request.
>
I met this only one time when kernel access USB host controller REGs on one
mpc837x. But the same kernel is fine on another same version target. So I think
sometimes you have to check the hardware.
> I've seen it when you access a physical address that has no device
> backing it up.
>
Yes. This should be most common reason for machine check exception when we
access one address with cache inhibited.
>> On the PCI bus, I haven't seen this error. The 83xx PCI controller is
>> smart enough to return 0xffffffff when reading a non-existent device.
>
> I believe that behavior is configurable.
I know 0xfffffffff will be returned by some PCI controller when PCI controller
access non-existent device. Because PCI controller can't get any response from
that non-existed device. So PCI controller think this 'read' should be aborted
by asserting bus to one known state, 0xffffffff. But I have to admit I really am
not sure if this is configured. I prefer to this behavior should be associated
to the given PCI controller fixed feature.
Tiejun
>
> -Scott
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Avi Kivity @ 2010-09-29 8:32 UTC (permalink / raw)
To: Greg KH
Cc: linuxppc-dev, linux-kernel, Dave Hansen, linux-mm, Robin Holt,
KAMEZAWA Hiroyuki
In-Reply-To: <20100929025035.GA13096@kroah.com>
On 09/29/2010 04:50 AM, Greg KH wrote:
> >
> > Because the old ABI creates 129,000+ entries inside
> > /sys/devices/system/memory with their associated links from
> > /sys/devices/system/node/node*/ back to those directory entries.
> >
> > Thankfully things like rpm, hald, and other miscellaneous commands scan
> > that information.
>
> Really? Why? Why would rpm care about this? hald is dead now so we
> don't need to worry about that anymore,
That's not what compatiblity means. We can't just support
latest-and-greatest userspace on latest-and-greatest kernels.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
^ permalink raw reply
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Greg KH @ 2010-09-29 2:50 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, linux-kernel, Dave Hansen, linux-mm, Avi Kivity,
KAMEZAWA Hiroyuki
In-Reply-To: <20100928151218.GJ14068@sgi.com>
On Tue, Sep 28, 2010 at 10:12:18AM -0500, Robin Holt wrote:
> On Tue, Sep 28, 2010 at 02:44:40PM +0200, Avi Kivity wrote:
> > On 09/27/2010 09:09 PM, Nathan Fontenot wrote:
> > >This set of patches decouples the concept that a single memory
> > >section corresponds to a single directory in
> > >/sys/devices/system/memory/. On systems
> > >with large amounts of memory (1+ TB) there are perfomance issues
> > >related to creating the large number of sysfs directories. For
> > >a powerpc machine with 1 TB of memory we are creating 63,000+
> > >directories. This is resulting in boot times of around 45-50
> > >minutes for systems with 1 TB of memory and 8 hours for systems
> > >with 2 TB of memory. With this patch set applied I am now seeing
> > >boot times of 5 minutes or less.
> > >
> > >The root of this issue is in sysfs directory creation. Every time
> > >a directory is created a string compare is done against all sibling
> > >directories to ensure we do not create duplicates. The list of
> > >directory nodes in sysfs is kept as an unsorted list which results
> > >in this being an exponentially longer operation as the number of
> > >directories are created.
> > >
> > >The solution solved by this patch set is to allow a single
> > >directory in sysfs to span multiple memory sections. This is
> > >controlled by an optional architecturally defined function
> > >memory_block_size_bytes(). The default definition of this
> > >routine returns a memory block size equal to the memory section
> > >size. This maintains the current layout of sysfs memory
> > >directories as it appears to userspace to remain the same as it
> > >is today.
> > >
> >
> > Why not update sysfs directory creation to be fast, for example by
> > using an rbtree instead of a linked list. This fixes an
> > implementation problem in the kernel instead of working around it
> > and creating a new ABI.
>
> Because the old ABI creates 129,000+ entries inside
> /sys/devices/system/memory with their associated links from
> /sys/devices/system/node/node*/ back to those directory entries.
>
> Thankfully things like rpm, hald, and other miscellaneous commands scan
> that information.
Really? Why? Why would rpm care about this? hald is dead now so we
don't need to worry about that anymore, but what other commands/programs
read this information?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 1/1 v3] Add kernel parameter to disable batched hcalls
From: Will Schmidt @ 2010-09-29 1:33 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <20100928175206.GA15783@lixom.net>
This introduces a pair of kernel parameters that can be used to disable
the MULTITCE and BULK_REMOVE h-calls.
By default, those hcalls are enabled, active, and good for throughput
and performance. The ability to disable them will be useful for some of
the PREEMPT_RT related investigation and work occurring on Power.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
cc: Olof Johansson <olof@lixom.net>
cc: Anton Blanchard <anton@samba.org>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
v2 - Per feedback from Olof, the code is reworked to utilize kernel
parameter runtime checks, rather than CONFIG options.
- Added relevant change to kernel-parameters.txt
v3 - ran through checkpatch and fixed whitespace issues.
- consolidated the if() staircases to save indentation.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e2c7487..5c40801 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -426,6 +426,10 @@ and is between 256 and 4096 characters. It is defined in the file
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
+ bulk_remove=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for flushing multiple hpte entries
+ at a time.
+
BusLogic= [HW,SCSI]
See drivers/scsi/BusLogic.c, comment before function
BusLogic_ParseDriverOptions().
@@ -1499,6 +1503,10 @@ and is between 256 and 4096 characters. It is defined in the file
mtdparts= [MTD]
See drivers/mtd/cmdlinepart.c.
+ multitce=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for updating multiple TCE entries
+ at a time.
+
onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration
Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 902987d..e174a2f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -625,3 +625,17 @@ void iommu_init_early_pSeries(void)
set_pci_dma_ops(&dma_iommu_ops);
}
+static int __init disable_multitce(char *str)
+{
+ if (strcmp(str, "off") == 0 &&
+ firmware_has_feature(FW_FEATURE_LPAR) &&
+ firmware_has_feature(FW_FEATURE_MULTITCE)) {
+ printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
+ ppc_md.tce_build = tce_build_pSeriesLP;
+ ppc_md.tce_free = tce_free_pSeriesLP;
+ powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
+ }
+ return 1;
+}
+
+__setup("multitce=", disable_multitce);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 0707653..82d15e7 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -599,6 +599,18 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
}
+static int __init disable_bulk_remove(char *str)
+{
+ if (strcmp(str, "off") == 0 &&
+ firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+ printk(KERN_INFO "Disabling BULK_REMOVE firmware feature");
+ powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE;
+ }
+ return 1;
+}
+
+__setup("bulk_remove=", disable_bulk_remove);
+
void __init hpte_init_lpar(void)
{
ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
^ permalink raw reply related
* Re: [PATCH (Option 1)] of/i2c: fix module load order issue caused by of_i2c.c
From: Ben Dooks @ 2010-09-28 23:20 UTC (permalink / raw)
To: Grant Likely; +Cc: mikpe, linux-kernel, rdunlap, linux-i2c, khali, linuxppc-dev
In-Reply-To: <20100924221313.28357.61419.stgit@angua>
On Fri, Sep 24, 2010 at 04:14:53PM -0600, Grant Likely wrote:
> Commit 959e85f7, "i2c: add OF-style registration and binding" caused a
> module dependency loop where of_i2c.c calls functions in i2c-core, and
> i2c-core calls of_i2c_register_devices() in of_i2c. This means that
> when i2c support is built as a module when CONFIG_OF is set, then
> neither i2c_core nor of_i2c are able to be loaded.
>
> This patch fixes the problem by moving the of_i2c_register_devices()
> function into the body of i2c_core and renaming it to
> i2c_scan_of_devices (of_i2c_register_devices is analogous to the
> existing i2c_scan_static_board_info function and so should be named
> similarly). This function isn't called by any code outside of
> i2c_core, and it must always be present when CONFIG_OF is selected, so
> it makes sense to locate it there. When CONFIG_OF is not selected,
> of_i2c_register_devices() becomes a no-op.
I sort of go with this one.
--
Ben
Q: What's a light-year?
A: One-third less calories than a regular year.
^ permalink raw reply
* Re: [PATCH (Option 1)] of/i2c: fix module load order issue caused by of_i2c.c
From: Ben Dooks @ 2010-09-28 23:21 UTC (permalink / raw)
To: Grant Likely; +Cc: mikpe, linux-kernel, rdunlap, linux-i2c, khali, linuxppc-dev
In-Reply-To: <20100924221313.28357.61419.stgit@angua>
On Fri, Sep 24, 2010 at 04:14:53PM -0600, Grant Likely wrote:
> Commit 959e85f7, "i2c: add OF-style registration and binding" caused a
> module dependency loop where of_i2c.c calls functions in i2c-core, and
> i2c-core calls of_i2c_register_devices() in of_i2c. This means that
> when i2c support is built as a module when CONFIG_OF is set, then
> neither i2c_core nor of_i2c are able to be loaded.
>
> This patch fixes the problem by moving the of_i2c_register_devices()
> function into the body of i2c_core and renaming it to
> i2c_scan_of_devices (of_i2c_register_devices is analogous to the
> existing i2c_scan_static_board_info function and so should be named
> similarly). This function isn't called by any code outside of
> i2c_core, and it must always be present when CONFIG_OF is selected, so
> it makes sense to locate it there. When CONFIG_OF is not selected,
> of_i2c_register_devices() becomes a no-op.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> drivers/i2c/i2c-core.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++--
> drivers/of/of_i2c.c | 57 ---------------------------------------------
> include/linux/of_i2c.h | 7 ------
> 3 files changed, 59 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index 6649176..64a261b 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -32,8 +32,8 @@
> #include <linux/init.h>
> #include <linux/idr.h>
> #include <linux/mutex.h>
> -#include <linux/of_i2c.h>
> #include <linux/of_device.h>
> +#include <linux/of_irq.h>
> #include <linux/completion.h>
> #include <linux/hardirq.h>
> #include <linux/irqflags.h>
> @@ -818,6 +818,63 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
> up_read(&__i2c_board_lock);
> }
>
> +#ifdef CONFIG_OF
> +void i2c_scan_of_devices(struct i2c_adapter *adap)
> +{
> + void *result;
> + struct device_node *node;
> +
> + /* Only register child devices if the adapter has a node pointer set */
> + if (!adap->dev.of_node)
> + return;
> +
> + for_each_child_of_node(adap->dev.of_node, node) {
> + struct i2c_board_info info = {};
> + struct dev_archdata dev_ad = {};
> + const __be32 *addr;
> + int len;
> +
> + dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
> + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
> + dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
> + node->full_name);
> + continue;
> + }
> +
> + addr = of_get_property(node, "reg", &len);
> + if (!addr || (len < sizeof(int))) {
> + dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
> + node->full_name);
> + continue;
> + }
> +
> + info.addr = be32_to_cpup(addr);
> + if (info.addr > (1 << 10) - 1) {
> + dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
> + info.addr, node->full_name);
> + continue;
> + }
> +
> + info.irq = irq_of_parse_and_map(node, 0);
> + info.of_node = of_node_get(node);
> + info.archdata = &dev_ad;
> +
> + request_module("%s", info.type);
> +
> + result = i2c_new_device(adap, &info);
> + if (result == NULL) {
> + dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
> + node->full_name);
> + of_node_put(node);
> + irq_dispose_mapping(info.irq);
> + continue;
> + }
> + }
> +}
> +#else
> +static inline void i2c_scan_of_devices(struct i2c_adapter *adap) { }
> +#endif
Is there any advantage to just making the definition in the header
file a static inline and removing the #else part of this?
--
Ben
Q: What's a light-year?
A: One-third less calories than a regular year.
^ permalink raw reply
* Re: [PATCH (Option 1)] of/i2c: fix module load order issue caused by of_i2c.c
From: Grant Likely @ 2010-09-28 23:26 UTC (permalink / raw)
To: Ben Dooks; +Cc: mikpe, linux-kernel, rdunlap, linux-i2c, khali, linuxppc-dev
In-Reply-To: <20100928232147.GR21564@trinity.fluff.org>
On Wed, Sep 29, 2010 at 8:21 AM, Ben Dooks <ben-i2c@fluff.org> wrote:
> On Fri, Sep 24, 2010 at 04:14:53PM -0600, Grant Likely wrote:
>> Commit 959e85f7, "i2c: add OF-style registration and binding" caused a
>> module dependency loop where of_i2c.c calls functions in i2c-core, and
>> i2c-core calls of_i2c_register_devices() in of_i2c. =A0This means that
>> when i2c support is built as a module when CONFIG_OF is set, then
>> neither i2c_core nor of_i2c are able to be loaded.
>>
>> This patch fixes the problem by moving the of_i2c_register_devices()
>> function into the body of i2c_core and renaming it to
>> i2c_scan_of_devices (of_i2c_register_devices is analogous to the
>> existing i2c_scan_static_board_info function and so should be named
>> similarly). =A0This function isn't called by any code outside of
>> i2c_core, and it must always be present when CONFIG_OF is selected, so
>> it makes sense to locate it there. =A0When CONFIG_OF is not selected,
>> of_i2c_register_devices() becomes a no-op.
>>
>> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
>> ---
>> =A0drivers/i2c/i2c-core.c | =A0 61 +++++++++++++++++++++++++++++++++++++=
+++++++++--
>> =A0drivers/of/of_i2c.c =A0 =A0| =A0 57 ---------------------------------=
------------
>> =A0include/linux/of_i2c.h | =A0 =A07 ------
>> =A03 files changed, 59 insertions(+), 66 deletions(-)
>>
>> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
>> index 6649176..64a261b 100644
>> --- a/drivers/i2c/i2c-core.c
>> +++ b/drivers/i2c/i2c-core.c
>> @@ -32,8 +32,8 @@
>> =A0#include <linux/init.h>
>> =A0#include <linux/idr.h>
>> =A0#include <linux/mutex.h>
>> -#include <linux/of_i2c.h>
>> =A0#include <linux/of_device.h>
>> +#include <linux/of_irq.h>
>> =A0#include <linux/completion.h>
>> =A0#include <linux/hardirq.h>
>> =A0#include <linux/irqflags.h>
>> @@ -818,6 +818,63 @@ static void i2c_scan_static_board_info(struct i2c_a=
dapter *adapter)
>> =A0 =A0 =A0 up_read(&__i2c_board_lock);
>> =A0}
>>
>> +#ifdef CONFIG_OF
>> +void i2c_scan_of_devices(struct i2c_adapter *adap)
>> +{
>> + =A0 =A0 void *result;
>> + =A0 =A0 struct device_node *node;
>> +
>> + =A0 =A0 /* Only register child devices if the adapter has a node point=
er set */
>> + =A0 =A0 if (!adap->dev.of_node)
>> + =A0 =A0 =A0 =A0 =A0 =A0 return;
>> +
>> + =A0 =A0 for_each_child_of_node(adap->dev.of_node, node) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 struct i2c_board_info info =3D {};
>> + =A0 =A0 =A0 =A0 =A0 =A0 struct dev_archdata dev_ad =3D {};
>> + =A0 =A0 =A0 =A0 =A0 =A0 const __be32 *addr;
>> + =A0 =A0 =A0 =A0 =A0 =A0 int len;
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(&adap->dev, "of_i2c: register %s\n", n=
ode->full_name);
>> + =A0 =A0 =A0 =A0 =A0 =A0 if (of_modalias_node(node, info.type, sizeof(i=
nfo.type)) < 0) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&adap->dev, "of_i2c: m=
odalias failure on %s\n",
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 node->full_nam=
e);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
>> + =A0 =A0 =A0 =A0 =A0 =A0 }
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 addr =3D of_get_property(node, "reg", &len);
>> + =A0 =A0 =A0 =A0 =A0 =A0 if (!addr || (len < sizeof(int))) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&adap->dev, "of_i2c: i=
nvalid reg on %s\n",
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 node->full_nam=
e);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
>> + =A0 =A0 =A0 =A0 =A0 =A0 }
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 info.addr =3D be32_to_cpup(addr);
>> + =A0 =A0 =A0 =A0 =A0 =A0 if (info.addr > (1 << 10) - 1) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&adap->dev, "of_i2c: i=
nvalid addr=3D%x on %s\n",
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 info.addr, nod=
e->full_name);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
>> + =A0 =A0 =A0 =A0 =A0 =A0 }
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 info.irq =3D irq_of_parse_and_map(node, 0);
>> + =A0 =A0 =A0 =A0 =A0 =A0 info.of_node =3D of_node_get(node);
>> + =A0 =A0 =A0 =A0 =A0 =A0 info.archdata =3D &dev_ad;
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 request_module("%s", info.type);
>> +
>> + =A0 =A0 =A0 =A0 =A0 =A0 result =3D i2c_new_device(adap, &info);
>> + =A0 =A0 =A0 =A0 =A0 =A0 if (result =3D=3D NULL) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&adap->dev, "of_i2c: F=
ailure registering %s\n",
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 node->full_nam=
e);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(node);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 irq_dispose_mapping(info.irq);
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
>> + =A0 =A0 =A0 =A0 =A0 =A0 }
>> + =A0 =A0 }
>> +}
>> +#else
>> +static inline void i2c_scan_of_devices(struct i2c_adapter *adap) { }
>> +#endif
>
> Is there any advantage to just making the definition in the header
> file a static inline and removing the #else part of this?
I'm not sure what you mean. This particular patch makes
i2c_scan_of_devices() completely internal to i2c-core.c so that there
is no need to expose it in the header file at all.
g.
>
> --
> Ben
>
> Q: =A0 =A0 =A0What's a light-year?
> A: =A0 =A0 =A0One-third less calories than a regular year.
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* [PATCH v3 2/2] USB: add USB EHCI support for MPC5121 SoC
From: Anatolij Gustschin @ 2010-09-28 18:55 UTC (permalink / raw)
To: linux-usb
Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
linuxppc-dev, Anatolij Gustschin
In-Reply-To: <1285666594-21150-1-git-send-email-agust@denx.de>
Extends FSL EHCI platform driver glue layer to support
MPC5121 USB controllers. MPC5121 Rev 2.0 silicon EHCI
registers are in big endian format. The appropriate flags
are set using the information in the platform data structure.
MPC83xx system interface registers are not available on
MPC512x, so the access to these registers is isolated in
MPC512x case. Furthermore the USB controller clocks
must be enabled before 512x register accesses which is
done by providing platform specific init callback.
The MPC512x internal USB PHY doesn't provide supply voltage.
For boards using different power switches allow specifying
DRVVBUS and PWR_FAULT signal polarity of the MPC5121 internal
PHY using "fsl,invert-drvvbus" and "fsl,invert-pwr-fault"
properties in the device tree USB nodes. Adds documentation
for this new device tree bindings.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
v3:
- rebased after changing of_platform_driver to platform_driver
Documentation/powerpc/dts-bindings/fsl/usb.txt | 22 +++++
drivers/usb/Kconfig | 1 +
drivers/usb/host/Kconfig | 6 +-
drivers/usb/host/ehci-fsl.c | 99 +++++++++++++++++-------
drivers/usb/host/ehci-fsl.h | 13 +++-
drivers/usb/host/ehci-mem.c | 2 +-
drivers/usb/host/fsl-mph-dr-of.c | 89 +++++++++++++++++++++
include/linux/fsl_devices.h | 15 ++++
8 files changed, 215 insertions(+), 32 deletions(-)
diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentation/powerpc/dts-bindings/fsl/usb.txt
index b001524..bd5723f 100644
--- a/Documentation/powerpc/dts-bindings/fsl/usb.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/usb.txt
@@ -8,6 +8,7 @@ and additions :
Required properties :
- compatible : Should be "fsl-usb2-mph" for multi port host USB
controllers, or "fsl-usb2-dr" for dual role USB controllers
+ or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
- phy_type : For multi port host USB controllers, should be one of
"ulpi", or "serial". For dual role USB controllers, should be
one of "ulpi", "utmi", "utmi_wide", or "serial".
@@ -33,6 +34,12 @@ Recommended properties :
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
+Optional properties :
+ - fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
+ port power polarity of internal PHY signal DRVVBUS is inverted.
+ - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
+ the PWR_FAULT signal polarity is inverted.
+
Example multi port host USB controller device node :
usb@22000 {
compatible = "fsl-usb2-mph";
@@ -57,3 +64,18 @@ Example dual role USB controller device node :
dr_mode = "otg";
phy = "ulpi";
};
+
+Example dual role USB controller device node for MPC5121ADS:
+
+ usb@4000 {
+ compatible = "fsl,mpc5121-usb2-dr";
+ reg = <0x4000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = < &ipic >;
+ interrupts = <44 0x8>;
+ dr_mode = "otg";
+ phy_type = "utmi_wide";
+ fsl,invert-drvvbus;
+ fsl,invert-pwr-fault;
+ };
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 4aa00e6..67eb377 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -59,6 +59,7 @@ config USB_ARCH_HAS_OHCI
config USB_ARCH_HAS_EHCI
boolean
default y if PPC_83xx
+ default y if PPC_MPC512x
default y if SOC_AU1200
default y if ARCH_IXP4XX
default y if ARCH_W90X900
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f3a90b0..bf2e7d2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED
config USB_EHCI_BIG_ENDIAN_MMIO
bool
- depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
+ depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \
+ XPS_USB_HCD_XILINX || PPC_MPC512x)
default y
config USB_EHCI_BIG_ENDIAN_DESC
bool
- depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
+ depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
+ PPC_MPC512x)
default y
config XPS_USB_HCD_XILINX
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 8600317..86e4289 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -116,13 +116,33 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
goto err3;
}
- /* Enable USB controller */
- temp = in_be32(hcd->regs + 0x500);
- out_be32(hcd->regs + 0x500, temp | 0x4);
+ pdata->regs = hcd->regs;
- /* Set to Host mode */
- temp = in_le32(hcd->regs + 0x1a8);
- out_le32(hcd->regs + 0x1a8, temp | 0x3);
+ /*
+ * do platform specific init: check the clock, grab/config pins, etc.
+ */
+ if (pdata->init && pdata->init(pdev)) {
+ retval = -ENODEV;
+ goto err3;
+ }
+
+ /*
+ * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
+ * flag for 83xx or 8536 system interface registers.
+ */
+ if (pdata->big_endian_mmio)
+ temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
+ else
+ temp = in_le32(hcd->regs + FSL_SOC_USB_ID);
+
+ if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
+ pdata->have_sysif_regs = 1;
+
+ /* Enable USB controller, 83xx or 8536 */
+ if (pdata->have_sysif_regs)
+ setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
+
+ /* Don't need to set host mode here. It will be done by tdi_reset() */
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
@@ -137,6 +157,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
usb_put_hcd(hcd);
err1:
dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
+ if (pdata->exit)
+ pdata->exit(pdev);
return retval;
}
@@ -154,17 +176,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
usb_remove_hcd(hcd);
+
+ /*
+ * do platform specific un-initialization:
+ * release iomux pins, disable clock, etc.
+ */
+ if (pdata->exit)
+ pdata->exit(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}
-static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
- enum fsl_usb2_phy_modes phy_mode,
- unsigned int port_offset)
+static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
+ enum fsl_usb2_phy_modes phy_mode,
+ unsigned int port_offset)
{
- u32 portsc = 0;
+ u32 portsc;
+
+ portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
+ portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
+
switch (phy_mode) {
case FSL_USB2_PHY_ULPI:
portsc |= PORT_PTS_ULPI;
@@ -184,20 +219,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
}
-static void mpc83xx_usb_setup(struct usb_hcd *hcd)
+static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
struct fsl_usb2_platform_data *pdata;
void __iomem *non_ehci = hcd->regs;
u32 temp;
- pdata =
- (struct fsl_usb2_platform_data *)hcd->self.controller->
- platform_data;
+ pdata = hcd->self.controller->platform_data;
+
/* Enable PHY interface in the control reg. */
- temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
- out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
- out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+ if (pdata->have_sysif_regs) {
+ temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+ out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
+ out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+ }
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
/*
@@ -214,7 +250,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
(pdata->operating_mode == FSL_USB2_DR_OTG))
- mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+ ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
unsigned int chip, rev, svr;
@@ -228,25 +264,27 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
ehci->has_fsl_port_bug = 1;
if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
- mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+ ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
- mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
+ ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
}
+ if (pdata->have_sysif_regs) {
#ifdef CONFIG_PPC_85xx
- out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
- out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
+ out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
+ out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
#else
- out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
- out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
+ out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
+ out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
#endif
- out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
+ out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
+ }
}
/* called after powerup, by probe or system-pm "wakeup" */
static int ehci_fsl_reinit(struct ehci_hcd *ehci)
{
- mpc83xx_usb_setup(ehci_to_hcd(ehci));
+ ehci_fsl_usb_setup(ehci);
ehci_port_power(ehci, 0);
return 0;
@@ -257,6 +295,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
+ ehci->big_endian_desc = pdata->big_endian_desc;
+ ehci->big_endian_mmio = pdata->big_endian_mmio;
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
@@ -370,7 +413,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_USB2,
+ .flags = HCD_USB2 | HCD_MEMORY,
/*
* basic lifecycle operations
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index eb537aa..2c83537 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 freescale semiconductor
+/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
* Copyright (c) 2005 MontaVista Software
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,9 @@
#define _EHCI_FSL_H
/* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_ID 0x0
+#define ID_MSK 0x3f
+#define NID_MSK 0x3f00
#define FSL_SOC_USB_ULPIVP 0x170
#define FSL_SOC_USB_PORTSC1 0x184
#define PORT_PTS_MSK (3<<30)
@@ -27,6 +30,14 @@
#define PORT_PTS_SERIAL (3<<30)
#define PORT_PTS_PTW (1<<28)
#define FSL_SOC_USB_PORTSC2 0x188
+
+#define FSL_SOC_USB_USBGENCTRL 0x200
+#define USBGENCTRL_PPP (1 << 3)
+#define USBGENCTRL_PFP (1 << 2)
+#define FSL_SOC_USB_ISIPHYCTRL 0x204
+#define ISIPHYCTRL_PXE (1)
+#define ISIPHYCTRL_PHYE (1 << 4)
+
#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 1f3f01e..d36e4e7 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
{
memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma;
- qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
+ qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
qtd->hw_next = EHCI_LIST_END(ehci);
qtd->hw_alt_next = EHCI_LIST_END(ehci);
INIT_LIST_HEAD (&qtd->qtd_list);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 12db5d5..574b99e 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of_platform.h>
+#include <linux/clk.h>
struct fsl_usb2_dev_data {
char *dr_mode; /* controller mode */
@@ -153,6 +154,12 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
pdata->operating_mode = FSL_USB2_MPH_HOST;
} else {
+ if (of_get_property(np, "fsl,invert-drvvbus", NULL))
+ pdata->invert_drvvbus = 1;
+
+ if (of_get_property(np, "fsl,invert-pwr-fault", NULL))
+ pdata->invert_pwr_fault = 1;
+
/* setup mode selected in the device tree */
pdata->operating_mode = dev_data->op_mode;
}
@@ -186,9 +193,91 @@ static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
return 0;
}
+#ifdef CONFIG_PPC_MPC512x
+
+#define USBGENCTRL 0x200 /* NOTE: big endian */
+#define GC_WU_INT_CLR (1 << 5) /* Wakeup int clear */
+#define GC_ULPI_SEL (1 << 4) /* ULPI i/f select (usb0 only)*/
+#define GC_PPP (1 << 3) /* Inv. Port Power Polarity */
+#define GC_PFP (1 << 2) /* Inv. Power Fault Polarity */
+#define GC_WU_ULPI_EN (1 << 1) /* Wakeup on ULPI event */
+#define GC_WU_IE (1 << 1) /* Wakeup interrupt enable */
+
+#define ISIPHYCTRL 0x204 /* NOTE: big endian */
+#define PHYCTRL_PHYE (1 << 4) /* On-chip UTMI PHY enable */
+#define PHYCTRL_BSENH (1 << 3) /* Bit Stuff Enable High */
+#define PHYCTRL_BSEN (1 << 2) /* Bit Stuff Enable */
+#define PHYCTRL_LSFE (1 << 1) /* Line State Filter Enable */
+#define PHYCTRL_PXE (1 << 0) /* PHY oscillator enable */
+
+int fsl_usb2_mpc5121_init(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct clk *clk;
+ char clk_name[10];
+ int base, clk_num;
+
+ base = pdev->resource->start & 0xf000;
+ if (base == 0x3000)
+ clk_num = 1;
+ else if (base == 0x4000)
+ clk_num = 2;
+ else
+ return -ENODEV;
+
+ snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num);
+ clk = clk_get(&pdev->dev, clk_name);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get clk\n");
+ return PTR_ERR(clk);
+ }
+
+ clk_enable(clk);
+ pdata->clk = clk;
+
+ if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) {
+ u32 reg = 0;
+
+ if (pdata->invert_drvvbus)
+ reg |= GC_PPP;
+
+ if (pdata->invert_pwr_fault)
+ reg |= GC_PFP;
+
+ out_be32(pdata->regs + ISIPHYCTRL, PHYCTRL_PHYE | PHYCTRL_PXE);
+ out_be32(pdata->regs + USBGENCTRL, reg);
+ }
+ return 0;
+}
+
+static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ pdata->regs = NULL;
+
+ if (pdata->clk) {
+ clk_disable(pdata->clk);
+ clk_put(pdata->clk);
+ }
+}
+
+struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
+ .big_endian_desc = 1,
+ .big_endian_mmio = 1,
+ .es = 1,
+ .le_setup_buf = 1,
+ .init = fsl_usb2_mpc5121_init,
+ .exit = fsl_usb2_mpc5121_exit,
+};
+#endif /* CONFIG_PPC_MPC512x */
+
static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
{ .compatible = "fsl-usb2-mph", },
{ .compatible = "fsl-usb2-dr", },
+#ifdef CONFIG_PPC_MPC512x
+ { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, },
+#endif
{},
};
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 28e33fe..d5f9a74 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -58,11 +58,26 @@ enum fsl_usb2_phy_modes {
FSL_USB2_PHY_SERIAL,
};
+struct clk;
+struct platform_device;
+
struct fsl_usb2_platform_data {
/* board specific information */
enum fsl_usb2_operating_modes operating_mode;
enum fsl_usb2_phy_modes phy_mode;
unsigned int port_enables;
+
+ int (*init)(struct platform_device *);
+ void (*exit)(struct platform_device *);
+ void __iomem *regs; /* ioremap'd register base */
+ struct clk *clk;
+ unsigned big_endian_mmio:1;
+ unsigned big_endian_desc:1;
+ unsigned es:1; /* need USBMODE:ES */
+ unsigned le_setup_buf:1;
+ unsigned have_sysif_regs:1;
+ unsigned invert_drvvbus:1;
+ unsigned invert_pwr_fault:1;
};
/* Flags in fsl_usb2_mph_platform_data */
--
1.7.0.4
^ permalink raw reply related
* [PATCH v3 1/2] USB: add platform glue driver for FSL USB DR controller
From: Anatolij Gustschin @ 2010-09-28 18:55 UTC (permalink / raw)
To: linux-usb
Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
linuxppc-dev, Anatolij Gustschin
In-Reply-To: <1285666594-21150-1-git-send-email-agust@denx.de>
Replace FSL USB platform code by simple platform driver for
creation of FSL USB platform devices.
The driver creates platform devices based on the information
from USB nodes in the flat device tree. This is the replacement
for old arch fsl_soc usb code removed by this patch. The driver
uses usual of-style binding, available EHCI-HCD and UDC
drivers can be bound to the created devices. The new of-style
driver additionaly instantiates USB OTG platform device, as the
appropriate USB OTG driver will be added soon.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
v3:
- merged patches 1/3 and 2/3 of the previous version
- changed to platform_driver as requested
- fixed probe() to avoid modification of driver's
shared platform data struct pointed to by 'data' in
the match table which is added by the next patch of
the series
arch/powerpc/sysdev/fsl_soc.c | 163 ----------------------------
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/host/Kconfig | 4 +
drivers/usb/host/Makefile | 1 +
drivers/usb/host/fsl-mph-dr-of.c | 219 ++++++++++++++++++++++++++++++++++++++
5 files changed, 225 insertions(+), 163 deletions(-)
create mode 100644 drivers/usb/host/fsl-mph-dr-of.c
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index b91f7ac..49a51f1 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -209,169 +209,6 @@ static int __init of_add_fixed_phys(void)
arch_initcall(of_add_fixed_phys);
#endif /* CONFIG_FIXED_PHY */
-static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
-{
- if (!phy_type)
- return FSL_USB2_PHY_NONE;
- if (!strcasecmp(phy_type, "ulpi"))
- return FSL_USB2_PHY_ULPI;
- if (!strcasecmp(phy_type, "utmi"))
- return FSL_USB2_PHY_UTMI;
- if (!strcasecmp(phy_type, "utmi_wide"))
- return FSL_USB2_PHY_UTMI_WIDE;
- if (!strcasecmp(phy_type, "serial"))
- return FSL_USB2_PHY_SERIAL;
-
- return FSL_USB2_PHY_NONE;
-}
-
-static int __init fsl_usb_of_init(void)
-{
- struct device_node *np;
- unsigned int i = 0;
- struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
- *usb_dev_dr_client = NULL;
- int ret;
-
- for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
- struct resource r[2];
- struct fsl_usb2_platform_data usb_data;
- const unsigned char *prop = NULL;
-
- memset(&r, 0, sizeof(r));
- memset(&usb_data, 0, sizeof(usb_data));
-
- ret = of_address_to_resource(np, 0, &r[0]);
- if (ret)
- goto err;
-
- of_irq_to_resource(np, 0, &r[1]);
-
- usb_dev_mph =
- platform_device_register_simple("fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_mph)) {
- ret = PTR_ERR(usb_dev_mph);
- goto err;
- }
-
- usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
-
- usb_data.operating_mode = FSL_USB2_MPH_HOST;
-
- prop = of_get_property(np, "port0", NULL);
- if (prop)
- usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
-
- prop = of_get_property(np, "port1", NULL);
- if (prop)
- usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
-
- prop = of_get_property(np, "phy_type", NULL);
- usb_data.phy_mode = determine_usb_phy(prop);
-
- ret =
- platform_device_add_data(usb_dev_mph, &usb_data,
- sizeof(struct
- fsl_usb2_platform_data));
- if (ret)
- goto unreg_mph;
- i++;
- }
-
- for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
- struct resource r[2];
- struct fsl_usb2_platform_data usb_data;
- const unsigned char *prop = NULL;
-
- if (!of_device_is_available(np))
- continue;
-
- memset(&r, 0, sizeof(r));
- memset(&usb_data, 0, sizeof(usb_data));
-
- ret = of_address_to_resource(np, 0, &r[0]);
- if (ret)
- goto unreg_mph;
-
- of_irq_to_resource(np, 0, &r[1]);
-
- prop = of_get_property(np, "dr_mode", NULL);
-
- if (!prop || !strcmp(prop, "host")) {
- usb_data.operating_mode = FSL_USB2_DR_HOST;
- usb_dev_dr_host = platform_device_register_simple(
- "fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_dr_host)) {
- ret = PTR_ERR(usb_dev_dr_host);
- goto err;
- }
- } else if (prop && !strcmp(prop, "peripheral")) {
- usb_data.operating_mode = FSL_USB2_DR_DEVICE;
- usb_dev_dr_client = platform_device_register_simple(
- "fsl-usb2-udc", i, r, 2);
- if (IS_ERR(usb_dev_dr_client)) {
- ret = PTR_ERR(usb_dev_dr_client);
- goto err;
- }
- } else if (prop && !strcmp(prop, "otg")) {
- usb_data.operating_mode = FSL_USB2_DR_OTG;
- usb_dev_dr_host = platform_device_register_simple(
- "fsl-ehci", i, r, 2);
- if (IS_ERR(usb_dev_dr_host)) {
- ret = PTR_ERR(usb_dev_dr_host);
- goto err;
- }
- usb_dev_dr_client = platform_device_register_simple(
- "fsl-usb2-udc", i, r, 2);
- if (IS_ERR(usb_dev_dr_client)) {
- ret = PTR_ERR(usb_dev_dr_client);
- goto err;
- }
- } else {
- ret = -EINVAL;
- goto err;
- }
-
- prop = of_get_property(np, "phy_type", NULL);
- usb_data.phy_mode = determine_usb_phy(prop);
-
- if (usb_dev_dr_host) {
- usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
- dev.coherent_dma_mask;
- if ((ret = platform_device_add_data(usb_dev_dr_host,
- &usb_data, sizeof(struct
- fsl_usb2_platform_data))))
- goto unreg_dr;
- }
- if (usb_dev_dr_client) {
- usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
- usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
- dev.coherent_dma_mask;
- if ((ret = platform_device_add_data(usb_dev_dr_client,
- &usb_data, sizeof(struct
- fsl_usb2_platform_data))))
- goto unreg_dr;
- }
- i++;
- }
- return 0;
-
-unreg_dr:
- if (usb_dev_dr_host)
- platform_device_unregister(usb_dev_dr_host);
- if (usb_dev_dr_client)
- platform_device_unregister(usb_dev_dr_client);
-unreg_mph:
- if (usb_dev_mph)
- platform_device_unregister(usb_dev_mph);
-err:
- return ret;
-}
-
-arch_initcall(fsl_usb_of_init);
-
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static __be32 __iomem *rstcr;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index fab765d..0fe5bc8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2
boolean "Freescale Highspeed USB DR Peripheral Controller"
depends on FSL_SOC || ARCH_MXC
select USB_GADGET_DUALSPEED
+ select USB_FSL_MPH_DR_OF
help
Some of Freescale PowerPC processors have a High Speed
Dual-Role(DR) USB controller, which supports device mode.
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2d926ce..f3a90b0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -112,10 +112,14 @@ config XPS_USB_HCD_XILINX
support both high speed and full speed devices, or high speed
devices only.
+config USB_FSL_MPH_DR_OF
+ tristate
+
config USB_EHCI_FSL
bool "Support for Freescale on-chip EHCI USB controller"
depends on USB_EHCI_HCD && FSL_SOC
select USB_EHCI_ROOT_HUB_TT
+ select USB_FSL_MPH_DR_OF
---help---
Variation of ARC USB block used in some Freescale chips.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b6315aa..aacbe82 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,4 +33,5 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
+obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
new file mode 100644
index 0000000..12db5d5
--- /dev/null
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -0,0 +1,219 @@
+/*
+ * Setup platform devices needed by the Freescale multi-port host
+ * and/or dual-role USB controller modules based on the description
+ * in flat device tree.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+
+struct fsl_usb2_dev_data {
+ char *dr_mode; /* controller mode */
+ char *drivers[3]; /* drivers to instantiate for this mode */
+ enum fsl_usb2_operating_modes op_mode; /* operating mode */
+};
+
+struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = {
+ {
+ .dr_mode = "host",
+ .drivers = { "fsl-ehci", NULL, NULL, },
+ .op_mode = FSL_USB2_DR_HOST,
+ },
+ {
+ .dr_mode = "otg",
+ .drivers = { "fsl-usb2-otg", "fsl-ehci", "fsl-usb2-udc", },
+ .op_mode = FSL_USB2_DR_OTG,
+ },
+ {
+ .dr_mode = "peripheral",
+ .drivers = { "fsl-usb2-udc", NULL, NULL, },
+ .op_mode = FSL_USB2_DR_DEVICE,
+ },
+};
+
+struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np)
+{
+ const unsigned char *prop;
+ int i;
+
+ prop = of_get_property(np, "dr_mode", NULL);
+ if (prop) {
+ for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) {
+ if (!strcmp(prop, dr_mode_data[i].dr_mode))
+ return &dr_mode_data[i];
+ }
+ }
+ pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n",
+ np->full_name);
+ return &dr_mode_data[0]; /* mode not specified, use host */
+}
+
+static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type)
+{
+ if (!phy_type)
+ return FSL_USB2_PHY_NONE;
+ if (!strcasecmp(phy_type, "ulpi"))
+ return FSL_USB2_PHY_ULPI;
+ if (!strcasecmp(phy_type, "utmi"))
+ return FSL_USB2_PHY_UTMI;
+ if (!strcasecmp(phy_type, "utmi_wide"))
+ return FSL_USB2_PHY_UTMI_WIDE;
+ if (!strcasecmp(phy_type, "serial"))
+ return FSL_USB2_PHY_SERIAL;
+
+ return FSL_USB2_PHY_NONE;
+}
+
+struct platform_device * __devinit fsl_usb2_device_register(
+ struct platform_device *ofdev,
+ struct fsl_usb2_platform_data *pdata,
+ const char *name, int id)
+{
+ struct platform_device *pdev;
+ const struct resource *res = ofdev->resource;
+ unsigned int num = ofdev->num_resources;
+ int retval;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ pdev->dev.parent = &ofdev->dev;
+
+ pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
+ pdev->dev.dma_mask = &pdev->archdata.dma_mask;
+ *pdev->dev.dma_mask = *ofdev->dev.dma_mask;
+
+ retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (retval)
+ goto error;
+
+ if (num) {
+ retval = platform_device_add_resources(pdev, res, num);
+ if (retval)
+ goto error;
+ }
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto error;
+
+ return pdev;
+
+error:
+ platform_device_put(pdev);
+ return ERR_PTR(retval);
+}
+
+static const struct of_device_id fsl_usb2_mph_dr_of_match[];
+
+static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
+{
+ struct device_node *np = ofdev->dev.of_node;
+ struct platform_device *usb_dev;
+ struct fsl_usb2_platform_data data, *pdata;
+ struct fsl_usb2_dev_data *dev_data;
+ const struct of_device_id *match;
+ const unsigned char *prop;
+ static unsigned int idx;
+ int i;
+
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ match = of_match_device(fsl_usb2_mph_dr_of_match, &ofdev->dev);
+ if (!match)
+ return -ENODEV;
+
+ pdata = &data;
+ if (match->data)
+ memcpy(pdata, match->data, sizeof(data));
+ else
+ memset(pdata, 0, sizeof(data));
+
+ dev_data = get_dr_mode_data(np);
+
+ if (of_device_is_compatible(np, "fsl-usb2-mph")) {
+ if (of_get_property(np, "port0", NULL))
+ pdata->port_enables |= FSL_USB2_PORT0_ENABLED;
+
+ if (of_get_property(np, "port1", NULL))
+ pdata->port_enables |= FSL_USB2_PORT1_ENABLED;
+
+ pdata->operating_mode = FSL_USB2_MPH_HOST;
+ } else {
+ /* setup mode selected in the device tree */
+ pdata->operating_mode = dev_data->op_mode;
+ }
+
+ prop = of_get_property(np, "phy_type", NULL);
+ pdata->phy_mode = determine_usb_phy(prop);
+
+ for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
+ if (!dev_data->drivers[i])
+ continue;
+ usb_dev = fsl_usb2_device_register(ofdev, pdata,
+ dev_data->drivers[i], idx);
+ if (IS_ERR(usb_dev)) {
+ dev_err(&ofdev->dev, "Can't register usb device\n");
+ return PTR_ERR(usb_dev);
+ }
+ }
+ idx++;
+ return 0;
+}
+
+static int __devexit __unregister_subdev(struct device *dev, void *d)
+{
+ platform_device_unregister(to_platform_device(dev));
+ return 0;
+}
+
+static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
+{
+ device_for_each_child(&ofdev->dev, NULL, __unregister_subdev);
+ return 0;
+}
+
+static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
+ { .compatible = "fsl-usb2-mph", },
+ { .compatible = "fsl-usb2-dr", },
+ {},
+};
+
+static struct platform_driver fsl_usb2_mph_dr_driver = {
+ .driver = {
+ .name = "fsl-usb2-mph-dr",
+ .owner = THIS_MODULE,
+ .of_match_table = fsl_usb2_mph_dr_of_match,
+ },
+ .probe = fsl_usb2_mph_dr_of_probe,
+ .remove = __devexit_p(fsl_usb2_mph_dr_of_remove),
+};
+
+static int __init fsl_usb2_mph_dr_init(void)
+{
+ return platform_driver_register(&fsl_usb2_mph_dr_driver);
+}
+module_init(fsl_usb2_mph_dr_init);
+
+static void __exit fsl_usb2_mph_dr_exit(void)
+{
+ platform_driver_unregister(&fsl_usb2_mph_dr_driver);
+}
+module_exit(fsl_usb2_mph_dr_exit);
+
+MODULE_DESCRIPTION("FSL MPH DR OF devices driver");
+MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
+MODULE_LICENSE("GPL");
--
1.7.0.4
^ permalink raw reply related
* [PATCH v3 0/2] Add USB Host support for MPC5121 SoC
From: Anatolij Gustschin @ 2010-09-28 18:55 UTC (permalink / raw)
To: linux-usb
Cc: David Brownell, Wolfgang Denk, Detlev Zundel, Greg Kroah-Hartman,
linuxppc-dev, Anatolij Gustschin
In-Reply-To: <1285666594-21150-1-git-send-email-agust@denx.de>
Version 3 of the patches to add MPC512x USB support in
mainline kernel. USB OTG support is not included in
this patch series, it will be submitted later.
There are only two patches now: patches 1/3 and 2/3 of
the previous version are merged into the first patch and
now bisectable. Additionally the 2nd patch of the previous
version is changed as requested by Grant. Please consider
for inclusion in 2.6.37.
Anatolij Gustschin (2):
USB: add platform glue driver for FSL USB DR controller
USB: add USB EHCI support for MPC5121 SoC
Documentation/powerpc/dts-bindings/fsl/usb.txt | 22 ++
arch/powerpc/sysdev/fsl_soc.c | 163 -------------
drivers/usb/Kconfig | 1 +
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/host/Kconfig | 10 +-
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ehci-fsl.c | 99 ++++++---
drivers/usb/host/ehci-fsl.h | 13 +-
drivers/usb/host/ehci-mem.c | 2 +-
drivers/usb/host/fsl-mph-dr-of.c | 308 ++++++++++++++++++++++++
include/linux/fsl_devices.h | 15 ++
11 files changed, 440 insertions(+), 195 deletions(-)
create mode 100644 drivers/usb/host/fsl-mph-dr-of.c
^ permalink raw reply
* Re: Parsing a bus fault message?
From: Scott Wood @ 2010-09-28 18:45 UTC (permalink / raw)
To: Ira W. Snyder; +Cc: david.hagood, linuxppc-dev
In-Reply-To: <20100928153153.GA22485@ovro.caltech.edu>
On Tue, 28 Sep 2010 08:31:54 -0700
"Ira W. Snyder" <iws@ovro.caltech.edu> wrote:
> On Tue, Sep 28, 2010 at 09:26:51AM -0500, david.hagood@gmail.com wrote:
> > Alternatively, can somebody see a hint in the message that I don't know
> > enough to pick out? At this point, my code is trying to memcpy() from the
> > PCIe bus (mapped via the outbound ATMU) to local memory, so the fault is
> > either a) the ATMU is not accessible b) the ATMU is accessible but not
> > mapped (which I would have thought the ioremap call I made would have
> > handled) or c) the chip is not able to bus master on the PCI bus.
Check the LAWs, the outbound ATMU, and the PCI device's BAR. Make sure
the address goes where you're expecting at each level.
> > Machine check in kernel mode.
> > Caused by (from SRR1=149030): Transfer error ack signal
>
> ^^^ this is the line that contains some critical info
>
> In the 86xx CPU manual, you should be able to find information about the
> SRR1 register. Decoding the hex SRR1=0x149030 may help.
>
> The kernel is telling you this is a TEA (transfer error acknowledge)
> error. I've only seen this when I get an unhandled timeout on the local
> bus. For example, a FPGA that has died in the middle of a request.
I've seen it when you access a physical address that has no device
backing it up.
> On the PCI bus, I haven't seen this error. The 83xx PCI controller is
> smart enough to return 0xffffffff when reading a non-existent device.
I believe that behavior is configurable.
-Scott
^ permalink raw reply
* Re: [PATCH 4/8] v2 Allow memory block to span multiple memory sections
From: Nathan Fontenot @ 2010-09-28 18:20 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <20100928124810.GI14068@sgi.com>
On 09/28/2010 07:48 AM, Robin Holt wrote:
>> +u32 __weak memory_block_size_bytes(void)
>> +{
>> + return MIN_MEMORY_BLOCK_SIZE;
>> +}
>> +
>> +static u32 get_memory_block_size(void)
>
> Can we make this an unsigned long? We are testing on a system whose
> smallest possible configuration is 4GB per socket with 512 sockets.
> We would like to be able to specify this as 2GB by default (results
> in the least lost memory) and suggest we add a command line option
> which overrides this value. We have many installations where 16GB may
> be optimal. Large configurations will certainly become more prevalent.
Works for me.
>
> ...
>> @@ -551,12 +608,16 @@
>> unsigned int i;
>> int ret;
>> int err;
>> + int block_sz;
>
> This one needs to match the return above. In our tests, we ended up
> with a negative sections_per_block which caused very unexpected results.
Oh, nice catch. I'll update both of these.
-Nathan
^ permalink raw reply
* Re: [PATCH 8/8] v2 Update memory hotplug documentation
From: Nathan Fontenot @ 2010-09-28 18:18 UTC (permalink / raw)
To: Avi Kivity
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <4CA1E36A.2000005@redhat.com>
On 09/28/2010 07:45 AM, Avi Kivity wrote:
> On 09/27/2010 09:28 PM, Nathan Fontenot wrote:
>>
>> For example, assume 1GiB section size. A device for a memory
>> starting at
>> 0x100000000 is /sys/device/system/memory/memory4
>> (0x100000000 / 1Gib = 4)
>> This device covers address range [0x100000000 ... 0x140000000)
>>
>> -Under each section, you can see 4 files.
>> +Under each section, you can see 5 files.
>
> Shouldn't this be, 4 or 5 files depending on kernel version?
>
Correct, I'll update this. Thanks.
-Nathan
^ permalink raw reply
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Nathan Fontenot @ 2010-09-28 18:17 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <20100928123848.GH14068@sgi.com>
On 09/28/2010 07:38 AM, Robin Holt wrote:
> I was tasked with looking at a slowdown in similar sized SGI machines
> booting x86_64. Jack Steiner had already looked into the memory_dev_init.
> I was looking at link_mem_sections().
>
> I made a dramatic improvement on a 16TB machine in that function by
> merely caching the most recent memory section and checking to see if
> the next memory section happens to be the subsequent in the linked list
> of kobjects.
>
> That simple cache reduced the time for link_mem_sections from 1 hour 27
> minutes down to 46 seconds.
Nice!
>
> I would like to propose we implement something along those lines also,
> but I am currently swamped. I can probably get you a patch tomorrow
> afternoon that applies at the end of this set.
Should this be done as a separate patch? This patch set concentrates on
updates to the memory code with the node updates only being done due to the
memory changes.
I think its a good idea to do the caching and have no problem adding on to
this patchset if no one else has any objections.
-Nathan
>
> Thanks,
> Robin
>
> On Mon, Sep 27, 2010 at 02:09:31PM -0500, Nathan Fontenot wrote:
>> This set of patches decouples the concept that a single memory
>> section corresponds to a single directory in
>> /sys/devices/system/memory/. On systems
>> with large amounts of memory (1+ TB) there are perfomance issues
>> related to creating the large number of sysfs directories. For
>> a powerpc machine with 1 TB of memory we are creating 63,000+
>> directories. This is resulting in boot times of around 45-50
>> minutes for systems with 1 TB of memory and 8 hours for systems
>> with 2 TB of memory. With this patch set applied I am now seeing
>> boot times of 5 minutes or less.
>>
>> The root of this issue is in sysfs directory creation. Every time
>> a directory is created a string compare is done against all sibling
>> directories to ensure we do not create duplicates. The list of
>> directory nodes in sysfs is kept as an unsorted list which results
>> in this being an exponentially longer operation as the number of
>> directories are created.
>>
>> The solution solved by this patch set is to allow a single
>> directory in sysfs to span multiple memory sections. This is
>> controlled by an optional architecturally defined function
>> memory_block_size_bytes(). The default definition of this
>> routine returns a memory block size equal to the memory section
>> size. This maintains the current layout of sysfs memory
>> directories as it appears to userspace to remain the same as it
>> is today.
>>
>> For architectures that define their own version of this routine,
>> as is done for powerpc in this patchset, the view in userspace
>> would change such that each memoryXXX directory would span
>> multiple memory sections. The number of sections spanned would
>> depend on the value reported by memory_block_size_bytes.
>>
>> In both cases a new file 'end_phys_index' is created in each
>> memoryXXX directory. This file will contain the physical id
>> of the last memory section covered by the sysfs directory. For
>> the default case, the value in 'end_phys_index' will be the same
>> as in the existing 'phys_index' file.
>>
>> This version of the patch set includes an update to to properly
>> report block_size_bytes, phys_index, and end_phys_index. Additionally,
>> the patch that adds the end_phys_index sysfs file is now patch 5/8
>> instead of being patch 2/8 as in the previous version of the patches.
>>
>> -Nathan Fontenot
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 2/8] v2 Add section count to memory_block struct
From: Nathan Fontenot @ 2010-09-28 18:14 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <20100928093132.GG14068@sgi.com>
On 09/28/2010 04:31 AM, Robin Holt wrote:
> In the next patch, you introduce a mutex for adding/removing memory blocks.
> Is there really a need for this to be atomic? If you reorder the patches
> so the mutex comes first, would the atomic be needed any longer?
>
I think you're right. Looking at the code with all patches applied I am only
updating the atomic when holding the mem_sysfs_mutex. I think the atomic
could safely be changed to a regular int.
-Nathan
> Robin
>
> On Mon, Sep 27, 2010 at 02:22:24PM -0500, Nathan Fontenot wrote:
>> Add a section count property to the memory_block struct to track the number
>> of memory sections that have been added/removed from a memory block. This
>> allows us to know when the last memory section of a memory block has been
>> removed so we can remove the memory block.
>>
>> Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
>>
>> ---
>> drivers/base/memory.c | 16 ++++++++++------
>> include/linux/memory.h | 3 +++
>> 2 files changed, 13 insertions(+), 6 deletions(-)
>>
>> Index: linux-next/drivers/base/memory.c
>> ===================================================================
>> --- linux-next.orig/drivers/base/memory.c 2010-09-27 09:17:20.000000000 -0500
>> +++ linux-next/drivers/base/memory.c 2010-09-27 09:31:35.000000000 -0500
>> @@ -478,6 +478,7 @@
>>
>> mem->phys_index = __section_nr(section);
>> mem->state = state;
>> + atomic_inc(&mem->section_count);
>> mutex_init(&mem->state_mutex);
>> start_pfn = section_nr_to_pfn(mem->phys_index);
>> mem->phys_device = arch_get_memory_phys_device(start_pfn);
>> @@ -505,12 +506,15 @@
>> struct memory_block *mem;
>>
>> mem = find_memory_block(section);
>> - unregister_mem_sect_under_nodes(mem);
>> - mem_remove_simple_file(mem, phys_index);
>> - mem_remove_simple_file(mem, state);
>> - mem_remove_simple_file(mem, phys_device);
>> - mem_remove_simple_file(mem, removable);
>> - unregister_memory(mem, section);
>> +
>> + if (atomic_dec_and_test(&mem->section_count)) {
>> + unregister_mem_sect_under_nodes(mem);
>> + mem_remove_simple_file(mem, phys_index);
>> + mem_remove_simple_file(mem, state);
>> + mem_remove_simple_file(mem, phys_device);
>> + mem_remove_simple_file(mem, removable);
>> + unregister_memory(mem, section);
>> + }
>>
>> return 0;
>> }
>> Index: linux-next/include/linux/memory.h
>> ===================================================================
>> --- linux-next.orig/include/linux/memory.h 2010-09-27 09:17:20.000000000 -0500
>> +++ linux-next/include/linux/memory.h 2010-09-27 09:22:56.000000000 -0500
>> @@ -19,10 +19,13 @@
>> #include <linux/node.h>
>> #include <linux/compiler.h>
>> #include <linux/mutex.h>
>> +#include <asm/atomic.h>
>>
>> struct memory_block {
>> unsigned long phys_index;
>> unsigned long state;
>> + atomic_t section_count;
>> +
>> /*
>> * This serializes all state change requests. It isn't
>> * held during creation because the control files are
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 4/8] v2 Allow memory block to span multiple memory sections
From: Nathan Fontenot @ 2010-09-28 18:06 UTC (permalink / raw)
To: Dave Hansen
Cc: linux-mm, Greg KH, linux-kernel, KAMEZAWA Hiroyuki, linuxppc-dev
In-Reply-To: <1285631707.19976.3385.camel@nimitz>
On 09/27/2010 06:55 PM, Dave Hansen wrote:
> On Mon, 2010-09-27 at 14:25 -0500, Nathan Fontenot wrote:
>> +static inline int base_memory_block_id(int section_nr)
>> +{
>> + return section_nr / sections_per_block;
>> +}
> ...
>> - mutex_lock(&mem_sysfs_mutex);
>> -
>> - mem->phys_index = __section_nr(section);
>> + scn_nr = __section_nr(section);
>> + mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block;
>
> I'm really regretting giving this variable such a horrid name. I suck.
>
> I think this is correct now:
>
> mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block;
> mem->phys_index = section_nr / sections_per_block * sections_per_block;
> mem->phys_index = section_nr
>
> Since it gets exported to userspace this way:
>
>> +static ssize_t show_mem_start_phys_index(struct sys_device *dev,
>> struct sysdev_attribute *attr, char *buf)
>> {
>> struct memory_block *mem =
>> container_of(dev, struct memory_block, sysdev);
>> - return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block);
>> + unsigned long phys_index;
>> +
>> + phys_index = mem->start_phys_index / sections_per_block;
>> + return sprintf(buf, "%08lx\n", phys_index);
>> +}
>
> The only other thing I'd say is that we need to put phys_index out of
> its misery and call it what it is now: a section number. I think it's
> OK to call them "start/end_section_nr", at least inside the kernel. I
> intentionally used "phys_index" terminology in sysfs so that we _could_
> eventually do this stuff and break the relationship between sections and
> the sysfs dirs, but I think keeping the terminology around inside the
> kernel is confusing now.
Yes, it took me a couple o looks to get the phys_index <-> section number
correlation. I think changing the kernel names to start/end_section_number
is a good idea.
-Nathan
>
> -- Dave
>
^ permalink raw reply
* Re: [PATCH 1/1 v2 ] Add kernel parameter to disable batched hcalls
From: Olof Johansson @ 2010-09-28 17:52 UTC (permalink / raw)
To: Will Schmidt; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <1285693371.2843.43.camel@lexx>
Nice. I've got minor nits below, and you might also want to run the patch
through checkpatch and fix up some of the whitespace warnings.
-Olof
On Tue, Sep 28, 2010 at 12:02:51PM -0500, Will Schmidt wrote:
>
> This introduces a pair of kernel parameters that can be used to disable
> the MULTITCE and BULK_REMOVE h-calls.
>
> By default, those hcalls are enabled, active, and good for throughput
> and performance. The ability to disable them will be useful for some of
> the PREEMPT_RT related investigation and work occurring on Power.
>
>
> Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
> cc: Olof Johansson <olof@lixom.net>
> cc: Anton Blanchard <anton@samba.org>
> cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>
> ---
>
> v2 - Per feedback from Olof, the code is reworked to utilize kernel
> parameter runtime checks, rather than CONFIG options.
> - Added relevant change to kernel-parameters.txt
>
>
>
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index e2c7487..5c40801 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -426,6 +426,10 @@ and is between 256 and 4096 characters. It is defined in the file
> bttv.pll= See Documentation/video4linux/bttv/Insmod-options
> bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
>
> + bulk_remove=off [PPC] This parameter disables the use of the pSeries
> + firmware feature for flushing multiple hpte entries
> + at a time.
> +
> BusLogic= [HW,SCSI]
> See drivers/scsi/BusLogic.c, comment before function
> BusLogic_ParseDriverOptions().
> @@ -1499,6 +1503,10 @@ and is between 256 and 4096 characters. It is defined in the file
> mtdparts= [MTD]
> See drivers/mtd/cmdlinepart.c.
>
> + multitce=off [PPC] This parameter disables the use of the pSeries
> + firmware feature for updating multiple TCE entries
> + at a time.
> +
> onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration
>
> Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
> diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
> index 902987d..e174a2f 100644
> --- a/arch/powerpc/platforms/pseries/iommu.c
> +++ b/arch/powerpc/platforms/pseries/iommu.c
> @@ -625,3 +625,19 @@ void iommu_init_early_pSeries(void)
> set_pci_dma_ops(&dma_iommu_ops);
> }
>
> +static int __init disable_multitce(char *str)
> +{
> + if (strcmp(str,"off")==0) {
> + if (firmware_has_feature(FW_FEATURE_LPAR)) {
> + if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
> + printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
> + ppc_md.tce_build = tce_build_pSeriesLP;
> + ppc_md.tce_free = tce_free_pSeriesLP;
> + powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
> + }
> + }
> + }
I personally prefer to keep cases like these in one if statement to save indentation:
if (strcmp(str, "off") == 0 &&
firmware_has_feature(FW_FEATURE_LPAR) &&
firmware_has_feature(FW_FEATURE_MULTITCE)) {
<...>
}
> + return 1;
> +}
> +
> +__setup("multitce=",disable_multitce);
> diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
> index 0707653..82d15e7 100644
> --- a/arch/powerpc/platforms/pseries/lpar.c
> +++ b/arch/powerpc/platforms/pseries/lpar.c
> @@ -599,6 +599,19 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
> spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
> }
>
> +static int __init disable_bulk_remove(char *str)
> +{
> + if (strcmp(str,"off")==0) {
> + if (firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
> + printk(KERN_INFO "Disabling BULK_REMOVE firmware feature");
> + powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE;
> + }
> + }
Same here.
> + return 1;
> +}
> +
> +__setup("bulk_remove=",disable_bulk_remove);
> +
> void __init hpte_init_lpar(void)
> {
> ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
>
^ permalink raw reply
* [PATCH 1/1 v2 ] Add kernel parameter to disable batched hcalls
From: Will Schmidt @ 2010-09-28 17:02 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev, Anton Blanchard
In-Reply-To: <20100926034903.GA5473@lixom.net>
This introduces a pair of kernel parameters that can be used to disable
the MULTITCE and BULK_REMOVE h-calls.
By default, those hcalls are enabled, active, and good for throughput
and performance. The ability to disable them will be useful for some of
the PREEMPT_RT related investigation and work occurring on Power.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
cc: Olof Johansson <olof@lixom.net>
cc: Anton Blanchard <anton@samba.org>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
v2 - Per feedback from Olof, the code is reworked to utilize kernel
parameter runtime checks, rather than CONFIG options.
- Added relevant change to kernel-parameters.txt
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e2c7487..5c40801 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -426,6 +426,10 @@ and is between 256 and 4096 characters. It is defined in the file
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
+ bulk_remove=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for flushing multiple hpte entries
+ at a time.
+
BusLogic= [HW,SCSI]
See drivers/scsi/BusLogic.c, comment before function
BusLogic_ParseDriverOptions().
@@ -1499,6 +1503,10 @@ and is between 256 and 4096 characters. It is defined in the file
mtdparts= [MTD]
See drivers/mtd/cmdlinepart.c.
+ multitce=off [PPC] This parameter disables the use of the pSeries
+ firmware feature for updating multiple TCE entries
+ at a time.
+
onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration
Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 902987d..e174a2f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -625,3 +625,19 @@ void iommu_init_early_pSeries(void)
set_pci_dma_ops(&dma_iommu_ops);
}
+static int __init disable_multitce(char *str)
+{
+ if (strcmp(str,"off")==0) {
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
+ if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
+ printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
+ ppc_md.tce_build = tce_build_pSeriesLP;
+ ppc_md.tce_free = tce_free_pSeriesLP;
+ powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
+ }
+ }
+ }
+ return 1;
+}
+
+__setup("multitce=",disable_multitce);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 0707653..82d15e7 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -599,6 +599,19 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
}
+static int __init disable_bulk_remove(char *str)
+{
+ if (strcmp(str,"off")==0) {
+ if (firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+ printk(KERN_INFO "Disabling BULK_REMOVE firmware feature");
+ powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE;
+ }
+ }
+ return 1;
+}
+
+__setup("bulk_remove=",disable_bulk_remove);
+
void __init hpte_init_lpar(void)
{
ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
^ permalink raw reply related
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Avi Kivity @ 2010-09-28 16:34 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <20100928151218.GJ14068@sgi.com>
On 09/28/2010 05:12 PM, Robin Holt wrote:
> > Why not update sysfs directory creation to be fast, for example by
> > using an rbtree instead of a linked list. This fixes an
> > implementation problem in the kernel instead of working around it
> > and creating a new ABI.
>
> Because the old ABI creates 129,000+ entries inside
> /sys/devices/system/memory with their associated links from
> /sys/devices/system/node/node*/ back to those directory entries.
>
> Thankfully things like rpm, hald, and other miscellaneous commands scan
> that information. On our 8 TB test machine, hald runs continuously
> following boot for nearly an hour mostly scanning useless information
> from /sys/
I see - so the problem wasn't just kernel internal; the ABI itself was
unsuitable. Too bad this wasn't considered at the time it was added.
(129k entries / 1 hour = 35 entries/sec; not very impressive)
--
error compiling committee.c: too many arguments to function
^ permalink raw reply
* Re: Parsing a bus fault message?
From: Ira W. Snyder @ 2010-09-28 15:31 UTC (permalink / raw)
To: david.hagood; +Cc: linuxppc-dev
In-Reply-To: <2bef2051c143a8d6e619519b222016f9.squirrel@localhost>
On Tue, Sep 28, 2010 at 09:26:51AM -0500, david.hagood@gmail.com wrote:
> I finally found my problems accessing the PPC OWBAR registers as an
> endpoint (copy/paste brown paper bag bug on my part), but I still get a
> bus fault trying to access the device.
>
> The problem is that I don't know if the fault is internal to the PPC (e.g.
> I don't have something in the chip set up) or if the fault is happening on
> the PCIe side of things.
>
> Are there any good how-tos on interpreting the kernel machine check error
> for the PPC, that might help me know where to look for the problem?
>
>
> Alternatively, can somebody see a hint in the message that I don't know
> enough to pick out? At this point, my code is trying to memcpy() from the
> PCIe bus (mapped via the outbound ATMU) to local memory, so the fault is
> either a) the ATMU is not accessible b) the ATMU is accessible but not
> mapped (which I would have thought the ioremap call I made would have
> handled) or c) the chip is not able to bus master on the PCI bus.
>
>
> Machine check in kernel mode.
> Caused by (from SRR1=149030): Transfer error ack signal
^^^ this is the line that contains some critical info
In the 86xx CPU manual, you should be able to find information about the
SRR1 register. Decoding the hex SRR1=0x149030 may help.
The kernel is telling you this is a TEA (transfer error acknowledge)
error. I've only seen this when I get an unhandled timeout on the local
bus. For example, a FPGA that has died in the middle of a request.
On the PCI bus, I haven't seen this error. The 83xx PCI controller is
smart enough to return 0xffffffff when reading a non-existent device.
I'm only familiar with 83xx, so I can't help too much on an 86xx board.
My best advice is: check your addresses. Make sure they're correct.
I assume that PCI on 86xx behaves similarly to 83xx. If you read from an
outbound window, your access gets translated into a PCI address and goes
onto the PCI bus. A good way of testing this is with the devmem utility
(part of busybox). It allows you to read/write any physical memory
location.
Using devmem will help you determine if the problem is in your code or
in your setup procedure.
I hope it helps,
Ira
> Oops: Machine check, sig: 7 [#1]
> SMP NR_CPUS=2 EP8641A
> Modules linked in: Endpoint_driver rionetlink
> NIP: c0014e80 LR: f102d434 CTR: 00000200
> REGS: ef05fdf0 TRAP: 0200 Not tainted (2.6.26.2-ep1.10)
> MSR: 00149030 <EE,ME,IR,DR> CR: 24004482 XER: 00000000
> TASK = ef05b310[76] 'cat' THREAD: ef05e000 CPU: 0
> GPR00: 00000000 ef05fea0 ef05b310 eed06000 f14dfffc 00001000 eed05ffc
> 80000000
> GPR08: 00000000 00000000 00001000 c0014e60 00001000 100a7264 0ffff100
> 00000001
> GPR16: ffffffff 004005b4 007fff00 c0290000 c02f0000 ef05ff20 bfba5978
> eed06000
> GPR24: eed14ce0 ef02c678 eed61910 00000000 00000000 efb8d4b0 fffffffb
> 00001000
> NIP [c0014e80] memcpy+0x20/0x9c
> LR [f102d434] Endpoint_atmu_read+0x4c/0x90 [Endpoint_driver]
> Call Trace:
> [ef05fea0] [ef05609c] 0xef05609c (unreliable)
> [ef05feb0] [c00cf2c0] read+0xd8/0x1c8
> [ef05fef0] [c007ff40] vfs_read+0xcc/0x16c
> [ef05ff10] [c008074c] sys_read+0x4c/0x90
> [ef05ff40] [c0011174] ret_from_syscall+0x0/0x38
> --- Exception: c01 at 0xff697f0
> LR = 0x10007008
> Instruction dump:
> 4200fff0 4e800020 7c032040 418100a0 54a7e8ff 38c3fffc 3884fffc 41820028
> 70c00003 7ce903a6 40820054 80e40004 <85040008> 90e60004 95060008 4200fff0
> ---[ end trace e0620da52f69882d ]---
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH 6/8] v2 Update node sysfs code
From: Dave Hansen @ 2010-09-28 15:21 UTC (permalink / raw)
To: Robin Holt
Cc: linuxppc-dev, Greg KH, linux-kernel, linux-mm, KAMEZAWA Hiroyuki
In-Reply-To: <20100928092919.GF14068@sgi.com>
On Tue, 2010-09-28 at 04:29 -0500, Robin Holt wrote:
> Also, I don't think I much care for the weirdness that occurs if a
> memory block spans two nodes. I have not thought through how possible
> (or likely) this is, but the code certainly permits it. If that were
> the case, how would we know which sections need to be taken offline,
> etc?
Since the architecture is the one doing the memory_block_size_bytes()
override, I'd expect that the per-arch code knows enough to ensure that
this doesn't happen. It's probably something to add to the
documentation or the patch descriptions. "How should an architecture
define this? When should it be overridden?"
It's just like the question of SECTION_SIZE. What if a section spans a
node? Well, they don't because the sections are a software concept and
we _define_ them to not be able to cross nodes. If they do, just make
them smaller.
-- Dave
^ permalink raw reply
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Dave Hansen @ 2010-09-28 15:17 UTC (permalink / raw)
To: Avi Kivity
Cc: linuxppc-dev, Greg KH, linux-kernel, linux-mm, KAMEZAWA Hiroyuki
In-Reply-To: <4CA1E338.6070201@redhat.com>
On Tue, 2010-09-28 at 14:44 +0200, Avi Kivity wrote:
> Why not update sysfs directory creation to be fast, for example by using
> an rbtree instead of a linked list. This fixes an implementation
> problem in the kernel instead of working around it and creating a new ABI.
>
> New ABIs mean old tools won't work, and new tools need to understand
> both ABIs.
Just to be clear _these_ patches do not change the existing ABI.
They do add a new ABI: the end_phys_index file. But, it is completely
redundant at the moment. It could be taken out of these patches.
That said, fixing the directory creation speed is probably a worthwhile
endeavor too.
-- Dave
^ permalink raw reply
* Re: [PATCH] powerpc: cell: Fix axion_msi irq shutdown
From: Arnd Bergmann @ 2010-09-28 15:13 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: linuxppc-dev
In-Reply-To: <alpine.LFD.2.00.1009281708350.2416@localhost6.localdomain6>
On Tuesday 28 September 2010, Thomas Gleixner wrote:
> Calling unmask_msi_irq on irq shutdown is at least suboptimal.
> Use mask_msi_irq instead.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections
From: Robin Holt @ 2010-09-28 15:12 UTC (permalink / raw)
To: Avi Kivity
Cc: linuxppc-dev, Greg KH, linux-kernel, Dave Hansen, linux-mm,
KAMEZAWA Hiroyuki
In-Reply-To: <4CA1E338.6070201@redhat.com>
On Tue, Sep 28, 2010 at 02:44:40PM +0200, Avi Kivity wrote:
> On 09/27/2010 09:09 PM, Nathan Fontenot wrote:
> >This set of patches decouples the concept that a single memory
> >section corresponds to a single directory in
> >/sys/devices/system/memory/. On systems
> >with large amounts of memory (1+ TB) there are perfomance issues
> >related to creating the large number of sysfs directories. For
> >a powerpc machine with 1 TB of memory we are creating 63,000+
> >directories. This is resulting in boot times of around 45-50
> >minutes for systems with 1 TB of memory and 8 hours for systems
> >with 2 TB of memory. With this patch set applied I am now seeing
> >boot times of 5 minutes or less.
> >
> >The root of this issue is in sysfs directory creation. Every time
> >a directory is created a string compare is done against all sibling
> >directories to ensure we do not create duplicates. The list of
> >directory nodes in sysfs is kept as an unsorted list which results
> >in this being an exponentially longer operation as the number of
> >directories are created.
> >
> >The solution solved by this patch set is to allow a single
> >directory in sysfs to span multiple memory sections. This is
> >controlled by an optional architecturally defined function
> >memory_block_size_bytes(). The default definition of this
> >routine returns a memory block size equal to the memory section
> >size. This maintains the current layout of sysfs memory
> >directories as it appears to userspace to remain the same as it
> >is today.
> >
>
> Why not update sysfs directory creation to be fast, for example by
> using an rbtree instead of a linked list. This fixes an
> implementation problem in the kernel instead of working around it
> and creating a new ABI.
Because the old ABI creates 129,000+ entries inside
/sys/devices/system/memory with their associated links from
/sys/devices/system/node/node*/ back to those directory entries.
Thankfully things like rpm, hald, and other miscellaneous commands scan
that information. On our 8 TB test machine, hald runs continuously
following boot for nearly an hour mostly scanning useless information
from /sys/
Robin
>
> New ABIs mean old tools won't work, and new tools need to understand
> both ABIs.
>
> --
> error compiling committee.c: too many arguments to function
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH] powerpc: cell: Fix axion_msi irq shutdown
From: Thomas Gleixner @ 2010-09-28 15:11 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
Calling unmask_msi_irq on irq shutdown is at least suboptimal.
Use mask_msi_irq instead.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/powerpc/platforms/cell/axon_msi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6/arch/powerpc/platforms/cell/axon_msi.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/axon_msi.c
+++ linux-2.6/arch/powerpc/platforms/cell/axon_msi.c
@@ -312,7 +312,7 @@ static void axon_msi_teardown_msi_irqs(s
static struct irq_chip msic_irq_chip = {
.mask = mask_msi_irq,
.unmask = unmask_msi_irq,
- .shutdown = unmask_msi_irq,
+ .shutdown = mask_msi_irq,
.name = "AXON-MSI",
};
^ 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