* MPC8272- Porting HDLC driver from 2.6.14 to 2.6.27- "no_irq_chip" error
From: Daniel Ng @ 2009-05-28 7:37 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org
Hi,
I'm attempting to port our Ethos HDLC driver from 2.6.14 to 2.6.27, on
a MPC8272-based platform.
So far, the kernel crashes when the driver tries to open (see below).
It seems that the interrupt handler fails to register, with the
following condition in setup_irq() in manage.c:
desc->chip == &no_irq_chip
I notice that the only place where desc->chip is assigned to anything
else besides &no_irq_chip is in __set_irq_handler() in
kernel/irq/chip.c
In that file, __set_irq_handler() assigns desc->chip to
&dummy_irq_chip, but this seems to be done for a special ARM-specific
case, according to the commenting:
/*
* Some ARM implementations install a handler for really dumb
* interrupt hardware without setting an irq_chip. This worked
* with the ARM no_irq_chip but the check in setup_irq would
* prevent us to setup the interrupt at all. Switch it to
* dummy_irq_chip for easy transition.
*/
Should I try to somehow call __set_irq_handler(), or should I be
looking elsewhere?
If I should be calling __set_irq_handler(), it seems the only relevant
function that calls this is cpm2_pic_host_map().
The only relevant functions which call cpm2_pic_host_map() are
irq_setup_virq() or irq_alloc_hosts() with the IRQ_HOST_MAP_LEGACY
parameter. IRQ_HOST_MAP_LEGACY seems to be irrelevant. Can someone
tell me what a virq is?
Cheers,
Daniel
Badness at c00224ec [verbose debug info unavailable]
NIP: c00224ec LR: c019b254 CTR: c01aa9f8
REGS: c1a49c70 TRAP: 0700 Not tainted (2.6.27.19-800-OS-03050107)
MSR: 00021032 <ME,IR,DR> CR: 22002022 XER: 00000000
TASK = c1bda400[306] 'pppd' THREAD: c1a48000
GPR00: 00000001 c1a49d20 c1bda400 00000000 c0318880 c19c4d80 c1b92211 00000000
GPR08: 00001032 c02cb240 00000000 00000000 22002022 fffffffe 01ff8000 00000000
GPR16: 10344020 00000000 00000002 10049ac0 c194f800 ffff8914 c18cd900 c18cd90c
GPR24: c1a49e48 00009032 c1a48000 c02b5fdc 00000002 c19c4d80 c1a48000 c1a48000
NIP [c00224ec] local_bh_enable+0x94/0xb4
LR [c019b254] dev_queue_xmit+0x108/0x580
Call Trace:
[c1a49d20] [c19c4d80] 0xc19c4d80 (unreliable)
[c1a49d30] [c019b254] dev_queue_xmit+0x108/0x580
[c1a49d50] [c016ac98] sppp_flush_xmit+0x20/0x44
[c1a49d60] [c016c0b4] sppp_open+0x80/0xac
[c1a49d80] [c016a104] ppp_open+0x70/0x98
--- Exception: bfd26bb0 at 0x8914
LR = 0xc1a49e90
[c1a49da0] [c01699e0] hdlc_open+0x3c/0x104 (unreliable)
[c1a49dc0] [c016cdd4] ethos_wan_genhdlc_open+0xb0/0xef8
[c1a49df0] [c019c490] dev_open+0xbc/0x120
[c1a49e00] [c019bbc8] dev_change_flags+0x8c/0x1d0
[c1a49e20] [c01e1678] devinet_ioctl+0x700/0x7ac
[c1a49e90] [c01e2538] inet_ioctl+0xcc/0xf8
[c1a49ea0] [c018b584] sock_ioctl+0x60/0x268
[c1a49ec0] [c0084ab0] vfs_ioctl+0x3c/0xc4
[c1a49ee0] [c0084bb8] do_vfs_ioctl+0x80/0x454
[c1a49f10] [c0084fcc] sys_ioctl+0x40/0x88
[c1a49f40] [c000f928] ret_from_syscall+0x0/0x38
--- Exception: c01 at 0x480af50c
LR = 0x480af5e4
Instruction dump:
41a20008 482044e1 80010014 83e1000c 38210010 7c0803a6 4e800020 3d20c02d
3929b240 800900dc 7c000034 5400d97e <0f000000> 2f800000 41beff90 38000001
hdlc2: Carrier detected
setup_irq()- desc->chip == &no_irq_chip
request_irq()- setup_irq() FAILED
ethos_wan_genhdlc_open(): request_irq() FAILED! ethos_wan->io_addr: 0xc5080000
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Benjamin Herrenschmidt @ 2009-05-28 6:11 UTC (permalink / raw)
To: Kumar Gala; +Cc: FUJITA Tomonori, linuxppc-dev list
In-Reply-To: <2CCC4C06-15EC-438B-8BEA-A31690B4FB2C@kernel.crashing.org>
On Wed, 2009-05-27 at 23:42 -0500, Kumar Gala wrote:
> Ben,
>
> Any comments on this.. need a decision so we can have patches ready
> for .31.
> > Clamping the DMA mask is even worse than the additional indirection
> > for us. We have valid scenarios in which we'd have 512M of outbound
> > PCI address space and 4G of mem and thus 3.5G of inbound PCI address
> > space. With the DMA mask we'd be limited to 2G and bouncing from
> > 2..3.5G when we don't need to.
Ok and agreed.
> > I think our options are to change archdata as follows:
> >
> > Option 1 - just add a new data member to dev_archdata
> >
> > struct dev_archdata {
> > /* Optional pointer to an OF device node */
> > struct device_node *of_node;
> >
> > /* DMA operations on that device */
> > struct dma_mapping_ops *dma_ops;
> > void *dma_data;
> > dma_addr_t direct_dma_addr;
> > };
That sounds like the "simple" option, might want for now to make
it conditional on SWIOTLB but the bloat is reasonably small I would
expect.
> > Option 2 - introduce a proper container for how we use dma_data.
> > This may just be moving the indirection from an indirection function
> > call to an indirection data reference:
Right, it somewhat defeats the purpose though an indirect data reference
tends to hit the pipeline less hard than an indirect function call...
> > Option 3 - use dma_data to keep the addr at which we need to bounce
> > vs not for SWIOTLB - this has potential issues w/conflicting with
> > dma_data being used as the dma_offset. (need to think on that a bit
> > more). Additionally this has the benefit in that we need dma_data
> > to be a 64-bit quantity on ppc32 w/>32-bit phys addr.
Well, that means that swiotlb can not be used with a !0 offset. That
-might- be an issue if the PCI is setup "backward", ie with 0..N being
the outbound MMIO and N..4G the DMA region, remapped to 0. There are
reasons to do it this way, it's not invalid, for example it allow easy
access to ISA/VGA holes.
At this stage I have no firm opinion. I'm thinking that either we try
to limit the overhead and option 1 is probably the simplest, at the
expense of a little bit of memory, or we think the overhead is going
to be minimum and we may as well stick to 2 functions since that's
going to be more flexible.
Cheers,
Ben.
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Grant Likely @ 2009-05-28 5:09 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev list
In-Reply-To: <20090528010000.31423083@lappy.seanm.ca>
On Wed, May 27, 2009 at 11:00 PM, Sean MacLennan
<smaclennan@pikatech.com> wrote:
> On Wed, 27 May 2009 21:42:18 -0600
> Grant Likely <grant.likely@secretlab.ca> wrote:
>
>> Make your driver use a platform device or an of_platform device. =A0It's
>> not at all hard.
>
> Here is my first shot.... any other fields that I need to fill in so I
> don't have any gotchas?
>
> /* This must exist */
> static void warp_device_release(struct device *dev) {}
It will be easier if you do it as an of_device. Then you just need to
add a node to the device tree and it will get registered correctly
without any platform specific registration code. That gives your
driver something to bind against.
However, if you do want to do it this way...
> static struct platform_device warp_device =3D {
> =A0 =A0 =A0 =A0.name =3D "warp-device",
> =A0 =A0 =A0 =A0.id =3D 0,
> =A0 =A0 =A0 =A0.num_resources =3D 0,
> =A0 =A0 =A0 =A0.dev =3D {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.coherent_dma_mask =3D ~0ULL,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.release =3D warp_device_release,
> =A0 =A0 =A0 =A0},
> };
No need for all this. use platform_device_register_simple() instead.
Again, that gives your driver something to bind again, this time on
the platform bus (instead of of_platform bus).
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Sean MacLennan @ 2009-05-28 5:00 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev list
In-Reply-To: <fa686aa40905272042yd7b4698gbd1133b4c61c9b87@mail.gmail.com>
On Wed, 27 May 2009 21:42:18 -0600
Grant Likely <grant.likely@secretlab.ca> wrote:
> Make your driver use a platform device or an of_platform device. It's
> not at all hard.
Here is my first shot.... any other fields that I need to fill in so I
don't have any gotchas?
/* This must exist */
static void warp_device_release(struct device *dev) {}
static struct platform_device warp_device = {
.name = "warp-device",
.id = 0,
.num_resources = 0,
.dev = {
.coherent_dma_mask = ~0ULL,
.release = warp_device_release,
},
};
platform_device_register(&warp_device);
Cheers,
Sean
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Kumar Gala @ 2009-05-28 4:42 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: FUJITA Tomonori, linuxppc-dev list
In-Reply-To: <13F18475-1D3E-4D9E-B10C-8BE48FBA9DF5@kernel.crashing.org>
Ben,
Any comments on this.. need a decision so we can have patches ready
for .31.
- k
On May 19, 2009, at 8:04 AM, Kumar Gala wrote:
>
> On May 18, 2009, at 4:49 PM, Benjamin Herrenschmidt wrote:
>
>> On Mon, 2009-05-18 at 08:25 -0500, Kumar Gala wrote:
>>>
>>> Part of this is how the generic swiotlb code works and part of it
>>> was
>>> our desire not to bloat dev archdata by adding such info that as you
>>> say is either bus specific or conveyed in the dma addr mask.
>>
>> Right but perf sucks :-)
>>
>> Maybe an option is to clamp the DMA mask when it's set by the
>> driver to
>> limit it to the available inbound window ?
>
> Clamping the DMA mask is even worse than the additional indirection
> for us. We have valid scenarios in which we'd have 512M of outbound
> PCI address space and 4G of mem and thus 3.5G of inbound PCI address
> space. With the DMA mask we'd be limited to 2G and bouncing from
> 2..3.5G when we don't need to.
>
> I think our options are to change archdata as follows:
>
> Option 1 - just add a new data member to dev_archdata
>
> struct dev_archdata {
> /* Optional pointer to an OF device node */
> struct device_node *of_node;
>
> /* DMA operations on that device */
> struct dma_mapping_ops *dma_ops;
> void *dma_data;
> dma_addr_t direct_dma_addr;
> };
>
> Option 2 - introduce a proper container for how we use dma_data.
> This may just be moving the indirection from an indirection function
> call to an indirection data reference:
>
> struct dma_data {
> dma_addr_t offset;
> dma_addr_t direct_dma_addr;
> struct iommu_table *iommu_table;
> };
>
> struct dev_archdata {
> /* Optional pointer to an OF device node */
> struct device_node *of_node;
>
> /* DMA operations on that device */
> struct dma_mapping_ops *dma_ops;
> struct dma_data *dma_data;
> };
>
> Option 3 - use dma_data to keep the addr at which we need to bounce
> vs not for SWIOTLB - this has potential issues w/conflicting with
> dma_data being used as the dma_offset. (need to think on that a bit
> more). Additionally this has the benefit in that we need dma_data
> to be a 64-bit quantity on ppc32 w/>32-bit phys addr.
>
> struct dev_archdata {
> /* Optional pointer to an OF device node */
> struct device_node *of_node;
>
> /* DMA operations on that device */
> struct dma_mapping_ops *dma_ops;
> dma_addr_t dma_data;
> };
>
> others??
>
> - k
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Benjamin Herrenschmidt @ 2009-05-28 4:19 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev list
In-Reply-To: <20090528001152.6c00b238@lappy.seanm.ca>
On Thu, 2009-05-28 at 00:11 -0400, Sean MacLennan wrote:
> On Thu, 28 May 2009 13:52:29 +1000
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> > Can't you set ISA_DMA_THRESHOLD = ~0L from your warp.c platform file ?
>
> I actually set it in the driver proper since it is faster to test, but
> it works. I am just wondering how kosher that is.
Set it in warp.c and send me a patch for 2.6.30, we can have a proper
device bound to it for .31.
> The advantage of the platform_device is I can go back to using the top
> level function. And I suspect down the road the __dma* functions may
> require a real device.
>
> However, the ISA_DMA_THRESHOLD = ~0L is a less intrusive patch.
Yes until you have a proper device probed of the device-tree.
Cheers,
Ben.
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Sean MacLennan @ 2009-05-28 4:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1243482749.3171.80.camel@pasglop>
On Thu, 28 May 2009 13:52:29 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> Can't you set ISA_DMA_THRESHOLD = ~0L from your warp.c platform file ?
I actually set it in the driver proper since it is faster to test, but
it works. I am just wondering how kosher that is.
The advantage of the platform_device is I can go back to using the top
level function. And I suspect down the road the __dma* functions may
require a real device.
However, the ISA_DMA_THRESHOLD = ~0L is a less intrusive patch.
Cheers,
Sean
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Benjamin Herrenschmidt @ 2009-05-28 3:52 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev list
In-Reply-To: <20090527233451.2d02343d@lappy.seanm.ca>
On Wed, 2009-05-27 at 23:34 -0400, Sean MacLennan wrote:
> On Mon, 25 May 2009 14:33:43 +1000
../..
You can just make it a platform device I suppose. In the meantime...
> Maybe set ISA_DMA_THRESHOLD somewhere? Some platforms seem to set it:
>
> ./platforms/52xx/efika.c: ISA_DMA_THRESHOLD = ~0L;
> ./platforms/amigaone/setup.c: ISA_DMA_THRESHOLD = 0x00ffffff;
> ./platforms/chrp/setup.c: ISA_DMA_THRESHOLD = ~0L;
> ./platforms/powermac/setup.c: ISA_DMA_THRESHOLD = ~0L;
>
> So if anybody knows another way around this? The driver is basically
> allocating a scatter gather list that is passed to a DMA engine in the
> FPGA.
>
> This isn't a showstopper.... we are not planning to move to 2.6.30 in
> the near future.
Can't you set ISA_DMA_THRESHOLD = ~0L from your warp.c platform file ?
Cheers,
Ben.
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Grant Likely @ 2009-05-28 3:42 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev list
In-Reply-To: <20090527233451.2d02343d@lappy.seanm.ca>
On Wed, May 27, 2009 at 9:34 PM, Sean MacLennan <smaclennan@pikatech.com> w=
rote:
> On Mon, 25 May 2009 14:33:43 +1000
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
>> This is going to .30 if nobody hollers. I've done some testing here
>> and it seems to be fine, but more eyes at this stage are much welcome.
>
> Sigh, I didn't get a chance to look at this until tonight. I use
> __dma_alloc_coherent in one of the warp drivers because I don't have a
> device to pass to dma_alloc_coherent. I was hoping to put it off until
> the summer.
>
> I assume I am scuppered without a device:
>
> [ =A0260.101751] coherent allocation too big (requested 0x5000 mask 0x0)
> [ =A0260.108054] pikadma: Unable to allocate SGL
>
> This is with a NULL passed as the device. And it looks
> like if the device is null, it just defaults to ISA_DMA_THRESHOLD,
> which is 0 as shown above.
>
> Is there a global platform device or something similar that I can
> piggyback off of? There is no bus associated with this driver, so no
> device.
Make your driver use a platform device or an of_platform device. It's
not at all hard.
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: powerpc: DMA coherent allocations broken for CONFIG_NOT_COHERENT_CACHE
From: Sean MacLennan @ 2009-05-28 3:34 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1243226023.24376.23.camel@pasglop>
On Mon, 25 May 2009 14:33:43 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> This is going to .30 if nobody hollers. I've done some testing here
> and it seems to be fine, but more eyes at this stage are much welcome.
Sigh, I didn't get a chance to look at this until tonight. I use
__dma_alloc_coherent in one of the warp drivers because I don't have a
device to pass to dma_alloc_coherent. I was hoping to put it off until
the summer.
I assume I am scuppered without a device:
[ 260.101751] coherent allocation too big (requested 0x5000 mask 0x0)
[ 260.108054] pikadma: Unable to allocate SGL
This is with a NULL passed as the device. And it looks
like if the device is null, it just defaults to ISA_DMA_THRESHOLD,
which is 0 as shown above.
Is there a global platform device or something similar that I can
piggyback off of? There is no bus associated with this driver, so no
device.
Maybe set ISA_DMA_THRESHOLD somewhere? Some platforms seem to set it:
./platforms/52xx/efika.c: ISA_DMA_THRESHOLD = ~0L;
./platforms/amigaone/setup.c: ISA_DMA_THRESHOLD = 0x00ffffff;
./platforms/chrp/setup.c: ISA_DMA_THRESHOLD = ~0L;
./platforms/powermac/setup.c: ISA_DMA_THRESHOLD = ~0L;
So if anybody knows another way around this? The driver is basically
allocating a scatter gather list that is passed to a DMA engine in the
FPGA.
This isn't a showstopper.... we are not planning to move to 2.6.30 in
the near future.
Cheers,
Sean
^ permalink raw reply
* Re: [Solved/Patch Question] Weird 5200/mtd-ram problem
From: Jon Smirl @ 2009-05-28 3:10 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: linuxppc-dev
In-Reply-To: <1243454097.3489.0@antares>
On Wed, May 27, 2009 at 3:54 PM, Albrecht Dre=DF <albrecht.dress@arcor.de> =
wrote:
> Hi all:
>
> Am 25.05.09 23:47 schrieb(en) Wolfram Sang:
>>>
>>> A word or long copy of 0x0055aaff with U-Boot works fine, but a byte co=
py
>>> filled the whole ram with 0x0000aaaa. =A0The reason is apparently that =
the
>>> chip is attached to the local bus in 16-bit mode, which is incompatible=
with
>>> byte accesses. =A0However, the Local Bus doesn't provide "low byte" or =
"high
>>> byte" indicators in non-muxed mode. =A0How is this supposed to work the=
n?
>>
>> Hmm, as I feared... we were bitten by this, too:
>>
>> http://thread.gmane.org/gmane.linux.drivers.mtd/21521
>>
>> There is no generic solution yet :(
>
> At least for my case, I could completely (afaict) solve the problem, i.e.=
I
> can now access the 16-bit nv ram as mtd char and block device, the latter
> with jffs2. =A0I would like to submit a patch, but I actually don't know
> exactly how...
>
> The solution itself is quite simple: add a new method which works like
> memcpy_toio, but respects the fact that no single bytes may be written
> (reading through memcpy_fromio works painlessly). =A0I think this functio=
n
> should go into arch/powerpc/kernel/io.c, depending upon CONFIG_PPC_MPC52x=
x,
> and the prototype into arch/powerpc/include/asm/io.h, right?
>
> The harder part is to actually call this function properly. =A0I now call=
it
> in include/linux/mtd/map.h, function inline_map_copy_to(), if
> CONFIG_PPC_MPC52xx is defined and if map->bankwidth is 2. =A0However, is =
it
> acceptable to have a processor-type dependency in a top-level include fil=
e?
> =A0Or what would be the proper way to implement it?
This is an old jffs2 patch that was addressing this same problem.
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 272872d..c982adc 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -16,6 +16,7 @@
#include <linux/pagemap.h>
#include <linux/crc32.h>
#include <linux/compiler.h>
+#include <asm/io.h>
#include "nodelist.h"
#include "summary.h"
#include "debug.h"
@@ -505,7 +506,7 @@ static int jffs2_scan_eraseblock (struct
jffs2_sb_info *c, struct jffs2_eraseblo
sumptr =3D kmalloc(sumlen, GFP_KERNEL);
if (!sumptr)
return -ENOMEM;
- memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len);
+ memcpy_fromio(sumptr + sumlen - buf_len, buf + buf_size -
buf_len, buf_len);
}
if (buf_len < sumlen) {
/* Need to read more so that the entire summary node is present */
@@ -1035,7 +1036,7 @@ static int jffs2_scan_dirent_node(struct
jffs2_sb_info *c, struct jffs2_eraseblo
if (!fd) {
return -ENOMEM;
}
- memcpy(&fd->name, rd->name, checkedlen);
+ memcpy_fromio(&fd->name, rd->name, checkedlen);
fd->name[checkedlen] =3D 0;
crc =3D crc32(0, fd->name, rd->nsize);
>
> Thanks, Albrecht.
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
--=20
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply related
* Re: [PATCH] v2: Display processor virtualization resource allocations in lparcfg
From: Michael Ellerman @ 2009-05-28 0:31 UTC (permalink / raw)
To: Nathan Fontenot; +Cc: linuxppc-dev
In-Reply-To: <4A1D5111.10505@austin.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1036 bytes --]
On Wed, 2009-05-27 at 09:41 -0500, Nathan Fontenot wrote:
> This patch updates the output from /proc/ppc64/lparcfg to display the
> processor virtualization resource allocations for a shared processor
> partition.
>
> This information is already gathered via the h_get_ppp call, we just
> have to make sure that the ibm,partition-performance-parameters-level
> property is >= 1 to ensure that the information is valid.
> @@ -267,6 +281,28 @@
> seq_printf(m, "capped=%d\n", ppp_data.capped);
> seq_printf(m, "unallocated_capacity=%lld\n",
> ppp_data.unallocated_entitlement);
> +
> + /* The last bits of information returned from h_get_ppp are only
> + * valid if the ibm,partition-performance-parameters-level
> + * property is >= 1.
> + */
> + root = of_find_node_by_path("/");
> + if (root) {
> + perf_level = of_get_property(root,
> + "ibm,partition-performance-parameters-level",
> + NULL);
> + if (perf_level && (*perf_level >= 1)) {
Yep that looks better, thanks.
cheers
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Becky Bruce @ 2009-05-27 22:11 UTC (permalink / raw)
To: Ian Campbell
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org, Jeremy Fitzhardinge,
linux-kernel@vger.kernel.org
In-Reply-To: <1243456159.4399.42.camel@localhost.localdomain>
On May 27, 2009, at 3:29 PM, Ian Campbell wrote:
> On Wed, 2009-05-27 at 15:05 -0400, Becky Bruce wrote:
>> On May 22, 2009, at 6:11 AM, Ian Campbell wrote:
>>>
>>>
>>> BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that
>>> it
>>> is implemented in terms of swiotlb_bus_to_phys sufficient?
>>
>> The default one in swiotlb calls phys_to_virt on the result of
>> swiotlb_bus_to_phys, which only works on lowmem.
>
> Perhaps we can simply enhance the default one to handle highmem
> instead
> of making it arch specific?
That's fine by me - as long as what I've got will work for you guys
I'm happy to stick it in the standard one (inside a nice pretty #ifdef
CONFIG_HIGHMEM, of course).
Cheers,
B
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Ian Campbell @ 2009-05-27 20:29 UTC (permalink / raw)
To: Becky Bruce
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org, Jeremy Fitzhardinge,
linux-kernel@vger.kernel.org
In-Reply-To: <0628DF07-E085-4CC8-ADFC-1B0798343159@kernel.crashing.org>
On Wed, 2009-05-27 at 15:05 -0400, Becky Bruce wrote:
> On May 22, 2009, at 6:11 AM, Ian Campbell wrote:
> >
> >
> > BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that
> > it
> > is implemented in terms of swiotlb_bus_to_phys sufficient?
>
> The default one in swiotlb calls phys_to_virt on the result of
> swiotlb_bus_to_phys, which only works on lowmem.
Perhaps we can simply enhance the default one to handle highmem instead
of making it arch specific?
Ian.
^ permalink raw reply
* [PATCH] powerpc: tiny memcpy_(to|from)io optimisation
From: Albrecht Dreß @ 2009-05-27 20:00 UTC (permalink / raw)
To: Linux PPC Development
[-- Attachment #1: Type: text/plain, Size: 1012 bytes --]
This trivial patch changes memcpy_(to|from)io as to transfer as many
32-bit words as possible in 32-bit accesses (in the current solution,
the last 32-bit word was transferred as 4 byte accesses).
Signed-off-by: Albrecht Dreß <albrecht.dress@arcor.de>
---
diff -urpN -X linux-2.6.29.1.orig/Documentation/dontdiff
linux-2.6.29.1.orig/arch/powerpc/kernel/io.c
linux-2.6.29.1/arch/powerpc/kernel/io.c
--- linux-2.6.29.1.orig/arch/powerpc/kernel/io.c 2009-04-02
22:55:27.000000000 +0200
+++ linux-2.6.29.1/arch/powerpc/kernel/io.c 2009-05-27
11:36:09.000000000 +0200
@@ -161,7 +161,7 @@ void _memcpy_fromio(void *dest, const vo
dest++;
n--;
}
- while(n > 4) {
+ while(n >= 4) {
*((u32 *)dest) = *((volatile u32 *)vsrc);
eieio();
vsrc += 4;
@@ -190,7 +190,7 @@ void _memcpy_toio(volatile void __iomem
vdest++;
n--;
}
- while(n > 4) {
+ while(n >= 4) {
*((volatile u32 *)vdest) = *((volatile u32 *)src);
src += 4;
vdest += 4;
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [Solved/Patch Question] Weird 5200/mtd-ram problem
From: Albrecht Dreß @ 2009-05-27 19:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20090525214718.GA8152@pengutronix.de>
[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]
Hi all:
Am 25.05.09 23:47 schrieb(en) Wolfram Sang:
>> A word or long copy of 0x0055aaff with U-Boot works fine, but a byte
>> copy filled the whole ram with 0x0000aaaa. The reason is apparently
>> that the chip is attached to the local bus in 16-bit mode, which is
>> incompatible with byte accesses. However, the Local Bus doesn't
>> provide "low byte" or "high byte" indicators in non-muxed mode. How
>> is this supposed to work then?
>
> Hmm, as I feared... we were bitten by this, too:
>
> http://thread.gmane.org/gmane.linux.drivers.mtd/21521
>
> There is no generic solution yet :(
At least for my case, I could completely (afaict) solve the problem,
i.e. I can now access the 16-bit nv ram as mtd char and block device,
the latter with jffs2. I would like to submit a patch, but I actually
don't know exactly how...
The solution itself is quite simple: add a new method which works like
memcpy_toio, but respects the fact that no single bytes may be written
(reading through memcpy_fromio works painlessly). I think this
function should go into arch/powerpc/kernel/io.c, depending upon
CONFIG_PPC_MPC52xx, and the prototype into
arch/powerpc/include/asm/io.h, right?
The harder part is to actually call this function properly. I now call
it in include/linux/mtd/map.h, function inline_map_copy_to(), if
CONFIG_PPC_MPC52xx is defined and if map->bankwidth is 2. However, is
it acceptable to have a processor-type dependency in a top-level
include file? Or what would be the proper way to implement it?
Thanks, Albrecht.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Becky Bruce @ 2009-05-27 19:11 UTC (permalink / raw)
To: Ian Campbell
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org, Jeremy Fitzhardinge,
linux-kernel@vger.kernel.org
In-Reply-To: <1243342307.9295.86.camel@zakaz.uk.xensource.com>
On May 26, 2009, at 7:51 AM, Ian Campbell wrote:
> On Fri, 2009-05-22 at 19:55 -0400, Jeremy Fitzhardinge wrote:
>> Ian Campbell wrote:
>>> On Thu, 2009-05-21 at 14:27 -0400, Becky Bruce wrote:
>>>
>>>> I can work with that, but it's going to be a bit inefficient, as I
>>>> actually need the dma_addr_t, not the phys_addr_t, so I'll have to
>>>> convert. In every case, this is a conversion I've already done and
>>>> that I need in the calling code as well.
>>>>
>>>
>>> Does
>>>
>>> dma_addr_t dma_map_range(struct device *hwdev, phys_addr_t addr,
>>> size_t size);
>>>
>>> work for you?
>>>
>>> If the range does not need mapping then it returns the dma
>>> address, if
>>> you needed to calculate the dma address anyway to figure out if
>>> mapping
>>> is required then this is fine. If the range does need mapping then
>>> it
>>> returns NULL.
>>>
>>
>> My only concern is whether dma_addr_t == 0 is actually equivalent to
>> NULL. That is, can we be sure that address 0 will never be used?
>
> It seems not, ~0UL might have been an option, but...
>
>> Taking dma_alloc_coherent as a model, we could have something like:
>>
>> int dma_map_range(struct device *hwdev, phys_addr_t addr, size_t
>> size, dma_addr_t *dma_addrp);
>>
>>
>> where *dma_addrp is set if the function returns success (bool return
>> type might be clearer).
>
> ... this sounds like a good idea to me.
I agree. This will work for me as well.
-becky
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Becky Bruce @ 2009-05-27 19:05 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, jeremy, linux-kernel, Ian.Campbell
In-Reply-To: <20090522194930E.fujita.tomonori@lab.ntt.co.jp>
On May 22, 2009, at 5:51 AM, FUJITA Tomonori wrote:
> On Thu, 21 May 2009 13:18:54 -0700
> Jeremy Fitzhardinge <jeremy@goop.org> wrote:
>
>> Becky Bruce wrote:
>>> I can work with that, but it's going to be a bit inefficient, as I
>>> actually need the dma_addr_t, not the phys_addr_t, so I'll have to
>>> convert. In every case, this is a conversion I've already done and
>>> that I need in the calling code as well. Can we pass in both the
>>> phys_addr_t and the dma_addr_t?
>>
>> The Xen implementation would needs to do the phys to bus conversion
>> page
>> by page anyway, so it wouldn't help much. But it also wouldn't hurt.
>>
>> How expensive is the phys-to-bus conversion on power? Is it worth
>> making the interface more complex for? Would passing phys+bus mean
>> that
>> we wouldn't also need to pass dev?
>
> I don't think so. POWERPC needs it.
Hrm, it looks like my response to this got dropped. Fujita is correct
- we still need the dev on powerpc because we use it to get device-
specific information that is used to determining when we need to
actually bounce.
Cheers,
B
^ permalink raw reply
* Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
From: Becky Bruce @ 2009-05-27 19:05 UTC (permalink / raw)
To: Ian Campbell
Cc: FUJITA Tomonori, linuxppc-dev@ozlabs.org, Jeremy Fitzhardinge,
linux-kernel@vger.kernel.org
In-Reply-To: <1242990702.22654.253.camel@zakaz.uk.xensource.com>
On May 22, 2009, at 6:11 AM, Ian Campbell wrote:
>
>
> BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that
> it
> is implemented in terms of swiotlb_bus_to_phys sufficient?
The default one in swiotlb calls phys_to_virt on the result of
swiotlb_bus_to_phys, which only works on lowmem.
>
>
> I have an appointment all afternoon and it's a bank holiday on Monday
> but here is my WIP patch as an example of what I'm thinking. Obviously
> some cleanups are still very much required:
> * The Xen specific stuff in arch/x86/include/asm/dma-mapping.h
> clearly needs to be properly abstracted away (I just stuck it
> there for testing).
> * swiotlb_phys_to_bus and swiotlb_bus_to_phys need to move to
> arch/*/include/asm/dma-mapping.h instead of being __weak
> * Maybe swiotlb_bus_to_virt can become static again.
> * Need to finish auditing the handful of non-swiotlb users of
> is_buffer_dma_capable.
> * It might be possible to implement swiolb_dma_mapping_error
> and/or swiotlb_dma_supported in terms of dma_map_range.
> * Minor detail: it doesn't actually work at the moment ;-)
Minor detail :)
I'm in the same boat- been offline most of the week and will continue
to be offline (I'm sneaking in an hour here to read emails!!!!) until
sometime next week. I'm in the middle of a big lab construction and
move project. I'll take a look as soon as I can - thanks!
-Becky
>
>
> Ian.
>
> diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/
> asm/dma-mapping.h
> index 36c0009..026667f 100644
> --- a/arch/ia64/include/asm/dma-mapping.h
> +++ b/arch/ia64/include/asm/dma-mapping.h
> @@ -174,4 +174,12 @@ dma_cache_sync (struct device *dev, void
> *vaddr, size_t size,
>
> #define dma_is_consistent(d, h) (1) /* all we do is coherent
> memory... */
>
> +static inline dma_addr_t dma_map_range(struct device *dev, u64 mask,
> + phys_addr_t addr, size_t size)
> +{
> + if (addr + size <= mask)
> + return addr;
> + return 0;
> +}
> +
> #endif /* _ASM_IA64_DMA_MAPPING_H */
> diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/
> asm/dma-mapping.h
> index 916cbb6..b2813ab 100644
> --- a/arch/x86/include/asm/dma-mapping.h
> +++ b/arch/x86/include/asm/dma-mapping.h
> @@ -309,4 +309,20 @@ static inline void dma_free_coherent(struct
> device *dev, size_t size,
> ops->free_coherent(dev, size, vaddr, bus);
> }
>
> +static inline dma_addr_t dma_map_range(struct device *dev, u64 mask,
> + phys_addr_t addr, size_t size)
> +{
> + dma_addr_t dma_addr;
> +#ifdef CONFIG_XEN
> + extern int xen_range_needs_mapping(phys_addr_t paddr, size_t size);
> + if (xen_pv_domain() && xen_range_needs_mapping(addr, size))
> + return 0;
> +#endif
> +
> + dma_addr = swiotlb_phys_to_bus(dev, addr);
> + if (dma_addr + size <= mask)
> + return 0;
> + return dma_addr;
> +}
> +
> #endif
> diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
> index 2fffc22..c2b4196 100644
> --- a/arch/x86/kernel/pci-dma.c
> +++ b/arch/x86/kernel/pci-dma.c
> @@ -145,8 +145,8 @@ again:
> if (!page)
> return NULL;
>
> - addr = page_to_phys(page);
> - if (!is_buffer_dma_capable(dma_mask, addr, size)) {
> + addr = dma_map_range(dev, dma_mask, page_to_phys(page), size);
> + if (!(addr == 0)) {
> __free_pages(page, get_order(size));
>
> if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
> diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-
> gart_64.c
> index 1e8920d..6a55770 100644
> --- a/arch/x86/kernel/pci-gart_64.c
> +++ b/arch/x86/kernel/pci-gart_64.c
> @@ -191,13 +191,13 @@ static inline int
> need_iommu(struct device *dev, unsigned long addr, size_t size)
> {
> return force_iommu ||
> - !is_buffer_dma_capable(*dev->dma_mask, addr, size);
> + dma_map_range(dev, *dev->dma_mask, addr, size) == 0;
> }
>
> static inline int
> nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
> {
> - return !is_buffer_dma_capable(*dev->dma_mask, addr, size);
> + return dma_map_range(dev, *dev->dma_mask, addr, size) == 0;
> }
>
> /* Map a single continuous physical area into the IOMMU.
> diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
> index 71d412a..712ce59 100644
> --- a/arch/x86/kernel/pci-nommu.c
> +++ b/arch/x86/kernel/pci-nommu.c
> @@ -12,13 +12,13 @@
> #include <asm/dma.h>
>
> static int
> -check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t
> size)
> +check_addr(char *name, struct device *hwdev, phys_addr_t phys,
> size_t size)
> {
> - if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) {
> + if (hwdev && dma_map_range(hwdev, *hwdev->dma_mask, phys, size) ==
> 0) {
> if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
> printk(KERN_ERR
> "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
> - name, (long long)bus, size,
> + name, (long long)phys, size,
> (long long)*hwdev->dma_mask);
> return 0;
> }
> @@ -30,12 +30,12 @@ static dma_addr_t nommu_map_page(struct device
> *dev, struct page *page,
> enum dma_data_direction dir,
> struct dma_attrs *attrs)
> {
> - dma_addr_t bus = page_to_phys(page) + offset;
> + phys_addr_t phys = page_to_phys(page) + offset;
> WARN_ON(size == 0);
> - if (!check_addr("map_single", dev, bus, size))
> + if (!check_addr("map_single", dev, phys, size))
> return bad_dma_address;
> flush_write_buffers();
> - return bus;
> + return phys;
> }
>
> /* Map a set of buffers described by scatterlist in streaming
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 8083b6a..85dafa1 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -96,11 +96,6 @@ static inline int is_device_dma_capable(struct
> device *dev)
> return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
> }
>
> -static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr,
> size_t size)
> -{
> - return addr + size <= mask;
> -}
> -
> #ifdef CONFIG_HAS_DMA
> #include <asm/dma-mapping.h>
> #else
> diff --git a/lib/swiotlb.c b/lib/swiotlb.c
> index cec5f62..4fd5185 100644
> --- a/lib/swiotlb.c
> +++ b/lib/swiotlb.c
> @@ -147,17 +147,6 @@ void * __weak swiotlb_bus_to_virt(struct device
> *hwdev, dma_addr_t address)
> return phys_to_virt(swiotlb_bus_to_phys(hwdev, address));
> }
>
> -int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev,
> - dma_addr_t addr, size_t size)
> -{
> - return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
> -}
> -
> -int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr,
> size_t size)
> -{
> - return 0;
> -}
> -
> static void swiotlb_print_info(unsigned long bytes)
> {
> phys_addr_t pstart, pend;
> @@ -318,17 +307,6 @@ cleanup1:
> return -ENOMEM;
> }
>
> -static inline int
> -address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t
> size)
> -{
> - return swiotlb_arch_address_needs_mapping(hwdev, addr, size);
> -}
> -
> -static inline int range_needs_mapping(phys_addr_t paddr, size_t size)
> -{
> - return swiotlb_force || swiotlb_arch_range_needs_mapping(paddr,
> size);
> -}
> -
> static int is_swiotlb_buffer(char *addr)
> {
> return addr >= io_tlb_start && addr < io_tlb_end;
> @@ -555,18 +533,17 @@ void *
> swiotlb_alloc_coherent(struct device *hwdev, size_t size,
> dma_addr_t *dma_handle, gfp_t flags)
> {
> - dma_addr_t dev_addr;
> + phys_addr_t phys;
> void *ret;
> int order = get_order(size);
> u64 dma_mask = DMA_BIT_MASK(32);
> + dma_addr_t dma_addr;
>
> if (hwdev && hwdev->coherent_dma_mask)
> dma_mask = hwdev->coherent_dma_mask;
>
> ret = (void *)__get_free_pages(flags, order);
> - if (ret &&
> - !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(hwdev,
> ret),
> - size)) {
> + if (ret && dma_map_range(hwdev, dma_mask, virt_to_phys(ret), size)
> == 0) {
> /*
> * The allocated memory isn't reachable by the device.
> */
> @@ -585,19 +562,20 @@ swiotlb_alloc_coherent(struct device *hwdev,
> size_t size,
> }
>
> memset(ret, 0, size);
> - dev_addr = swiotlb_virt_to_bus(hwdev, ret);
> + phys = virt_to_phys(ret);
>
> /* Confirm address can be DMA'd by device */
> - if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) {
> - printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
> + dma_addr = dma_map_range(hwdev, dma_mask, phys, size);
> + if (dma_addr == 0) {
> + printk("hwdev DMA mask = 0x%016Lx, physical addr = 0x%016Lx\n",
> (unsigned long long)dma_mask,
> - (unsigned long long)dev_addr);
> + (unsigned long long)phys);
>
> /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
> do_unmap_single(hwdev, ret, size, DMA_TO_DEVICE);
> return NULL;
> }
> - *dma_handle = dev_addr;
> + *dma_handle = dma_addr;
> return ret;
> }
> EXPORT_SYMBOL(swiotlb_alloc_coherent);
> @@ -649,7 +627,7 @@ dma_addr_t swiotlb_map_page(struct device *dev,
> struct page *page,
> struct dma_attrs *attrs)
> {
> phys_addr_t phys = page_to_phys(page) + offset;
> - dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys);
> + dma_addr_t dma_addr;
> void *map;
>
> BUG_ON(dir == DMA_NONE);
> @@ -658,9 +636,9 @@ dma_addr_t swiotlb_map_page(struct device *dev,
> struct page *page,
> * we can safely return the device addr and not worry about bounce
> * buffering it.
> */
> - if (!address_needs_mapping(dev, dev_addr, size) &&
> - !range_needs_mapping(phys, size))
> - return dev_addr;
> + dma_addr = dma_map_range(dev, dma_get_mask(dev), phys, size);
> + if (dma_addr && !swiotlb_force)
> + return dma_addr;
>
> /*
> * Oh well, have to allocate and map a bounce buffer.
> @@ -671,15 +649,14 @@ dma_addr_t swiotlb_map_page(struct device
> *dev, struct page *page,
> map = io_tlb_overflow_buffer;
> }
>
> - dev_addr = swiotlb_virt_to_bus(dev, map);
> -
> /*
> * Ensure that the address returned is DMA'ble
> */
> - if (address_needs_mapping(dev, dev_addr, size))
> + dma_addr = dma_map_range(dev, dma_get_mask(dev),
> virt_to_phys(map), size);
> + if (dma_addr == 0)
> panic("map_single: bounce buffer is not DMA'ble");
>
> - return dev_addr;
> + return dma_addr;
> }
> EXPORT_SYMBOL_GPL(swiotlb_map_page);
>
> @@ -820,10 +797,8 @@ swiotlb_map_sg_attrs(struct device *hwdev,
> struct scatterlist *sgl, int nelems,
>
> for_each_sg(sgl, sg, nelems, i) {
> phys_addr_t paddr = sg_phys(sg);
> - dma_addr_t dev_addr = swiotlb_phys_to_bus(hwdev, paddr);
> -
> - if (range_needs_mapping(paddr, sg->length) ||
> - address_needs_mapping(hwdev, dev_addr, sg->length)) {
> + dma_addr_t dma_addr = dma_map_range(hwdev, dma_get_mask(hwdev),
> paddr, sg->length);
> + if (dma_addr == 0 || swiotlb_force) {
> void *map = map_single(hwdev, sg_phys(sg),
> sg->length, dir);
> if (!map) {
> @@ -835,9 +810,9 @@ swiotlb_map_sg_attrs(struct device *hwdev,
> struct scatterlist *sgl, int nelems,
> sgl[0].dma_length = 0;
> return 0;
> }
> - sg->dma_address = swiotlb_virt_to_bus(hwdev, map);
> - } else
> - sg->dma_address = dev_addr;
> + dma_addr = dma_map_range(hwdev, dma_get_mask(hwdev),
> virt_to_phys(map), sg->length);
> + }
> + sg->dma_address = dma_addr;
> sg->dma_length = sg->length;
> }
> return nelems;
>
^ permalink raw reply
* [PATCH v3] powerpc: add ioremap_early() for mapping IO regions before MMU_init()
From: Grant Likely @ 2009-05-27 18:55 UTC (permalink / raw)
To: linuxppc-dev, benh, scottwood, galak
From: Grant Likely <grant.likely@secretlab.ca>
ioremap_early() is useful for things like mapping SoC internally registers
and early debug output because it allows mappings to devices to be setup
early in the boot process where they are needed. It also give a
performance boost since BAT mapped registers don't get flushed out of
the TLB.
Without ioremap_early(), early mappings are set up in an ad-hoc manner
and they get lost when the MMU is set up. Drivers then have to perform
hacky fixups to transition over to new mappings.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
new in v3:
- Rebased onto Ben's dma_alloc_coherent changes
- Fixed alignment to match region size
arch/powerpc/include/asm/io.h | 8 +
arch/powerpc/kernel/setup_32.c | 4
arch/powerpc/mm/init_32.c | 3
arch/powerpc/mm/mmu_decl.h | 7 +
arch/powerpc/mm/pgtable_32.c | 12 +
arch/powerpc/mm/ppc_mmu_32.c | 210 +++++++++++++++++++++++---
arch/powerpc/platforms/52xx/mpc52xx_common.c | 13 ++
arch/powerpc/sysdev/cpm_common.c | 2
8 files changed, 228 insertions(+), 31 deletions(-)
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 001f2f1..10183e2 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -624,6 +624,12 @@ static inline void iosync(void)
*
* * iounmap undoes such a mapping and can be hooked
*
+ * * ioremap_early is for setting up mapping regions during early boot. Useful
+ * for console devices or mapping an entire region of SoC internal registers.
+ * ioremap_early becomes usable at machine_init() time. Care must be taken
+ * when using this routine because it can consume limited resources like BAT
+ * registers.
+ *
* * __ioremap_at (and the pending __iounmap_at) are low level functions to
* create hand-made mappings for use only by the PCI code and cannot
* currently be hooked. Must be page aligned.
@@ -647,6 +653,8 @@ extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size,
extern void iounmap(volatile void __iomem *addr);
+extern void __iomem *ioremap_early(phys_addr_t addr, unsigned long size);
+
extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
unsigned long flags);
extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 9e1ca74..c1c0442 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -41,6 +41,7 @@
#include <asm/mmu_context.h>
#include "setup.h"
+#include "mm/mmu_decl.h"
#define DBG(fmt...)
@@ -118,6 +119,9 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
*/
notrace void __init machine_init(unsigned long dt_ptr)
{
+ /* Get ready to allocate IO virtual address regions */
+ ioremap_init();
+
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 3de6a0d..806c237 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -168,9 +168,6 @@ void __init MMU_init(void)
ppc_md.progress("MMU:mapin", 0x301);
mapin_ram();
- /* Initialize early top-down ioremap allocator */
- ioremap_bot = IOREMAP_TOP;
-
/* Map in I/O resources */
if (ppc_md.progress)
ppc_md.progress("MMU:setio", 0x302);
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index d1f9c62..6be30fe 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -86,11 +86,14 @@ struct tlbcam {
extern void mapin_ram(void);
extern int map_page(unsigned long va, phys_addr_t pa, int flags);
-extern void setbat(int index, unsigned long virt, phys_addr_t phys,
- unsigned int size, int flags);
+extern int setbat(unsigned long virt, phys_addr_t phys, unsigned int size,
+ int flags);
+extern int loadbat(unsigned long virt, phys_addr_t phys, unsigned int size,
+ int flags);
extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
unsigned int size, int flags, unsigned int pid);
extern void invalidate_tlbcam_entry(int index);
+extern void ioremap_init(void); /* called by machine_init() */
extern int __map_without_bats;
extern unsigned long ioremap_base;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5422169..508fb91 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -51,8 +51,6 @@ extern char etext[], _stext[];
#ifdef HAVE_BATS
extern phys_addr_t v_mapped_by_bats(unsigned long va);
extern unsigned long p_mapped_by_bats(phys_addr_t pa);
-void setbat(int index, unsigned long virt, phys_addr_t phys,
- unsigned int size, int flags);
#else /* !HAVE_BATS */
#define v_mapped_by_bats(x) (0UL)
@@ -126,6 +124,16 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
return ptepage;
}
+/**
+ * ioremap_init - Initialize early top-down ioremap allocator
+ */
+void __init ioremap_init(void)
+{
+ if (ioremap_bot)
+ return;
+ ioremap_bot = IOREMAP_TOP;
+}
+
void __iomem *
ioremap(phys_addr_t addr, unsigned long size)
{
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 2d2a87e..01acd2e 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -72,38 +72,41 @@ unsigned long p_mapped_by_bats(phys_addr_t pa)
return 0;
}
+/**
+ * mmu_mapin_ram - Map as much of RAM as possible into kernel space using BATs
+ */
unsigned long __init mmu_mapin_ram(void)
{
unsigned long tot, bl, done;
- unsigned long max_size = (256<<20);
+ int rc;
if (__map_without_bats) {
- printk(KERN_DEBUG "RAM mapped without BATs\n");
+ pr_debug("RAM mapped without BATs\n");
return 0;
}
- /* Set up BAT2 and if necessary BAT3 to cover RAM. */
-
- /* Make sure we don't map a block larger than the
- smallest alignment of the physical address. */
+ /* Set up BATs to cover RAM. */
tot = total_lowmem;
- for (bl = 128<<10; bl < max_size; bl <<= 1) {
- if (bl * 2 > tot)
+ done = 0;
+ while (done < tot) {
+ /* determine the smallest block size need to map the region.
+ * Don't use a BAT mapping if the remaining region is less
+ * that 128k */
+ if (tot - done <= 128<<10)
break;
- }
-
- setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X);
- done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
- if ((done < tot) && !bat_addrs[3].limit) {
- /* use BAT3 to cover a bit more */
- tot -= done;
- for (bl = 128<<10; bl < max_size; bl <<= 1)
- if (bl * 2 > tot)
+ for (bl = 128<<10; bl < (256<<20); bl <<= 1)
+ if ((bl * 2) > (tot - done))
break;
- setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
- done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
+
+ /* Allocate the BAT and recalculate amount of RAM mapped */
+ rc = setbat(PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
+ if (rc < 0)
+ break;
+ done = (unsigned long)bat_addrs[rc].limit - PAGE_OFFSET + 1;
}
+ if (done == 0)
+ pr_crit("Weird; No BATs available for RAM.\n");
return done;
}
@@ -112,12 +115,29 @@ unsigned long __init mmu_mapin_ram(void)
* The parameters are not checked; in particular size must be a power
* of 2 between 128k and 256M.
*/
-void __init setbat(int index, unsigned long virt, phys_addr_t phys,
- unsigned int size, int flags)
+int __init setbat(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags)
{
unsigned int bl;
- int wimgxpp;
- struct ppc_bat *bat = BATS[index];
+ int wimgxpp, index, nr_bats;
+ struct ppc_bat *bat;
+
+ /* Find a free BAT
+ *
+ * Special case; Keep the first entry in reserve for mapping RAM.
+ * Otherwise the too many other users can prevent RAM from getting
+ * mapped at all with a BAT.
+ */
+ index = (flags == PAGE_KERNEL_X) ? 0 : 1;
+ nr_bats = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
+ for (; index < nr_bats; index++) {
+ if ((BATS[index][0].batu == 0) && (BATS[index][1].batu == 0))
+ break;
+ }
+ if (index == nr_bats)
+ return -1;
+
+ bat = BATS[index];
if ((flags & _PAGE_NO_CACHE) ||
(cpu_has_feature(CPU_FTR_NEED_COHERENT) == 0))
@@ -156,6 +176,150 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
bat_addrs[index].start = virt;
bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1;
bat_addrs[index].phys = phys;
+ return index;
+}
+
+/**
+ * loadbat - Set up and configure one of the I/D BAT register pairs.
+ * @virt - virtual address, 128k aligned
+ * @phys - physical address, 128k aligned
+ * @size - size of mapping
+ * @flags - region attribute flags
+ *
+ * Uses setbat() to allocate a BAT pair and immediately writes the
+ * configuration into the BAT registers (instead of waiting for load_up_mmu)
+ */
+int __init loadbat(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags)
+{
+ struct ppc_bat *bat;
+ int i;
+
+ i = setbat(virt, phys, size, flags);
+ if (i < 0)
+ return i;
+ bat = BATS[i];
+
+ /* BATs must be set with a switch statement because there is no way
+ * to paramaterize mtspr/mfspr instructions.
+ *
+ * Note: BAT0 is not handled here because early boot code depends
+ * on BAT0 for mapping first 16M of RAM. setbat() keeps BAT0 in
+ * reserve for mapping main memory anyway, so this is okay.
+ */
+ switch (i) {
+ case 1:
+ mtspr(SPRN_IBAT1U, bat[0].batu);
+ mtspr(SPRN_IBAT1L, bat[0].batl);
+ mtspr(SPRN_DBAT1U, bat[1].batu);
+ mtspr(SPRN_DBAT1L, bat[1].batl);
+ break;
+ case 2:
+ mtspr(SPRN_IBAT2U, bat[0].batu);
+ mtspr(SPRN_IBAT2L, bat[0].batl);
+ mtspr(SPRN_DBAT2U, bat[1].batu);
+ mtspr(SPRN_DBAT2L, bat[1].batl);
+ break;
+ case 3:
+ mtspr(SPRN_IBAT3U, bat[0].batu);
+ mtspr(SPRN_IBAT3L, bat[0].batl);
+ mtspr(SPRN_DBAT3U, bat[1].batu);
+ mtspr(SPRN_DBAT3L, bat[1].batl);
+ break;
+ case 4:
+ mtspr(SPRN_IBAT4U, bat[0].batu);
+ mtspr(SPRN_IBAT4L, bat[0].batl);
+ mtspr(SPRN_DBAT4U, bat[1].batu);
+ mtspr(SPRN_DBAT4L, bat[1].batl);
+ break;
+ case 5:
+ mtspr(SPRN_IBAT5U, bat[0].batu);
+ mtspr(SPRN_IBAT5L, bat[0].batl);
+ mtspr(SPRN_DBAT5U, bat[1].batu);
+ mtspr(SPRN_DBAT5L, bat[1].batl);
+ break;
+ case 6:
+ mtspr(SPRN_IBAT6U, bat[0].batu);
+ mtspr(SPRN_IBAT6L, bat[0].batl);
+ mtspr(SPRN_DBAT6U, bat[1].batu);
+ mtspr(SPRN_DBAT6L, bat[1].batl);
+ break;
+ case 7:
+ mtspr(SPRN_IBAT7U, bat[0].batu);
+ mtspr(SPRN_IBAT7L, bat[0].batl);
+ mtspr(SPRN_DBAT7U, bat[1].batu);
+ mtspr(SPRN_DBAT7L, bat[1].batl);
+ break;
+ }
+
+ return i;
+}
+
+/**
+ * ioremap_early - Allow large persistant IO regions to be mapped early.
+ * @addr: physical address of region
+ * @size: size of region
+ *
+ * This routine uses setbat() to set up IO ranges before the MMU is
+ * fully configured.
+ *
+ * This routine can be called really early, before MMU_init() is called. It
+ * is useful for setting up early debug output consoles and frequently
+ * accessed IO regions, like the internally memory mapped registers (IMMR)
+ * in an SoC. Ranges mapped with this function persist even after MMU_init()
+ * is called and the MMU is turned on 'for real.'
+ *
+ * The region mapped is large (minimum size of 128k) and virtual mapping must
+ * be aligned against this boundary. Therefore, to avoid fragmentation all
+ * calls to ioremap_early() are best made before any calls to ioremap
+ * for smaller regions.
+ */
+void __iomem * __init
+ioremap_early(phys_addr_t addr, unsigned long size)
+{
+ unsigned long v, p, bl;
+ int i;
+
+ /* Be loud and annoying if someone calls this too late.
+ * No need to crash the kernel though */
+ WARN_ON(mem_init_done);
+ if (mem_init_done)
+ return NULL;
+
+ /* Make sure request is sane */
+ if (size == 0)
+ return NULL;
+
+ /* If the region is already block mapped, then there is nothing
+ * to do; just return the mapped address */
+ v = p_mapped_by_bats(addr);
+ if (v)
+ return (void __iomem *)v;
+
+ /* Align region size */
+ for (bl = 128<<10; bl < (256<<20); bl <<= 1) {
+ p = _ALIGN_DOWN(addr, bl); /* BATs align on 128k boundaries */
+ size = ALIGN(addr - p + size, bl);
+ if (bl >= size)
+ break;
+ }
+
+ /* Complain loudly if too much is requested */
+ if (bl >= (256<<20)) {
+ WARN_ON(1);
+ return NULL;
+ }
+
+ /* Allocate the aligned virtual base address. ALIGN_DOWN is used
+ * to ensure no overlaps occur with normal 4k ioremaps. */
+ ioremap_bot = _ALIGN_DOWN(ioremap_bot, bl) - size;
+
+ /* Set up a BAT for this IO region */
+ i = loadbat(ioremap_bot, p, size, PAGE_KERNEL_NCG);
+ if (i < 0)
+ return NULL;
+
+ return (void __iomem *) (ioremap_bot + (addr - p));
}
/*
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 8e3dd5a..2c49148 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -146,7 +146,20 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
void __init
mpc52xx_map_common_devices(void)
{
+ const struct of_device_id immr_ids[] = {
+ { .compatible = "fsl,mpc5200-immr", },
+ { .compatible = "fsl,mpc5200b-immr", },
+ { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
+ { .type = "builtin", .compatible = "mpc5200", }, /* efika */
+ {}
+ };
struct device_node *np;
+ struct resource res;
+
+ /* Pre-map the whole register space using a BAT entry */
+ np = of_find_matching_node(NULL, immr_ids);
+ if (np && (of_address_to_resource(np, 0, &res) == 0))
+ ioremap_early(res.start, res.end - res.start + 1);
/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
* possibly from a interrupt context. wdt is only implement
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index e4b6d66..370723e 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -56,7 +56,7 @@ void __init udbg_init_cpm(void)
{
if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
- setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
+ setbat(0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
#endif
udbg_putc = udbg_putc_cpm;
}
^ permalink raw reply related
* [PATCH] v2: Display processor virtualization resource allocations in lparcfg
From: Nathan Fontenot @ 2009-05-27 14:41 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <4A1C2E10.9020109@austin.ibm.com>
This patch updates the output from /proc/ppc64/lparcfg to display the
processor virtualization resource allocations for a shared processor
partition.
This information is already gathered via the h_get_ppp call, we just
have to make sure that the ibm,partition-performance-parameters-level
property is >= 1 to ensure that the information is valid.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---
Index: linux-2.6/arch/powerpc/kernel/lparcfg.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/lparcfg.c 2009-05-21 10:24:57.000000000 -0500
+++ linux-2.6/arch/powerpc/kernel/lparcfg.c 2009-05-27 08:27:34.000000000 -0500
@@ -169,6 +169,9 @@
u8 unallocated_weight;
u16 active_procs_in_pool;
u16 active_system_procs;
+ u16 phys_platform_procs;
+ u32 max_proc_cap_avail;
+ u32 entitled_proc_cap_avail;
};
/*
@@ -190,13 +193,18 @@
* XX - Unallocated Variable Processor Capacity Weight.
* XXXX - Active processors in Physical Processor Pool.
* XXXX - Processors active on platform.
+ * R8 (QQQQRRRRRRSSSSSS). if ibm,partition-performance-parameters-level >= 1
+ * XXXX - Physical platform procs allocated to virtualization.
+ * XXXXXX - Max procs capacity % available to the partitions pool.
+ * XXXXXX - Entitled procs capacity % available to the
+ * partitions pool.
*/
static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
{
unsigned long rc;
- unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
- rc = plpar_hcall(H_GET_PPP, retbuf);
+ rc = plpar_hcall9(H_GET_PPP, retbuf);
ppp_data->entitlement = retbuf[0];
ppp_data->unallocated_entitlement = retbuf[1];
@@ -210,6 +218,10 @@
ppp_data->active_procs_in_pool = (retbuf[3] >> 2 * 8) & 0xffff;
ppp_data->active_system_procs = retbuf[3] & 0xffff;
+ ppp_data->phys_platform_procs = retbuf[4] >> 6 * 8;
+ ppp_data->max_proc_cap_avail = (retbuf[4] >> 3 * 8) & 0xffffff;
+ ppp_data->entitled_proc_cap_avail = retbuf[4] & 0xffffff;
+
return rc;
}
@@ -234,6 +246,8 @@
static void parse_ppp_data(struct seq_file *m)
{
struct hvcall_ppp_data ppp_data;
+ struct device_node *root;
+ const int *perf_level;
int rc;
rc = h_get_ppp(&ppp_data);
@@ -267,6 +281,28 @@
seq_printf(m, "capped=%d\n", ppp_data.capped);
seq_printf(m, "unallocated_capacity=%lld\n",
ppp_data.unallocated_entitlement);
+
+ /* The last bits of information returned from h_get_ppp are only
+ * valid if the ibm,partition-performance-parameters-level
+ * property is >= 1.
+ */
+ root = of_find_node_by_path("/");
+ if (root) {
+ perf_level = of_get_property(root,
+ "ibm,partition-performance-parameters-level",
+ NULL);
+ if (perf_level && (*perf_level >= 1)) {
+ seq_printf(m,
+ "physical_procs_allocated_to_virtualization=%d\n",
+ ppp_data.phys_platform_procs);
+ seq_printf(m, "max_proc_capacity_available=%d\n",
+ ppp_data.max_proc_cap_avail);
+ seq_printf(m, "entitled_proc_capacity_available=%d\n",
+ ppp_data.entitled_proc_cap_avail);
+ }
+
+ of_node_put(root);
+ }
}
/**
^ permalink raw reply
* Re: [PATCH] Display processor virtualization resource allocations in lparcfg
From: Nathan Fontenot @ 2009-05-27 14:30 UTC (permalink / raw)
To: michael; +Cc: linuxppc-dev
In-Reply-To: <1243386862.18971.41.camel@concordia>
Michael Ellerman wrote:
>> + root = of_find_node_by_path("/");
>> + if (root) {
>> + perf_level = of_get_property(root,
>> + "ibm,partition-performance-parameters-level",
>> + NULL);
>
> What if there is no such property?
Yes, that would cause this code to do some bad things. Updated patch on its way.
>
>> + if (*perf_level >= 1) {
>> + seq_printf(m,
>> + "physical_procs_allocated_to_virtualization=%d\n",
>> + ppp_data.phys_platform_procs);
>> + seq_printf(m, "max_proc_capacity_available=%d\n",
>> + ppp_data.max_proc_cap_avail);
>> + seq_printf(m, "entitled_proc_capacity_available=%d\n",
>> + ppp_data.entitled_proc_cap_avail);
>> + }
>> +
>> + of_node_put(root);
>> + }
>
> cheers
-Nathan
^ permalink raw reply
* Re: [alsa-devel] [PATCH V2] Modify mpc5200 AC97 driver to use V9 of spin_event_timeout()
From: Timur Tabi @ 2009-05-27 11:39 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-dev, alsa-devel, broonie
In-Reply-To: <20090527043018.4667.94590.stgit@terra>
On Tue, May 26, 2009 at 11:30 PM, Jon Smirl <jonsmirl@gmail.com> wrote:
> The function signature for spin_event_timeout() has changed in version V9.
> Adjust the mpc5200 AC97 driver to use the new function.
> v2 - switch back to udelay() for fixed timeouts.
>
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
Acked-by: Timur Tabi <timur@freescale.com>
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: Net: ucc_geth ethernet driver optimization space
From: Li Yang @ 2009-05-27 10:36 UTC (permalink / raw)
To: Liu Dave-R63238; +Cc: netdev, linux-kernel, linuxppc-dev
In-Reply-To: <D7CCA83BB0796C49BC0BB53B6AB1208934920A@zch01exm21.fsl.freescale.net>
On Wed, May 27, 2009 at 1:08 PM, Liu Dave-R63238 <DaveLiu@freescale.com> wr=
ote:
> Guys,
>
> The ucc_geth ethernet driver have dozens of strong sync read/write
> operation, such as in_be32/16/8, out_be32/16/8.
>
> all of them is sync read/write, it is very expensive for performance.
>
Totally agree. That's one of my concerns right from the beginning.
> For the critical patch, we can remove some unnecessary in_be(x),
> out_be(x) with normal memory operation, and keep some necessary
> memory barrier.
>
> eg: BD access in the interrupt handler and start_xmit.
>
> The BD operation only need the memory barrier between length/buffer
> and status.
>
> struct buffer descriptor {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u16 status;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u16 length;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u32 buffer;
> } __attribute__ ((packed));
>
> struct buffer descriptor *BD;
>
> BD->length =3D xxxx;
> BD->buffer =3D yyyy;
> wmb();
> BD->status =3D zzzz;
The BD can reside either in memory or memory mapped region, which
makes the case more complex.
MMIO accesses need to use IO accessors for the sparse checking. We
might make use of the __raw_*() accessors, but I'm not sure if it's
suitable for non-PCI buses on powerpc. And also we need to pay
special attention to the problem described here:
http://lwn.net/Articles/198988/
- Leo
^ permalink raw reply
* Re: [GIT PULL] fsldma driver fixes
From: Li Yang @ 2009-05-27 8:24 UTC (permalink / raw)
To: Dan Williams; +Cc: linuxppc-dev Development, lkml, Ira Snyder
In-Reply-To: <e9c3a7c20905261659v5d785df3w646efd4cbba2e6dd@mail.gmail.com>
On Wed, May 27, 2009 at 7:59 AM, Dan Williams <dan.j.williams@intel.com> wr=
ote:
> On Fri, May 22, 2009 at 3:47 AM, Li Yang <leoli@freescale.com> wrote:
>> Hi Dan,
>>
>> Here are fixes for Freescale DMA engine driver.
>>
>> Thanks,
>> - Leo
>>
>>
>> The following changes since commit 5805977e63a36ad56594a623f3bd2bebcb7db=
233:
>> =C2=A0Linus Torvalds (1):
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0Merge branch 'for-linus' of git://git.kernel.=
org/.../jbarnes/drm-2.6
>>
>> are available in the git repository at:
>>
>> =C2=A0git://git.kernel.org/pub/scm/linux/kernel/git/leo/fsl-soc.git fsld=
ma
>>
>> Ira Snyder (4):
>> =C2=A0 =C2=A0 =C2=A0fsldma: fix "DMA halt timeout!" errors
>> =C2=A0 =C2=A0 =C2=A0fsldma: fix infinite loop on multi-descriptor DMA ch=
ain completion
>> =C2=A0 =C2=A0 =C2=A0fsldma: snooping is not enabled for last entry in de=
scriptor chain
>> =C2=A0 =C2=A0 =C2=A0fsldma: fix memory leak on error path in fsl_dma_pre=
p_memcpy()
>>
>> Li Yang (1):
>> =C2=A0 =C2=A0 =C2=A0fsldma: update mailling list address in MAINTAINERS
>>
>> Roel Kluin (1):
>> =C2=A0 =C2=A0 =C2=A0fsldma: fix check on potential fdev->chan[] overflow
>>
>
> Pulled, thanks. =C2=A0These all look like 2.6.30 candidates, right?
Yes, they are pure fixes.
- Leo
^ 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