* Re: [PATCH 00/13] IB/ehca: eHCA2 enablement & some fixes
From: Joachim Fenkes @ 2007-07-10 13:20 UTC (permalink / raw)
To: Roland Dreier
Cc: LKML, LinuxPPC-Dev, Christoph Raisch, OF-General, Stefan Roscher
In-Reply-To: <adak5t9w7kx.fsf@cisco.com>
Roland Dreier <rdreier@cisco.com> wrote on 10.07.2007 00:11:42:
> thanks, I applied these for 2.6.23 and fixed a bunch of minor things
> that scripts/checkpatch.pl complained about (since I was in a mood to
> do mindless things).
Thanks! Both for the quick merge and for the fixes!
> In the future please run that yourself and clean
> up the obvious things. I generally don't worry about the 80 column
> stuff, but it will catch most whitespace problems and tell you that
> foo(x,y) should be foo(x, y) etc. So you don't have to completely
> silence the script but at least take a look at the output.
Didn't know about that script before, so thanks for the pointer!
I'll be sure to pass the next set of patches through it.
Joachim
^ permalink raw reply
* Re: [kernel-2.6.19]Marvell GT-64260 and Ethernet
From: Matt Sealey @ 2007-07-10 13:14 UTC (permalink / raw)
To: ThomasB; +Cc: linuxppc-embedded
In-Reply-To: <13b81f0c0707092336r5c7f4996u6f9c73d95c63bdc6@mail.gmail.com>
Isn't the ethernet the same on the 64260, 64360, 64460?
There's definitely a driver for 6436x and above..
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
ThomasB wrote:
> Hi all,
> I'm porting a Linux kernel 2.6.19 on a PowerPC 750 FX board.
> My Linux runs completely except for Ethernet. I don't find any Ethernet
> driver for my bridge. Do you know if there is an Ethernet driver for the
> Marvell GT-64260 bridge for PowerPC processor. I found a GT-64260
> ethernet driver in the kernel 2.4.34 for MIPS processor, will it be
> possible to port it in a 2.6 kernel?
> Thanks for you help.
>
>
> --
> ThomasB
> http://psyphi.zeblog.com/ <http://psyphi.zeblog.com/>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* Re: [PATCH] Allow exec on 32-bit from readable, non-exec pages, with a warning.
From: Segher Boessenkool @ 2007-07-10 13:11 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070709195743.GA26089@ld0162-tx32.am.freescale.net>
> In older versions of glibc (through 2.3), the dynamic linker
> executes a
> small amount of code from the data segment, which is not marked as
> executable. A recent change (commit
> 9ba4ace39fdfe22268daca9f28c5df384ae462cf)
> stops this from working; there should be a deprecation period before
> older glibc versions stop working.
>
> The problem has been observed on glibc 2.2. While glibc 2.3 has
> the same
> code, I did not see the problem; it may be that it accesses the
> page in
> question as data before executing from it, and thus it is already
> mapped.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: Segher Boessenkool <segher@kernel.crashing.org>
> Unfortunately, this didn't make it into 2.6.22, but it should
> probably go
> into the stable branch...
Both .21.x and .22.x I suppose; if we care about glibc 2.2.x
at all still, that is.
So to make double sure, this doesn't warn on glibc 2.3.x?
Segher
^ permalink raw reply
* Re: [PATCH] i2c-mpc: work around missing-9th-clock-pulse bug
From: Jean Delvare @ 2007-07-10 12:40 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-embedded, Domen Puncer, i2c
In-Reply-To: <fa686aa40707092322v58bbdad0veb0ee2ec00f125b0@mail.gmail.com>
Hi Grant, hi Domen,
On Tue, 10 Jul 2007 00:22:05 -0600, Grant Likely wrote:
> On 7/10/07, Domen Puncer <domen.puncer@telargo.com> wrote:
> > Work around a problem reported on:
> > http://ozlabs.org/pipermail/linuxppc-embedded/2005-July/019038.html
> > Without this patch I2C on mpc5200 becomes unusable after a while.
> > Tested on mpc5200 boards by Matthias and me.
> >
> >
> > Signed-off-by: Domen Puncer <domen.puncer@telargo.com>
>
> Looks good to me,
>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
OK, I will take this patch, but I'd like you to add a comment before
mpc_i2c_fixup() explaining what exactly the problem is and how it is
worked around. Otherwise it's a bit obscure what is going on.
I guess you want this patch in 2.6.23-rc1?
> > ---
> > drivers/i2c/busses/i2c-mpc.c | 17 +++++++++++++++++
> > 1 file changed, 17 insertions(+)
> >
> > Index: work-powerpc.git/drivers/i2c/busses/i2c-mpc.c
> > ===================================================================
> > --- work-powerpc.git.orig/drivers/i2c/busses/i2c-mpc.c
> > +++ work-powerpc.git/drivers/i2c/busses/i2c-mpc.c
> > @@ -74,6 +74,20 @@ static irqreturn_t mpc_i2c_isr(int irq,
> > return IRQ_HANDLED;
> > }
> >
> > +static void mpc_i2c_fixup(struct mpc_i2c *i2c)
> > +{
> > + writeccr(i2c, 0);
> > + udelay(30);
> > + writeccr(i2c, CCR_MEN);
> > + udelay(30);
> > + writeccr(i2c, CCR_MSTA | CCR_MTX);
> > + udelay(30);
> > + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
> > + udelay(30);
> > + writeccr(i2c, CCR_MEN);
> > + udelay(30);
> > +}
> > +
> > static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
> > {
> > unsigned long orig_jiffies = jiffies;
> > @@ -153,6 +167,7 @@ static void mpc_i2c_start(struct mpc_i2c
> > static void mpc_i2c_stop(struct mpc_i2c *i2c)
> > {
> > writeccr(i2c, CCR_MEN);
> > + writeccr(i2c, 0);
> > }
> >
> > static int mpc_write(struct mpc_i2c *i2c, int target,
> > @@ -245,6 +260,8 @@ static int mpc_xfer(struct i2c_adapter *
> > }
> > if (time_after(jiffies, orig_jiffies + HZ)) {
> > pr_debug("I2C: timeout\n");
> > + if (readb(i2c->base + MPC_I2C_SR) == (CSR_MCF | CSR_MBB | CSR_RXAK))
> > + mpc_i2c_fixup(i2c);
> > return -EIO;
> > }
> > schedule();
> >
--
Jean Delvare
^ permalink raw reply
* Re: [PATCH] Allow exec on 32-bit from readable, non-exec pages, with a warning.
From: Segher Boessenkool @ 2007-07-10 13:08 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, paulus, Arnd Bergmann
In-Reply-To: <4692A5B8.9010702@freescale.com>
>> I may be missing the obvious, but doesn't that defeat the purpose of
>> non-executable mappings?
>
> The hardware in question doesn't support non-executable mappings;
Not on a per-page basis, anyway.
> otherwise, it'd never have worked in the first place. Note that
> this is
> only allowed on 32-bit, non-book-E.
>
> There isn't much value in enforcing non-exec mappings only if it
> happens
> to be the first fault on a given page.
Yeah. Giving the warning is a good thing though.
Segher
^ permalink raw reply
* Re: [PATCH] ide: Use inline function for eieio
From: Sergei Shtylyov @ 2007-07-10 13:08 UTC (permalink / raw)
To: Kumar Gala; +Cc: linux-ide, bzolnier, linuxppc-dev
In-Reply-To: <Pine.LNX.4.64.0707100018020.5814@blarg.am.freescale.net>
Hello.
Kumar Gala wrote:
> Move to using inline function variant of eieio instead of inline assmebly.
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
MBR, Sergei
^ permalink raw reply
* Re: [PATCH][POWERPC] document ipic level/sense info
From: Segher Boessenkool @ 2007-07-10 12:59 UTC (permalink / raw)
To: Stuart Yoder; +Cc: linuxppc-dev, paulus
In-Reply-To: <200707091820.l69IKjBU013685@ld0164-tx32.am.freescale.net>
> +Sense and level information follows the Linux convention
> +(specified in include/linux/interrupt.h) and should be encoded
> +as follows:
> +
> + 1 = low to high edge sensitive type enabled
> + 2 = high to low edge sensitive type enabled
> + 4 = active high level sensitive type enabled
> + 8 = active low level sensitive type enabled
Please note that using the same bit encoding as some Linux
version does buys you (almost) nothing; a good parser for
this OF node should do range/value checking on this property
anyway, translating the values in the process costs nothing.
Segher
^ permalink raw reply
* more patches pushed to powerpc.git for-2.6.23 branch
From: Paul Mackerras @ 2007-07-10 12:38 UTC (permalink / raw)
To: linuxppc-dev
I just pushed the following patches to the for-2.6.23 branch on
powerpc.git. I intend to ask Linus to pull everything on the
for-2.6.23 branch shortly, unless I hear loud screams to the
contrary. :)
Paul.
Documentation/feature-removal-schedule.txt | 12 +
Documentation/powerpc/booting-without-of.txt | 32 ++
arch/powerpc/boot/Makefile | 31 ++
arch/powerpc/boot/dts/ebony.dts | 4
arch/powerpc/boot/dts/mpc8272ads.dts | 42 +--
arch/powerpc/boot/dts/mpc832x_mds.dts | 16 +
arch/powerpc/boot/dts/mpc832x_rdb.dts | 16 +
arch/powerpc/boot/dts/mpc8349emitx.dts | 10 +
arch/powerpc/boot/dts/mpc834x_mds.dts | 10 +
arch/powerpc/boot/dts/mpc836x_mds.dts | 16 +
arch/powerpc/boot/dts/mpc8540ads.dts | 147 ++++++-----
arch/powerpc/boot/dts/mpc8541cds.dts | 90 +++----
arch/powerpc/boot/dts/mpc8544ds.dts | 18 +
arch/powerpc/boot/dts/mpc8548cds.dts | 108 ++++----
arch/powerpc/boot/dts/mpc8555cds.dts | 90 +++----
arch/powerpc/boot/dts/mpc8560ads.dts | 148 ++++++-----
arch/powerpc/boot/dts/mpc8568mds.dts | 66 +++--
arch/powerpc/boot/dts/mpc8641_hpcn.dts | 50 +++-
arch/powerpc/boot/dts/mpc866ads.dts | 31 +-
arch/powerpc/boot/dts/mpc885ads.dts | 54 ++--
arch/powerpc/boot/ps3-head.S | 80 ++++++
arch/powerpc/boot/ps3-hvcall.S | 184 ++++++++++++++
arch/powerpc/boot/ps3.c | 161 ++++++++++++
arch/powerpc/boot/wrapper | 55 ++++
arch/powerpc/boot/zImage.ps3.lds.S | 50 ++++
arch/powerpc/kernel/cputable.c | 20 +
arch/powerpc/kernel/io.c | 12 -
arch/powerpc/kernel/irq.c | 3
arch/powerpc/kernel/pci_32.c | 34 ---
arch/powerpc/kernel/pci_64.c | 9 -
arch/powerpc/kernel/ppc_ksyms.c | 1
arch/powerpc/kernel/prom.c | 27 +-
arch/powerpc/kernel/setup-common.c | 21 ++
arch/powerpc/kernel/sysfs.c | 5
arch/powerpc/kernel/time.c | 9 -
arch/powerpc/kernel/vmlinux.lds.S | 6
arch/powerpc/mm/hash_native_64.c | 2
arch/powerpc/mm/mem.c | 2
arch/powerpc/mm/stab.c | 4
arch/powerpc/oprofile/op_model_power4.c | 14 +
arch/powerpc/platforms/52xx/efika.c | 4
arch/powerpc/platforms/52xx/lite5200.c | 2
arch/powerpc/platforms/52xx/mpc52xx_pm.c | 8 -
arch/powerpc/platforms/83xx/Makefile | 2
arch/powerpc/platforms/83xx/mpc8313_rdb.c | 1
arch/powerpc/platforms/83xx/mpc834x_itx.c | 2
arch/powerpc/platforms/83xx/mpc834x_mds.c | 49 ----
arch/powerpc/platforms/83xx/mpc83xx.h | 28 ++
arch/powerpc/platforms/83xx/usb.c | 181 +++++++++++++
arch/powerpc/platforms/85xx/misc.c | 32 ++
arch/powerpc/platforms/85xx/mpc8544_ds.c | 15 -
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 22 --
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 99 +++----
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 21 --
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 15 -
arch/powerpc/platforms/8xx/m8xx_setup.c | 5
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 71 +++++
arch/powerpc/platforms/pasemi/Kconfig | 1
arch/powerpc/platforms/pasemi/setup.c | 2
arch/powerpc/platforms/powermac/low_i2c.c | 23 +-
arch/powerpc/platforms/ps3/mm.c | 2
arch/powerpc/platforms/pseries/reconfig.c | 2
arch/powerpc/sysdev/fsl_soc.c | 13 +
arch/powerpc/sysdev/mpc8xx_pic.h | 11 +
arch/powerpc/sysdev/qe_lib/ucc.c | 2
arch/powerpc/sysdev/qe_lib/ucc_fast.c | 8 +
arch/powerpc/xmon/xmon.c | 2
arch/ppc/kernel/ppc_ksyms.c | 1
arch/ppc/mm/tlb.c | 1
drivers/block/viodasd.c | 4
drivers/char/briq_panel.c | 10 -
drivers/char/hvc_console.c | 2
drivers/char/viotape.c | 12 -
drivers/pcmcia/Kconfig | 17 +
drivers/pcmcia/m8xx_pcmcia.c | 351 ++++++++++++--------------
drivers/rtc/Kconfig | 2
drivers/serial/cpm_uart/cpm_uart_core.c | 2
drivers/serial/of_serial.c | 33 ++
include/asm-powerpc/cache.h | 4
include/asm-powerpc/cputable.h | 26 --
include/asm-powerpc/mmu-8xx.h | 147 +++++++++++
include/asm-powerpc/mmu-fsl-booke.h | 88 +++++++
include/asm-powerpc/mmu.h | 10 -
include/asm-powerpc/mmu_context.h | 202 +++++++++++++++
include/asm-powerpc/mpc8xx.h | 4
include/asm-powerpc/prom.h | 15 +
include/asm-powerpc/reg.h | 2
include/asm-powerpc/system.h | 4
include/asm-powerpc/termbits.h | 4
include/linux/fsl_devices.h | 5
90 files changed, 2322 insertions(+), 937 deletions(-)
create mode 100644 arch/powerpc/boot/ps3-head.S
create mode 100644 arch/powerpc/boot/ps3-hvcall.S
create mode 100644 arch/powerpc/boot/ps3.c
create mode 100644 arch/powerpc/boot/zImage.ps3.lds.S
create mode 100644 arch/powerpc/platforms/83xx/usb.c
create mode 100644 include/asm-powerpc/mmu-8xx.h
create mode 100644 include/asm-powerpc/mmu-fsl-booke.h
Adrian Bunk (1):
[POWERPC] Make drivers/char/hvc_console.c:khvcd() static
Christoph Hellwig (1):
[POWERPC] Remove unused do_signal export
David Gibson (2):
[POWERPC] Split out asm-ppc/mmu.h portions for Freescale Book-E
[POWERPC] Split out asm-ppc/mmu.h portions for PowerPC 8xx
David Woodhouse (1):
[POWERPC] Enable arbitary speed tty ioctls and split input/output speed
Domen Puncer (1):
[POWERPC] 52xx: sparse fixes
Geoff Levand (1):
[POWERPC] PS3: Bootwrapper support.
Grant Likely (1):
[POWERPC] 83xx: Add USB support to mpc8349-mitx board port
Ishizaki Kou (2):
[POWERPC] of_serial: Ignore unknown serial port
[POWERPC] of_serial: add port type checking
Johannes Berg (2):
[POWERPC] powermac i2c: Use mutex
[POWERPC] arch/powerpc/kernel/sysfs.c: Move NUMA exports
Jon Loeliger (1):
[POWERPC] Replace use of GET_64BIT(prop, i) with of_read_number().
Josh Boyer (2):
[POWERPC] Consolidate PowerPC 750 cputable features
[POWERPC] Schedule removal of arch/ppc
Kumar Gala (6):
[POWERPC] Reworked interrupt numbers for OpenPIC based Freescale chips
[POWERPC] Kill pcibios_enable_resources()
[POWERPC] Fix up interrupt senses for MPC85xx boards
[POWERPC] Merge asm-ppc/mmu_context.h into asm-power/mmu_context.h
[POWERPC] Move inline asm eieio to using eieio inline function
[POWERPC] CPM_UART: Use inline function form of eieio
Laurent Pinchart (1):
[PPC] Add linux/pagemap.h to arch/ppc/mm/tlb.c
Li Yang (3):
[POWERPC] qe_lib: export symbols for QE driver to compile as module
[POWERPC] 83xx: USB platform code rework
[POWERPC] Fix typo in Ebony default DTS
Manish Ahuja (1):
[POWERPC] Remove extra return statement
Mathieu Desnoyers (1):
[POWERPC] Remove unnecessary #undef printk from prom.c
Michael Ellerman (4):
[POWERPC] Check for the root node in of_detach_node()
[POWERPC] Generalise device_node flag interface
[POWERPC] Add a warning to help trackdown device_node refcounting bugs
[POWERPC] Make the debugfs "powerpc" dir globally accessible
Olaf Hering (1):
[POWERPC] Make two xmon variables static
Olof Johansson (2):
[POWERPC] pasemi: Rename platform
[POWERPC] pasemi: Don't auto-select CONFIG_EMBEDDED
Robert P. J. Day (2):
[POWERPC] VIOTAPE: Use designated initializers for fops member structures.
[POWERPC] Remove dead code for preventing pread() and pwrite() calls
Roland Dreier (1):
[POWERPC] Add cputable entry for PowerPC 440SPe Rev. B
Roy Zang (4):
[POWERPC] Document the global utilities node define and example
[POWERPC] Fix the node index confusion for SOC
[POWERPC] 85xx: Fix 8548CDS reset bug
[POWERPC] Remove redundant pci_read_irq_line() function for 85xx platform
Sonny Rao (1):
[POWERPC] Check for NULL ppc_md.init_IRQ() before calling
Stephen Rothwell (1):
[POWERPC] Fix viodasd geometry calculations
Timur Tabi (1):
[POWERPC] Fix MAC address entries for 83xx, 85xx, and 86xx device trees
Tony Breeds (3):
[POWERPC] Create a dummy zImage if no valid platform has been selected
[POWERPC] Modify sched_clock() to make CONFIG_PRINTK_TIME more sane
[POWERPC] Add __read_mostly support for powerpc
Vitaly Bordug (2):
[POWERPC] 8xx: mpc885ads pcmcia support
[POWERPC] dts: kill hardcoded phandles
Wade Farnsworth (2):
[POWERPC] Fix drivers/rtc/Kconfig for powerpc
[POWERPC] Add a check for keyboard/mouse device nodes in check_legacy_ioport()
will schmidt (1):
[POWERPC] Oprofile enhanced instruction sampling support
^ permalink raw reply
* Re: [PATCH v3] Create add_rtc() function to enable the RTC CMOS driver
From: Paul Mackerras @ 2007-07-10 11:54 UTC (permalink / raw)
To: Wade Farnsworth; +Cc: linuxppc-dev
In-Reply-To: <1182358772.5674.383.camel@rhino>
Wade Farnsworth writes:
> In order to use the RTC CMOS driver, each architecture must register a
> platform device for the RTC.
>
> This creates a function to register the platform device based on the RTC
> device node and verifies that the RTC port against the hard-coded value
> in asm/mc146818rtc.h.
The patch appears to be line-wrapped. Please re-send.
Paul.
^ permalink raw reply
* Re: [PATCH 06/13] IB/ehca: Set SEND_GRH flag for all non-LL UD QPs on eHCA2
From: Joachim Fenkes @ 2007-07-10 11:26 UTC (permalink / raw)
To: Roland Dreier
Cc: LKML, LinuxPPC-Dev, Christoph Raisch, OF-General, Stefan Roscher
In-Reply-To: <adazm25w998.fsf@cisco.com>
Roland Dreier <rdreier@cisco.com> wrote on 09.07.2007 23:35:31:
> Out of curiousity, does this mean that a GRH will be sent on all UD
> messages (for non-LL QPs)?
No - the bit instructs the hardware to fetch the GRH parts of the QP
context.
The GRH will only be used if the WQE says so.
Joachim
^ permalink raw reply
* [PATCH] [POWERPC] Move generic MPC82xx functions out of ADS-specific
From: Laurent Pinchart @ 2007-07-10 11:12 UTC (permalink / raw)
To: linuxppc-embedded
The non board-specific mpc82xx_halt and mpc82xx_restart functions are defined
in arch/powerpc/platforms/82xx/mpc82xx_ads.c. This patch moves them to
mpc82xx.c to make them usable by other MPC82xx boards.
Signed-off-by: Laurent Pinchart <laurent.pinchart@technotrade.biz>
---
arch/powerpc/platforms/82xx/mpc82xx.c | 33
+++++++++++++++--------------
arch/powerpc/platforms/82xx/mpc82xx.h | 24 +++++++++++++++++++++
arch/powerpc/platforms/82xx/mpc82xx_ads.c | 31 ++++++++++++++-------------
arch/powerpc/platforms/82xx/pq2ads.h | 1 -
4 files changed, 57 insertions(+), 32 deletions(-)
create mode 100644 arch/powerpc/platforms/82xx/mpc82xx.h
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c
b/arch/powerpc/platforms/82xx/mpc82xx.c
index cc9900d..d67c754 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx.c
@@ -50,7 +50,7 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/cpm2_pic.h>
-#include "pq2ads.h"
+#include "mpc82xx.h"
static int __init get_freq(char *name, unsigned long *val)
{
@@ -88,23 +88,24 @@ void __init m82xx_calibrate_decr(void)
"(not found)\n");
}
-void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
+#define RMR_CSRE 0x00000001
+void m82xx_restart(char *cmd)
{
- uint pvid, svid, phid1;
- uint memsize = total_memory;
+ __volatile__ unsigned char dummy;
- pvid = mfspr(SPRN_PVR);
- svid = mfspr(SPRN_SVR);
+ local_irq_disable();
+ ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
- seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
- seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
- seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
- seq_printf(m, "SVR\t\t: 0x%x\n", svid);
-
- /* Display cpu Pll setting */
- phid1 = mfspr(SPRN_HID1);
- seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+ /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
+ mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
+ dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
+ printk("Restart failed\n");
+ while (1) ;
+}
- /* Display the amount of memory */
- seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+void m82xx_halt(void)
+{
+ local_irq_disable();
+ while (1) ;
}
+
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.h
b/arch/powerpc/platforms/82xx/mpc82xx.h
new file mode 100644
index 0000000..427925b
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx.h
@@ -0,0 +1,24 @@
+/*
+ * MPC82xx setup and early boot code plus other random bits.
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright (c) 2006 MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __MACH_MPC82XX_H__
+#define __MACH_MPC82XX_H__
+
+#include <linux/init.h>
+
+extern void __init m82xx_calibrate_decr(void);
+extern void m82xx_restart(char *cmd);
+extern void m82xx_halt(void);
+
+#endif
+
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index 47cb09f..1af9449 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -51,6 +51,7 @@
#include <sysdev/fsl_soc.h>
#include <../sysdev/cpm2_pic.h>
+#include "mpc82xx.h"
#include "pq2ads.h"
#ifdef CONFIG_PCI
@@ -611,25 +612,25 @@ static int __init mpc82xx_ads_probe(void)
return 1;
}
-#define RMR_CSRE 0x00000001
-static void m82xx_restart(char *cmd)
+void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
{
- __volatile__ unsigned char dummy;
+ uint pvid, svid, phid1;
+ uint memsize = total_memory;
- local_irq_disable();
- ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
+ pvid = mfspr(SPRN_PVR);
+ svid = mfspr(SPRN_SVR);
- /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
- mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
- dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
- printk("Restart failed\n");
- while (1) ;
-}
+ seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+ seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
+ seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+ seq_printf(m, "SVR\t\t: 0x%x\n", svid);
-static void m82xx_halt(void)
-{
- local_irq_disable();
- while (1) ;
+ /* Display cpu Pll setting */
+ phid1 = mfspr(SPRN_HID1);
+ seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+
+ /* Display the amount of memory */
+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
}
define_machine(mpc82xx_ads)
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h
b/arch/powerpc/platforms/82xx/pq2ads.h
index 5b5cca6..5056fe5 100644
--- a/arch/powerpc/platforms/82xx/pq2ads.h
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -60,7 +60,6 @@
void m82xx_pci_init_irq(void);
void mpc82xx_ads_show_cpuinfo(struct seq_file*);
-void m82xx_calibrate_decr(void);
#endif /* __MACH_ADS8260_DEFS */
#endif /* __KERNEL__ */
--
1.5.0
^ permalink raw reply related
* Re: [PATCH 2.6.21-rt2] PowerPC: decrementer clockevent driver
From: Gabriel Paubert @ 2007-07-10 10:52 UTC (permalink / raw)
To: Matt Sealey; +Cc: linuxppc-dev, Thomas Gleixner, mingo, linux-kernel
In-Reply-To: <464DD9DD.8030603@genesi-usa.com>
On Fri, May 18, 2007 at 05:52:45PM +0100, Matt Sealey wrote:
> Kumar Gala wrote:
> >
> > On May 18, 2007, at 9:48 AM, Thomas Gleixner wrote:
> >
> >> On Fri, 2007-05-18 at 15:28 +0100, Matt Sealey wrote:
> >>>
> >>> I think both the MPC52xx GPT0-7 and the SLT0-1 fulfil this fairly
> >>> easily.
> >>
> >> There is some basic work for MPC5200 available:
> >>
> >> http://www.pengutronix.de/oselas/bsp/phytec/index_en.html#phyCORE-MPC5200B-tiny
> >>
> >
> > I asked this earlier, but figured you might have a better insight. Is
> > their value in having 'drivers' for more than one clock source? I'd say
> > most (of not all) the PPC SoCs have timers on the system side that we
> > could provide drivers for, I'm just not sure if that does anything for
> > anyone.
>
> As I asked after, I'm also very intrigued as to what is going to end
> up using these timers, but likewise, not much use writing a driver if
> everyone can use the extremely high resolution decrementer all at
> once..
>
> As I said before too, at least Intel has decided there is a great need
> for up to 256 high resolution timer sources on a system, but since this
> is a fairly new concept to Linux (and hrtimers and dynticks too) it
> only seems to be used in the case of i8254/RTC emulation, mostly on
> x86-64.
>
> I'm looking at it now and finding "users" of hrtimers is looking very
> thin on the ground. Maybe it's justified on the basis that more is
> better, and having support is preferable to not having it (even if
> nobody really uses it) but it seems the entire gamut of timing
> possibility in Linux can be handled through a simple, and single,
> high resolution timer and a queue of events..
>
> So do we need some more? :D
>
I don't think so. I really wonder what other capabilities the
other clock sources bring, except more convoluted and complex
code in the end.
There may be one exception to it: scheduled wakeup with
very deep sleep in which you can't even afford the power
dissipated by the processor in the modes in with the
timebase/decrementer keeps running (which is fairly low
to start with). But this would be a special wakeup path
where timebase and decrementer are reinitialized and
become again the main timer source.
Otherwise the decrementer can provide essentially arbitrary
high resolution (i.e., comparable to the time of an external
bus access) on a fairly large number of independent timers.
This scales with the number of processors since there is one
decrementer per core (is it per thread on SMT chips?
I don't know).
<side note>
A few months ago, I implemented here for out internal needs
the equivalent of HRT (I called them FGT for fine-grained timers)
for our VME machines still running a 2.2 kernel. We have boards
who should have generated regular interrupts at programmable
rate interpreting GPS timestamp signals (IRIG B). Unfortunately
the signals were sometimes corrupt and the interrupts were no
more regularly spaced. Now the IRIGB signal is only used to feed
NTP which acts as a low pass filter with an extremely small
cut-off frequency (1mHz or less) and the regular interrupts
are generated from the decrementer in parallel with the standard
ticks. The code is not really polished and would not scale to
a large number of timers but it took me about one day and a half
to write and debug it. I can even monitor it from a /proc file:
[root@vac1 /root]# cat /proc/fgtimer
Calls Lost Name
60865181 158 System timer tick
77889762 0 itFast (128Hz)
There are a few lost ticks for the main system timer because
some operations mask interrupts for too long during early
boot, especially with root on NFS which is the case here,
they never happen after the root file system is mounted.
This is also a somewhat special 2.2 kernel, it essentially has
the timekeeping code I submitted for 2.4 and which is
still the core of PPC timekeeping.
</side note>
Regards,
Gabriel
^ permalink raw reply
* Re: [PATCH] Infinite loop/always true check possible with unsigned counter.
From: Paul Mackerras @ 2007-07-10 10:08 UTC (permalink / raw)
To: Andreas Schwab; +Cc: ppc-dev
In-Reply-To: <jewsx8fuqk.fsf@sykes.suse.de>
Andreas Schwab writes:
> >> ??? There is no rgn->cnt involved in the comparison.
> >
> > Look further down in lmb_add_region; there is a second for loop that
> > does
> >
> > for (i = rgn->cnt-1; i >= 0; i--)
>
> Which is exactly the one quoted above. I still don't see your point.
You're right - my mistake.
Paul.
^ permalink raw reply
* Re: [PATCH] Infinite loop/always true check possible with unsigned counter.
From: Andreas Schwab @ 2007-07-10 9:55 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <18067.22066.466767.663198@cargo.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> Andreas Schwab writes:
>> Paul Mackerras <paulus@samba.org> writes:
>>
>> > Manish Ahuja writes:
>> >
>> >> Repost to fix my email id.
>> >>
>> >> Fix to correct a possible infinite loop or an always true check when the
>> >> unsigned long counter "i" is used in
>> >> lmb_add_region() in the following for loop:
>> >>
>> >> for (i = rgn->cnt-1; i >= 0; i--)
>> >
>> > Unfortunately this won't fix the bug. Since rgn->cnt is unsigned
>> > long, the comparison will be done as an unsigned comparison even if i
>> > is signed.
>>
>> ??? There is no rgn->cnt involved in the comparison.
>
> Look further down in lmb_add_region; there is a second for loop that
> does
>
> for (i = rgn->cnt-1; i >= 0; i--)
Which is exactly the one quoted above. I still don't see your point.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH] Infinite loop/always true check possible with unsigned counter.
From: Paul Mackerras @ 2007-07-10 9:49 UTC (permalink / raw)
To: Andreas Schwab; +Cc: ppc-dev
In-Reply-To: <je1wfgh9qj.fsf@sykes.suse.de>
Andreas Schwab writes:
> Paul Mackerras <paulus@samba.org> writes:
>
> > Manish Ahuja writes:
> >
> >> Repost to fix my email id.
> >>
> >> Fix to correct a possible infinite loop or an always true check when the
> >> unsigned long counter "i" is used in
> >> lmb_add_region() in the following for loop:
> >>
> >> for (i = rgn->cnt-1; i >= 0; i--)
> >
> > Unfortunately this won't fix the bug. Since rgn->cnt is unsigned
> > long, the comparison will be done as an unsigned comparison even if i
> > is signed.
>
> ??? There is no rgn->cnt involved in the comparison.
Look further down in lmb_add_region; there is a second for loop that
does
for (i = rgn->cnt-1; i >= 0; i--)
I agree that Manish's patch description was misleading, but there is
a real problem in there.
Paul.
^ permalink raw reply
* Re: [PATCH] Infinite loop/always true check possible with unsigned counter.
From: Andreas Schwab @ 2007-07-10 9:46 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppc-dev
In-Reply-To: <18066.53384.449544.952545@cargo.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> Manish Ahuja writes:
>
>> Repost to fix my email id.
>>
>> Fix to correct a possible infinite loop or an always true check when the
>> unsigned long counter "i" is used in
>> lmb_add_region() in the following for loop:
>>
>> for (i = rgn->cnt-1; i >= 0; i--)
>
> Unfortunately this won't fix the bug. Since rgn->cnt is unsigned
> long, the comparison will be done as an unsigned comparison even if i
> is signed.
??? There is no rgn->cnt involved in the comparison.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* [PATCH 4/4] Add DMA engine driver for Freescale MPC8xxx processors.
From: Zhang Wei @ 2007-07-10 9:45 UTC (permalink / raw)
To: paulus, galak; +Cc: linuxppc-dev
This driver adopts DMA engine API, which could be used for
MEM<-->MEM, IO_ADDR<-->MEM and IO_ADDR<-->IO_ADDR data transfer.
This driver support both Basic and Extended chain mode of Freescale
MPC8xxx DMA controller.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
drivers/dma/Kconfig | 7 +
drivers/dma/Makefile | 1 +
drivers/dma/fsldma.c | 1074 ++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/dma/fsldma.h | 161 ++++++++
4 files changed, 1243 insertions(+), 0 deletions(-)
create mode 100644 drivers/dma/fsldma.c
create mode 100644 drivers/dma/fsldma.h
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 72be6c6..8102a0b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -32,4 +32,11 @@ config INTEL_IOATDMA
---help---
Enable support for the Intel(R) I/OAT DMA engine.
+config FSL_DMA
+ bool "Freescale MPC8xxx DMA support"
+ depends on DMA_ENGINE && (PPC_86xx || PPC_85xx)
+ ---help---
+ Enable support for the Freescale DMA engine. Now, it support
+ MPC8xxx processors.
+
endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index bdcfdbd..7a28d5c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
obj-$(CONFIG_NET_DMA) += iovlock.o
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
+obj-$(CONFIG_FSL_DMA) += fsldma.o
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
new file mode 100644
index 0000000..f5a2a78
--- /dev/null
+++ b/drivers/dma/fsldma.c
@@ -0,0 +1,1074 @@
+/*
+ * Freescale MPC8xxx DMA Engine support
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ * Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * Description:
+ * DMA engine driver for Freescale MPC8xxx DMA controller, such as MPC85xx,
+ * MPC86xx.
+ *
+ * This 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/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include "fsldma.h"
+
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+
+static LIST_HEAD(reserved_chan_list);
+
+#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common)
+#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
+
+#define FSL_SET_EOSIE(x) (x) = cpu_to_be64(be64_to_cpu(x) | FSL_DMA_EOSIE);
+#define FSL_CLR_EOSIE(x) (x) = cpu_to_be64(be64_to_cpu(x) & ~FSL_DMA_EOSIE);
+#define FSL_SET_EOL(x) (x) = cpu_to_be64(be64_to_cpu(x) | FSL_DMA_EOL);
+#define FSL_CLR_EOL(x) (x) = cpu_to_be64(be64_to_cpu(x) & ~FSL_DMA_EOL);
+
+#define INSERT_LD_RING(fsl_chan, desc, ld, reg) \
+ (desc)->hw.ld.reg = cpu_to_be64( \
+ (uint64_t)to_fsl_desc(list_ring_next( \
+ &(desc)->node, &(fsl_chan)->ld_ring))->phys); \
+ to_fsl_desc(list_ring_prev(&(desc)->node, \
+ &(fsl_chan)->ld_ring))->hw.ld.reg \
+ = cpu_to_be64((uint64_t)desc->phys);
+
+static inline int fsl_dma_idle(struct fsl_dma_chan *fsl_chan)
+{
+ return (((in_be32(&fsl_chan->reg_base->sr) & FSL_DMA_SR_CB) == 0) &&
+ ((in_be32(&fsl_chan->reg_base->mr) & FSL_DMA_MR_CC) == 0));
+}
+
+static inline void fsl_dma_start(struct fsl_dma_chan *fsl_chan)
+{
+ if (fsl_dma_idle(fsl_chan))
+ setbits32(&fsl_chan->reg_base->mr, FSL_DMA_MR_CS);
+}
+
+static inline void fsl_dma_halt(struct fsl_dma_chan *fsl_chan)
+{
+ clrbits32(&fsl_chan->reg_base->mr, FSL_DMA_MR_CS);
+}
+
+static inline struct list_head *list_ring_next(struct list_head *cur,
+ struct list_head *head)
+{
+ return (cur->next == head) ? head->next : cur->next;
+}
+
+static inline struct list_head *list_ring_prev(struct list_head *cur,
+ struct list_head *head)
+{
+ return (cur->prev == head) ? head->prev : cur->prev;
+}
+
+/* Get current list physical address from DMA register */
+static inline dma_addr_t fsl_get_cur_list_pa(struct fsl_dma_chan *fsl_chan)
+{
+ return be64_to_cpu(
+ ((uint64_t)in_be32(&fsl_chan->reg_base->eclsdar) << 32
+ | in_be32(&fsl_chan->reg_base->clsdar))
+ & FSL_DMA_NLDA_MASK);
+}
+
+/* Get current link physical address from DMA register */
+static inline dma_addr_t fsl_get_cur_link_pa(struct fsl_dma_chan *fsl_chan)
+{
+ return be64_to_cpu(
+ ((uint64_t)in_be32(&fsl_chan->reg_base->eclndar) << 32
+ | in_be32(&fsl_chan->reg_base->clndar))
+ & FSL_DMA_NLDA_MASK);
+}
+/**
+ * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
+ *
+ * Return - The descriptor allocated. NULL for failed.
+ */
+static struct fsl_desc_sw *fsl_dma_alloc_descriptor(struct dma_pool *pool,
+ gfp_t flags)
+{
+ dma_addr_t pdesc;
+ struct fsl_desc_sw *desc_sw;
+
+ desc_sw = dma_pool_alloc(pool, flags, &pdesc);
+ if (likely(desc_sw)) {
+ INIT_LIST_HEAD(&desc_sw->link_desc_head);
+ desc_sw->phys = pdesc;
+ desc_sw->cookie = 0;
+ }
+
+ return desc_sw;
+}
+
+#define FSLDMA_LD_INIT_RING_SIZE 64
+
+/**
+ * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
+ *
+ * This function will create a dma pool for descriptor allocation.
+ *
+ * Return - The number of descriptors allocated.
+ */
+static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_desc_sw *desc;
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ int i;
+ LIST_HEAD(tmp_list);
+
+ /* We need the descriptor to be aligned to 32bytes
+ * for meeting FSL DMA specification requirement.
+ */
+ fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
+ fsl_chan->device->dev, sizeof(struct fsl_desc_sw),
+ 32, 0);
+ if (unlikely(!fsl_chan->desc_pool)) {
+ dev_err(fsl_chan->device->dev, "No memory for channel %d "
+ "descriptor dma pool.\n", fsl_chan->id);
+ return 0;
+ }
+
+ /* Allocate list ring, and form the static list ring */
+ for (i = 0; i < FSLDMA_LD_INIT_RING_SIZE; i++) {
+ desc = fsl_dma_alloc_descriptor(fsl_chan->desc_pool,
+ GFP_KERNEL);
+
+ if (unlikely(!desc)) {
+ dev_err(fsl_chan->device->dev,
+ "Only %d initial descriptors\n", i);
+ break;
+ }
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->device->dev, "new LD allocated %p\n", desc);
+#endif
+ list_add_tail(&desc->node, &fsl_chan->ld_ring);
+ /* Insert LD into the ring */
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ INSERT_LD_RING(fsl_chan, desc, list, next_ls_addr);
+ break;
+ case FSL_DMA_BASIC:
+ INSERT_LD_RING(fsl_chan, desc, link, next_ln_addr);
+ break;
+ }
+ }
+
+ return i;
+}
+
+/**
+ * fsl_dma_free_chan_resources - Free all resources of the channel.
+ */
+static void fsl_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ struct fsl_desc_sw *desc, *_desc;
+ struct fsl_desc_sw *linkdesc, *_linkdesc;
+ unsigned long flags;
+
+ dev_dbg(fsl_chan->device->dev, "Free all channel resources.\n");
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_ring, node) {
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->device->dev,
+ "LD %p will be released.\n", desc);
+#endif
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ /* Release link descriptors of list descriptor */
+ list_for_each_entry_safe(linkdesc, _linkdesc,
+ &desc->link_desc_head, node) {
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->device->dev,
+ "link descriptor %p will be "
+ "released.\n", linkdesc);
+#endif
+ list_del(&linkdesc->node);
+ /* free link descriptor */
+ dma_pool_free(fsl_chan->desc_pool, linkdesc,
+ linkdesc->phys);
+ }
+ break;
+ case FSL_DMA_BASIC:
+ break;
+ }
+ list_del(&desc->node);
+ /* free list descritpor */
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->phys);
+ }
+ /* Reset the enque and deque to the head of the ring */
+ fsl_chan->enque = &fsl_chan->ld_ring;
+ fsl_chan->deque = fsl_chan->enque;
+
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dma_pool_destroy(fsl_chan->desc_pool);
+}
+
+/**
+ * do_fsl_dma_memcpy - The DMA core function to assign descriptors
+ * for preparing transfer.
+ *
+ * Return - The DMA transfer cookie.
+ */
+static dma_cookie_t do_fsl_dma_memcpy(struct fsl_dma_chan *fsl_chan,
+ dma_addr_t dest,
+ dma_addr_t src, size_t len,
+ dma_xfer_callback cb, void *data)
+{
+ struct fsl_desc_sw *first = NULL, *prev = NULL, *list, *new;
+ size_t copy;
+ dma_cookie_t cookie;
+ unsigned long flags;
+ struct fsl_dma_device *fdev = fsl_chan->device;
+ int err = 0;
+ LIST_HEAD(link_chain);
+
+ if (unlikely(!fsl_chan || !dest || !src))
+ return -EFAULT;
+
+ if (unlikely(!len))
+ return fsl_chan->common.cookie;
+
+ dev_dbg(fdev->dev, "chan %d memcpy: src = %x, dest = %x, len = %d\n",
+ fsl_chan->id, src, dest, len);
+
+ dev_dbg(fdev->dev, "enque = %p, deque = %p\n",
+ fsl_chan->enque, fsl_chan->deque);
+
+ /* If the desc_ring is empty or there is no free node
+ * in LD ring, we need to add the new node to LD
+ * ring.
+ */
+ if (unlikely(list_empty(&fsl_chan->ld_ring)
+ || (list_ring_prev(fsl_chan->deque, &fsl_chan->ld_ring)
+ == fsl_chan->enque))) {
+ struct fsl_desc_sw *ld;
+
+ dev_dbg(fdev->dev, "no free node in ld_ring, "
+ "new LD will be allocated.\n");
+ /* Allocate the ld descriptor*/
+ ld = fsl_dma_alloc_descriptor(fsl_chan->desc_pool,
+ GFP_ATOMIC);
+
+ if (unlikely(!ld)) {
+ dev_err(fdev->dev, "No free memory for LD.\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ dev_dbg(fdev->dev, "new LD allocated %p\n", ld);
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ /* Stop the DMA */
+ fsl_dma_halt(fsl_chan);
+ /* Insert the ld descriptor to the LD ring */
+ list_add(&ld->node, fsl_chan->enque);
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ INSERT_LD_RING(fsl_chan, ld, list, next_ls_addr);
+ break;
+ case FSL_DMA_BASIC:
+ INSERT_LD_RING(fsl_chan, ld, link, next_ln_addr);
+ break;
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ }
+
+ /* cookie incr and addition to used_list must be atomic */
+ cookie = fsl_chan->common.cookie;
+ cookie++;
+ if (cookie < 0)
+ cookie = 1;
+
+ if (fsl_chan->mode == FSL_DMA_BASIC)
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ do {
+ int alloc_ld = 0;
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ alloc_ld = 1;
+ break;
+ case FSL_DMA_BASIC:
+ alloc_ld = ((list_ring_prev(fsl_chan->deque,
+ &fsl_chan->ld_ring) == fsl_chan->enque));
+ break;
+ }
+ if (alloc_ld) {
+ /* Allocate the link descriptor from DMA pool */
+ new = fsl_dma_alloc_descriptor(fsl_chan->desc_pool,
+ GFP_ATOMIC);
+ if (unlikely(!new)) {
+ if (fsl_chan->mode == FSL_DMA_BASIC)
+ spin_unlock_irqrestore(
+ &fsl_chan->desc_lock, flags);
+ dev_err(fdev->dev,
+ "No free memory for link descriptor\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ dev_dbg(fdev->dev, "new link desc alloc %p\n", new);
+ } else
+ new = to_fsl_desc(list_ring_next(fsl_chan->enque,
+ &fsl_chan->ld_ring));
+
+ copy = min(len, (size_t)FSL_DMA_BCR_MAX_CNT);
+ /* Initialize the link descriptor */
+ new->hw.link.count = cpu_to_be32(copy);
+ new->hw.link.src_addr = cpu_to_be32((uint32_t)src);
+ new->hw.link.dst_addr = cpu_to_be32((uint32_t)dest);
+ /* Read and write with snoop local processor */
+ new->hw.link.src_attr = cpu_to_be32(
+ FSL_DMA_SATR_SREADTYPE_SNOOP_READ |
+ (((uint64_t)src >> 32) & 0x2ff));
+ new->hw.link.dst_attr = cpu_to_be32(
+ FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE
+ | (((uint64_t)dest >> 32) & 0x2ff));
+
+ if (!first)
+ first = new;
+
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ if (prev)
+ prev->hw.link.next_ln_addr = cpu_to_be64(
+ (uint64_t)new->phys);
+ list_add_tail(&new->node, &link_chain);
+ break;
+ case FSL_DMA_BASIC:
+ new->cookie = cookie;
+ if (alloc_ld)
+ INSERT_LD_RING(fsl_chan, new, link,
+ next_ln_addr);
+ FSL_CLR_EOL(new->hw.link.next_ln_addr);
+ FSL_CLR_EOSIE(new->hw.link.next_ln_addr);
+ fsl_chan->enque = list_ring_next(fsl_chan->enque,
+ &fsl_chan->ld_ring);
+ break;
+ }
+
+ prev = new;
+
+ len -= copy;
+ dest += copy;
+ src += copy;
+ } while(len);
+
+ /* Set End-of-link to the last link descriptor */
+ FSL_SET_EOL(new->hw.link.next_ln_addr);
+
+ dev_dbg(fdev->dev, "assign cookie %d\n", cookie);
+ fsl_chan->common.cookie = cookie;
+
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ /* Add the link descriptors to list ring node */
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ /* Link first link address to the list node */
+ list = to_fsl_desc(list_ring_next(fsl_chan->enque,
+ &fsl_chan->ld_ring));
+ dev_dbg(fdev->dev, "list %p, ->phys=%x\n", list, list->phys);
+ dev_dbg(fdev->dev, "first link->phys=%x\n", first->phys);
+
+ list->hw.list.first_ln_addr = cpu_to_be64(
+ (uint64_t)first->phys);
+ list_splice_init(&link_chain, &list->link_desc_head);
+ list->cookie = cookie;
+
+ /* Hook the callback function */
+ if (cb) {
+ list->callback = cb;
+ list->cb_data = data;
+ }
+
+ /* Set End-of-List to the tail of list ring */
+ FSL_SET_EOL(list->hw.list.next_ls_addr);
+
+ /* Clear End-of-List to the previous list node in the ring */
+ FSL_CLR_EOL(to_fsl_desc(fsl_chan->enque)
+ ->hw.list.next_ls_addr);
+ fsl_chan->enque = list_ring_next(fsl_chan->enque,
+ &fsl_chan->ld_ring);
+
+ if (!fsl_get_cur_list_pa(fsl_chan)) {
+ fsl_dma_halt(fsl_chan);
+ out_be32(&fsl_chan->reg_base->clsdar, (uint32_t)
+ to_fsl_desc(list_ring_prev(&list->node,
+ &fsl_chan->ld_ring))
+ ->hw.list.next_ls_addr);
+ out_be32(&fsl_chan->reg_base->eclsdar, (uint32_t)
+ (to_fsl_desc(list_ring_prev(&list->node,
+ &fsl_chan->ld_ring))
+ ->hw.list.next_ls_addr >> 32));
+ dev_dbg(fdev->dev, "set clsdar %08x, eclsdar %08x\n",
+ in_be32(&fsl_chan->reg_base->clsdar),
+ in_be32(&fsl_chan->reg_base->eclsdar));
+ }
+ break;
+ case FSL_DMA_BASIC:
+ /* Hook the callback function to the first link
+ * descriptor of this transfer.
+ */
+ if (cb) {
+ first->callback = cb;
+ first->cb_data = data;
+ }
+
+ /* Enable End-of-segment interrupt for
+ * the last link descriptor.
+ * (the previous node's next link descriptor)
+ */
+ FSL_SET_EOSIE(to_fsl_desc(list_ring_prev(&new->node,
+ &fsl_chan->ld_ring))->hw.link.next_ln_addr);
+
+ /* Clear End-of-Link to the previous link node in the ring */
+ FSL_CLR_EOL(to_fsl_desc(list_ring_prev(&first->node,
+ &fsl_chan->ld_ring))->hw.link.next_ln_addr);
+
+ if (!fsl_get_cur_link_pa(fsl_chan)) {
+ out_be32(&fsl_chan->reg_base->clndar, (uint32_t)
+ to_fsl_desc(list_ring_prev(&first->node,
+ &fsl_chan->ld_ring))
+ ->hw.link.next_ln_addr);
+ out_be32(&fsl_chan->reg_base->eclndar, (uint32_t)
+ (to_fsl_desc(
+ list_ring_prev(&first->node,
+ &fsl_chan->ld_ring))
+ ->hw.link.next_ln_addr >> 32));
+ dev_dbg(fdev->dev, "set clndar %08x, eclndar %08x\n",
+ in_be32(&fsl_chan->reg_base->clndar),
+ in_be32(&fsl_chan->reg_base->eclndar));
+ }
+ break;
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dev_dbg(fdev->dev, "enque updated = %p\n", fsl_chan->enque);
+out:
+ return cookie;
+}
+
+/**
+ * fsl_dma_raw_xfer - The function assigns descriptors for preparing
+ * raw transfer. dest and src both are physical
+ * address.
+ *
+ * Return - The DMA transfer cookie.
+ */
+static inline dma_cookie_t fsl_dma_raw_xfer(struct dma_chan *chan,
+ dma_addr_t dest, dma_addr_t src, size_t len,
+ dma_xfer_callback cb, void *data)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ return do_fsl_dma_memcpy(fsl_chan, dest, src, len, cb, data);
+}
+
+/**
+ * fsl_dma_memcpy_buf_to_buf - The function assigns descriptors
+ * for preparing buffer to buffer transfer.
+ *
+ * Return - The DMA transfer cookie.
+ */
+static dma_cookie_t fsl_dma_memcpy_buf_to_buf(struct dma_chan *chan,
+ void *dest, void *src, size_t len)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_addr_t dest_addr;
+ dma_addr_t src_addr;
+
+ dest_addr = dma_map_single(fsl_chan->device->dev, dest, len,
+ DMA_FROM_DEVICE);
+ src_addr = dma_map_single(fsl_chan->device->dev, src, len,
+ DMA_TO_DEVICE);
+
+ return do_fsl_dma_memcpy(fsl_chan, dest_addr, src_addr, len,
+ NULL, NULL);
+}
+
+/**
+ * fsl_dma_memcpy_buf_to_pg - The function assigns descriptors
+ * for preparing buffer to page transfer.
+ *
+ * Return - The DMA transfer cookie.
+ */
+static dma_cookie_t fsl_dma_memcpy_buf_to_pg(struct dma_chan *chan,
+ struct page *page,
+ unsigned int offset,
+ void *src,
+ size_t len)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_addr_t dest_addr;
+ dma_addr_t src_addr;
+
+ dest_addr = dma_map_page(fsl_chan->device->dev, page, offset, len,
+ DMA_FROM_DEVICE);
+ src_addr = dma_map_single(fsl_chan->device->dev, src, len,
+ DMA_TO_DEVICE);
+
+ return do_fsl_dma_memcpy(fsl_chan, dest_addr, src_addr, len,
+ NULL, NULL);
+}
+
+/**
+ * fsl_dma_memcpy_pg_to_pg - The function assigns descriptors
+ * for preparing page to page transfer.
+ *
+ * Return - The DMA transfer cookie.
+ */
+static dma_cookie_t fsl_dma_memcpy_pg_to_pg(struct dma_chan *chan,
+ struct page *dest_pg,
+ unsigned int dest_off,
+ struct page *src_pg,
+ unsigned int src_off,
+ size_t len)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_addr_t dest_addr;
+ dma_addr_t src_addr;
+
+ dest_addr = dma_map_page(fsl_chan->device->dev, dest_pg, dest_off, len,
+ DMA_FROM_DEVICE);
+ src_addr = dma_map_page(fsl_chan->device->dev, src_pg, src_off, len,
+ DMA_TO_DEVICE);
+
+ return do_fsl_dma_memcpy(fsl_chan, dest_addr, src_addr, len,
+ NULL, NULL);
+}
+
+/**
+ * fsl_dma_memcpy_issue_pending - Issue the DMA start command
+ */
+static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+#ifdef FSL_DMA_LD_DEBUG
+ struct fsl_desc_sw *list, *link;
+ if (fsl_chan->enque == fsl_chan->deque)
+ return;
+ dev_dbg(fsl_chan->device->dev, "--memcpy issue--\n");
+ list_for_each_entry(list, &fsl_chan->ld_ring, node) {
+ int i;
+ dev_dbg(fsl_chan->device->dev, "Ch %d, LD %08x\n",
+ fsl_chan->id, list->phys);
+ for (i = 0; i < 8; i++)
+ dev_dbg(fsl_chan->device->dev,
+ "LD offset %d: %08x\n",
+ i, *(((u32 *)&list->hw) + i));
+ list_for_each_entry(link, &list->link_desc_head, node) {
+ int j;
+ dev_dbg(fsl_chan->device->dev, "link %08x\n",
+ link->phys);
+ for (j = 0; j < 8; j++)
+ dev_dbg(fsl_chan->device->dev,
+ " link offset %d: %08x\n", j,
+ *(((u32 *)&link->hw) + j));
+ dev_dbg(fsl_chan->device->dev, " ----\n");
+ }
+ }
+ dev_dbg(fsl_chan->device->dev, "----------------\n");
+#endif
+
+ /* Start the DMA transfer */
+ if (fsl_chan->enque != fsl_chan->deque)
+ fsl_dma_start(fsl_chan);
+}
+
+/**
+ * fsl_dma_update_completed_cookie - Update the completed cookie.
+ */
+static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan)
+{
+ struct fsl_desc_sw *cur_desc;
+ dma_addr_t ld_phy;
+
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ ld_phy = fsl_get_cur_list_pa(fsl_chan);
+ break;
+ case FSL_DMA_BASIC:
+ ld_phy = fsl_get_cur_link_pa(fsl_chan);
+ break;
+ }
+
+ if (ld_phy) {
+ cur_desc = (struct fsl_desc_sw *)bus_to_virt(ld_phy);
+
+ if (cur_desc->cookie) {
+ if (fsl_dma_idle(fsl_chan))
+ fsl_chan->completed_cookie = cur_desc->cookie;
+ else
+ fsl_chan->completed_cookie = cur_desc->cookie
+ - 1;
+ }
+ }
+}
+
+/**
+ * fsl_dma_is_complete -- Determine the DMA status
+ */
+static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ dma_cookie_t *done,
+ dma_cookie_t *used)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+
+ fsl_dma_update_completed_cookie(fsl_chan);
+
+ last_used = chan->cookie;
+ last_complete = fsl_chan->completed_cookie;
+
+ if (done)
+ *done = last_complete;
+
+ if (used)
+ *used = last_used;
+
+ return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/**
+ * fsl_dma_destroy - Destroy all fsl dma device resources and
+ * close the channel
+ */
+static void fsl_dma_destroy(struct fsl_dma_device *fdev)
+{
+ struct dma_chan *chan, *_chan;
+ if (!fdev)
+ return;
+
+ list_for_each_entry_safe(chan, _chan, &fdev->common.channels,
+ device_node) {
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ out_be32(&fsl_chan->reg_base->mr, 0);
+ free_irq(fsl_chan->irq, fsl_chan);
+ list_del(&chan->device_node);
+ kfree(fsl_chan);
+ }
+ kfree(fdev);
+}
+
+static irqreturn_t fsl_dma_do_interrupt(int irq, void *data)
+{
+ struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+ uint8_t stat;
+ int busy;
+ unsigned long flags;
+ struct fsl_desc_sw *desc, *_desc;
+ int need_dequeue = 0;
+ int end_of_transfer = 0;
+
+ stat = in_be32(&fsl_chan->reg_base->sr);
+ dev_dbg(fsl_chan->device->dev, "event: channel %d, stat = 0x%x\n",
+ fsl_chan->id, stat);
+ if (!stat)
+ return IRQ_NONE;
+ busy = stat & (FSL_DMA_SR_CB);
+ stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
+
+ if (stat & FSL_DMA_SR_EOLNI) {
+ dev_dbg(fsl_chan->device->dev, "event: End-of-link INT\n");
+ stat &= ~FSL_DMA_SR_EOLNI;
+ setbits32(&fsl_chan->reg_base->sr, FSL_DMA_SR_EOLNI);
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ need_dequeue = 1;
+ break;
+ case FSL_DMA_BASIC:
+ end_of_transfer = 1;
+ break;
+ }
+ }
+
+ if (stat & FSL_DMA_SR_EOSI) {
+ dev_dbg(fsl_chan->device->dev, "event: End-of-segments INT\n");
+ dev_dbg(fsl_chan->device->dev, "event: clndar 0x%08x, "
+ "nlndar 0x%08x\n",
+ in_be32(&fsl_chan->reg_base->clndar),
+ in_be32(&fsl_chan->reg_base->nlndar));
+ stat &= ~FSL_DMA_SR_EOSI;
+ setbits32(&fsl_chan->reg_base->sr, FSL_DMA_SR_EOSI);
+ need_dequeue = 1;
+ }
+
+ if (stat & FSL_DMA_SR_EOLSI) {
+ dev_dbg(fsl_chan->device->dev, "event: End-of-list INT\n");
+ stat &= ~FSL_DMA_SR_EOLSI;
+ setbits32(&fsl_chan->reg_base->sr, FSL_DMA_SR_EOLSI);
+ end_of_transfer = 1;
+ }
+
+ /* If the ld descriptor transfer finishes,
+ * we will recycle the used descriptor.
+ */
+ if (need_dequeue) {
+ LIST_HEAD(recy_ln_chain); /* LINK chain for recycle */
+ dev_dbg(fsl_chan->device->dev,
+ "event: enque = %p, deque = %p\n",
+ fsl_chan->enque, fsl_chan->deque);
+
+ fsl_dma_update_completed_cookie(fsl_chan);
+
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ dev_dbg(fsl_chan->device->dev,
+ "event: chan completed_cookie = %d\n",
+ fsl_chan->completed_cookie);
+ for (desc = to_fsl_desc(list_ring_next(fsl_chan->deque,
+ &fsl_chan->ld_ring));
+ (desc->cookie > 0)
+ && (desc->cookie <= fsl_chan->completed_cookie);
+ fsl_chan->deque = &desc->node,
+ desc = to_fsl_desc(list_ring_next(
+ fsl_chan->deque, &fsl_chan->ld_ring))) {
+ dev_dbg(fsl_chan->device->dev,
+ "..cookie %d cleaned\n", desc->cookie);
+ /* Add the link descriptors to recycle chain */
+ list_splice_init(&desc->link_desc_head, &recy_ln_chain);
+
+ /* Run the LD descriptor callback function */
+ if (desc->callback) {
+ spin_unlock_irqrestore(&fsl_chan->desc_lock,
+ flags);
+ desc->callback(&fsl_chan->common,
+ desc->cb_data);
+ desc->callback = NULL;
+ spin_lock_irqsave(&fsl_chan->desc_lock,
+ flags);
+ }
+ desc->cookie = 0;
+ fsl_chan->deque = &desc->node;
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+ /* Now, free all list node from recycle chain */
+ list_for_each_entry_safe(desc, _desc, &recy_ln_chain, node) {
+ /* Recycle it! */
+ dev_dbg(fsl_chan->device->dev,
+ "event: link descriptor %p will be recycle.\n",
+ desc);
+ list_del(&desc->node);
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->phys);
+ }
+ dev_dbg(fsl_chan->device->dev, "event: deque updated = %p\n",
+ fsl_chan->deque);
+ }
+
+ /* If it current transfer is the end-of-transfer,
+ * we should clear the Channel Start bit for
+ * prepare next transfer.
+ */
+ if (end_of_transfer && !busy) {
+ fsl_dma_halt(fsl_chan);
+ /* If there still are some ld descriptors
+ * not transfered in queue. We need start it.
+ */
+ if (fsl_chan->enque != fsl_chan->deque) {
+ dev_dbg(fsl_chan->device->dev,
+ "event: Continue to xfer rest LDs\n");
+ switch (fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ out_be32(&fsl_chan->reg_base->clsdar,
+ in_be32(&fsl_chan->reg_base->nlsdar)
+ & FSL_DMA_NLDA_MASK);
+ out_be32(&fsl_chan->reg_base->eclsdar,
+ in_be32(&fsl_chan->reg_base->enlsdar));
+ break;
+ case FSL_DMA_BASIC:
+ out_be32(&fsl_chan->reg_base->clndar,
+ in_be32(&fsl_chan->reg_base->nlndar)
+ & FSL_DMA_NLDA_MASK);
+ out_be32(&fsl_chan->reg_base->eclndar,
+ in_be32(&fsl_chan->reg_base->enlndar));
+ break;
+ }
+ fsl_dma_start(fsl_chan);
+ } else {
+ out_be32(&fsl_chan->reg_base->clsdar, 0);
+ out_be32(&fsl_chan->reg_base->eclsdar, 0);
+ out_be32(&fsl_chan->reg_base->clndar, 0);
+ out_be32(&fsl_chan->reg_base->eclndar, 0);
+ }
+ }
+
+ if (stat)
+ dev_dbg(fsl_chan->device->dev, "event: unhandled sr 0x%02x\n", stat);
+ out_be32(&fsl_chan->reg_base->sr, stat); /* Clean SR */
+
+ wake_up_interruptible(&fsl_chan->common.wait_q);
+
+ dev_dbg(fsl_chan->device->dev, "event: Exit\n");
+ return IRQ_HANDLED;
+}
+
+static int fsl_dma_self_test(struct fsl_dma_device *fdev)
+{
+ struct dma_chan *chan;
+ struct fsl_dma_chan *fsl_chan;
+ int err = 0;
+ dma_cookie_t cookie;
+ uint8_t src[1024], dest[1024];
+ int i;
+ size_t test_size;
+ DEFINE_WAIT(wait);
+
+ test_size = 1024;
+ for (i = 0; i < test_size; i++) {
+ src[i] = (uint8_t) i;
+ }
+
+ chan = container_of(fdev->common.channels.next,
+ struct dma_chan, device_node);
+ fsl_chan = to_fsl_chan(chan);
+
+ if (fsl_dma_alloc_chan_resources(chan) < 1) {
+ dev_err(fdev->dev,
+ "selftest: Can not alloc resources for DMA\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ cookie =
+ fsl_dma_memcpy_buf_to_buf(chan, dest, src, 4);
+ cookie =
+ fsl_dma_memcpy_buf_to_buf(chan, dest + 4, src + 4,
+ test_size / 2 - 4);
+ fsl_dma_memcpy_issue_pending(chan);
+ cookie =
+ fsl_dma_memcpy_buf_to_buf(chan, dest + test_size / 2,
+ src + test_size / 2, test_size / 2);
+ fsl_dma_memcpy_issue_pending(chan);
+#ifdef TEST_DMA_WAIT_Q
+ prepare_to_wait(&chan->common.wait_q, &wait, TASK_INTERRUPTIBLE);
+ if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS)
+ schedule();
+ finish_wait(&chan->common.wait_q, &wait);
+#else
+ while (fsl_dma_is_complete(chan, cookie, NULL, NULL)
+ != DMA_SUCCESS);
+#endif
+ err = memcmp(src, dest, test_size);
+ if (err) {
+ for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
+ i++);
+ dev_err(fdev->dev, "selftest: Test failed, data %d/%d is "
+ "error! src 0x%x, dest 0x%x\n",
+ i, test_size, *(src + i), *(dest + i));
+ }
+
+ fsl_dma_free_chan_resources(chan);
+
+out:
+ return err;
+}
+
+static struct dma_chan *of_find_dma_chan_by_phandle(phandle phandle)
+{
+ struct device_node *np;
+ struct dma_chan *chan;
+
+ np = of_find_node_by_phandle(phandle);
+ if (np)
+ list_for_each_entry(chan, &reserved_chan_list, device_node)
+ if (to_fsl_chan(chan)->np == np)
+ return chan;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_dma_chan_by_phandle);
+
+static int __devinit of_fsl_dma_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ int err;
+ int i;
+ struct fsl_dma_device *fdev;
+ struct device_node *chnode, *prev;
+ struct resource base;
+
+ fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
+ if (!fdev) {
+ dev_err(&dev->dev, "No enough memory for 'priv'\n");
+ err = -ENOMEM;
+ goto err;
+ }
+ fdev->dev = &dev->dev;
+ INIT_LIST_HEAD(&fdev->common.channels);
+
+ /* get dma controller register base */
+ err = of_address_to_resource(dev->node, 0, &base);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ goto err;
+ }
+
+ dev_info(&dev->dev,
+ "Probe the fsl,mpc8xxx-dma controller at 0x%08x...\n",
+ base.start);
+
+ /* get all channel data from of tree */
+ for (i = 0, chnode = of_get_next_child(dev->node, NULL);
+ chnode;
+ prev = chnode, i++,
+ chnode = of_get_next_child(dev->node, prev)) {
+ struct fsl_dma_chan *new_fsl_chan;
+ struct resource reg;
+ int cplen;
+ const int *extended;
+ const int *reserved;
+
+ /* get dma channel register base */
+ err = of_address_to_resource(chnode, 0, ®);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ chnode->full_name);
+ goto err;
+ }
+
+ /* alloc channel */
+ new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan),
+ GFP_KERNEL);
+ if (!new_fsl_chan) {
+ dev_err(&dev->dev, "No free memory for allocating "
+ "dma channels!\n");
+ err = -ENOMEM;
+ goto err;
+ }
+ new_fsl_chan->np = chnode;
+
+ new_fsl_chan->device = fdev;
+ new_fsl_chan->id = (reg.start - base.end - 1) /
+ sizeof(struct fsl_dma_channel_regs);
+ new_fsl_chan->reg_base = ioremap(reg.start,
+ reg.end - reg.start + 1);
+ reserved = of_get_property(chnode, "reserved", &cplen);
+ extended = of_get_property(chnode, "extended", &cplen);
+ if (extended)
+ new_fsl_chan->mode = FSL_DMA_EXTENDED;
+ else
+ new_fsl_chan->mode = FSL_DMA_BASIC;
+
+ /* Reset the channel */
+ out_be32(&new_fsl_chan->reg_base->mr, 0);
+ /* Set the channel to below modes:
+ * EIE - Error interrupt enable
+ * EOSIE - End of segments interrupt enable (basic mode)
+ * EOLNIE - End of links interrupt enable
+ * EOLSIE - End of lists interrupt enable
+ * XFE - Extended features enable
+ */
+ switch (new_fsl_chan->mode) {
+ case FSL_DMA_EXTENDED:
+ out_be32(&new_fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+ | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOLSIE
+ | FSL_DMA_MR_XFE);
+
+ /* Clear clsdar and eclsdar registers */
+ out_be32(&new_fsl_chan->reg_base->clsdar, 0);
+ out_be32(&new_fsl_chan->reg_base->eclsdar, 0);
+ break;
+ case FSL_DMA_BASIC:
+ out_be32(&new_fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+ | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE);
+
+ /* Clear clndar and eclndar registers */
+ out_be32(&new_fsl_chan->reg_base->clndar, 0);
+ out_be32(&new_fsl_chan->reg_base->eclndar, 0);
+ break;
+ default:
+ err = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_init(&new_fsl_chan->desc_lock);
+ INIT_LIST_HEAD(&new_fsl_chan->ld_ring);
+
+ /* Link the enque and deque to the head of the ring */
+ new_fsl_chan->enque = &new_fsl_chan->ld_ring;
+ new_fsl_chan->deque = new_fsl_chan->enque;
+
+ new_fsl_chan->common.device = &fdev->common;
+ new_fsl_chan->common.client = NULL;
+ init_waitqueue_head(&new_fsl_chan->common.wait_q);
+ /* If this channel is not reserved,
+ * add it to dma device channel list
+ */
+ if (!reserved) {
+ list_add_tail(&new_fsl_chan->common.device_node,
+ &fdev->common.channels);
+ fdev->common.chancnt++;
+ } else
+ list_add_tail(&new_fsl_chan->common.device_node,
+ &reserved_chan_list);
+
+ new_fsl_chan->irq = irq_of_parse_and_map(chnode, 0);
+ err = request_irq(new_fsl_chan->irq, &fsl_dma_do_interrupt,
+ IRQF_SHARED, "fsldma", new_fsl_chan);
+ if (err) {
+ dev_err(&dev->dev, "DMA channel %s request_irq error "
+ "with return %d\n", chnode->full_name, err);
+ goto err;
+ }
+ dev_info(&dev->dev, "Channel #%d (%s), irq %d, %s chain mode\n",
+ i, chnode->name, new_fsl_chan->irq,
+ extended ? "extended" : "basic");
+ if (reserved)
+ dev_info(&dev->dev, " -- reserved\n");
+ of_node_put(chnode);
+ }
+
+ fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
+ fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
+ fdev->common.device_raw_xfer = fsl_dma_raw_xfer;
+ fdev->common.device_memcpy_buf_to_buf = fsl_dma_memcpy_buf_to_buf;
+ fdev->common.device_memcpy_buf_to_pg = fsl_dma_memcpy_buf_to_pg;
+ fdev->common.device_memcpy_pg_to_pg = fsl_dma_memcpy_pg_to_pg;
+ fdev->common.device_memcpy_complete = fsl_dma_is_complete;
+ fdev->common.device_memcpy_issue_pending = fsl_dma_memcpy_issue_pending;
+
+ dev_set_drvdata(&(dev->dev), fdev);
+
+ fsl_dma_self_test(fdev);
+
+ dma_async_device_register(&fdev->common);
+ return 0;
+err:
+ fsl_dma_destroy(fdev);
+ return err;
+}
+
+static struct of_device_id of_fsl_dma_ids[] = {
+ {
+ .compatible = "fsl,mpc8xxx-dma",
+ },
+ {},
+};
+
+static struct of_platform_driver of_fsl_dma_driver = {
+ .name = "of-fsl-dma",
+ .match_table = of_fsl_dma_ids,
+ .probe = of_fsl_dma_probe,
+};
+
+static __init int of_fsl_dma_init(void)
+{
+ return of_register_platform_driver(&of_fsl_dma_driver);
+}
+
+device_initcall(of_fsl_dma_init);
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
new file mode 100644
index 0000000..b6d89bf
--- /dev/null
+++ b/drivers/dma/fsldma.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei <wei.zhang@freescale.com>, Jul 2007
+ * Ebony Zhu <ebony.zhu@freescale.com>, May 2007
+ *
+ * Description:
+ * This file defines data structures needed by Freescale
+ * MPC8xxx DMA controller.
+ *
+ * This 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/device.h>
+#include <linux/dmapool.h>
+#include <linux/dmaengine.h>
+
+#define FSL_DMA_MR_CS 0x00000001
+#define FSL_DMA_MR_CC 0x00000002
+#define FSL_DMA_MR_EIE 0x00000040
+#define FSL_DMA_MR_XFE 0x00000020
+#define FSL_DMA_MR_EOLNIE 0x00000100
+#define FSL_DMA_MR_EOLSIE 0x00000080
+#define FSL_DMA_MR_EOSIE 0x00000200
+#define FSL_DMA_MR_CDSM 0x00000010
+#define FSL_DMA_MR_CTM 0x00000004
+
+#define FSL_DMA_SR_CH 0x00000020
+#define FSL_DMA_SR_CB 0x00000004
+#define FSL_DMA_SR_TE 0x00000080
+#define FSL_DMA_SR_EOSI 0x00000002
+#define FSL_DMA_SR_EOLSI 0x00000001
+#define FSL_DMA_SR_EOLNI 0x00000008
+
+#define FSL_DMA_SATR_SBPATMU 0x20000000
+#define FSL_DMA_SATR_STRANSINT_RIO 0x00c00000
+#define FSL_DMA_SATR_SREADTYPE_SNOOP_READ 0x00050000
+#define FSL_DMA_SATR_SREADTYPE_BP_IORH 0x00020000
+#define FSL_DMA_SATR_SREADTYPE_BP_NREAD 0x00040000
+#define FSL_DMA_SATR_SREADTYPE_BP_MREAD 0x00070000
+
+#define FSL_DMA_DATR_DBPATMU 0x20000000
+#define FSL_DMA_DATR_DTRANSINT_RIO 0x00c00000
+#define FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE 0x00050000
+#define FSL_DMA_DATR_DWRITETYPE_BP_FLUSH 0x00010000
+
+#define FSL_DMA_EOL ((uint64_t)0x1)
+#define FSL_DMA_EOSIE 0x8
+#define FSL_DMA_NLDA_MASK (~(uint64_t)0x1f)
+
+#define FSL_DMA_BCR_MAX_CNT ((2 << 26) - 1)
+
+#define FSL_DMA_DGSR_TE 0x80
+#define FSL_DMA_DGSR_CH 0x20
+#define FSL_DMA_DGSR_PE 0x10
+#define FSL_DMA_DGSR_EOLNI 0x08
+#define FSL_DMA_DGSR_CB 0x04
+#define FSL_DMA_DGSR_EOSI 0x02
+#define FSL_DMA_DGSR_EOLSI 0x01
+
+enum fsl_dma_mode {
+ FSL_DMA_BASIC, /* Basic chain mode,
+ * only support link descriptor
+ */
+ FSL_DMA_EXTENDED /* Extended chain mode,
+ * suport both list and link descriptor
+ */
+};
+
+struct fsl_dma_list_descriptor {
+ __be64 next_ls_addr;
+ __be64 first_ln_addr;
+ __be32 src_stride;
+ __be32 dst_stride;
+ __be32 reserve[2];
+} __attribute__ ((aligned(32)));
+
+struct fsl_dma_link_descriptor {
+ __be32 src_attr;
+ __be32 src_addr;
+ __be32 dst_attr;
+ __be32 dst_addr;
+ __be64 next_ln_addr;
+ __be32 count;
+ __be32 reserve;
+} __attribute__ ((aligned(32)));
+
+struct fsl_desc_sw {
+ union {
+ struct fsl_dma_list_descriptor list;
+ struct fsl_dma_link_descriptor link;
+ } hw;
+ struct list_head node;
+ struct list_head link_desc_head;
+ dma_cookie_t cookie;
+ dma_addr_t phys;
+ void *priv;
+ dma_xfer_callback callback;
+ void *cb_data;
+} __attribute__ ((aligned(32)));
+
+struct fsl_dma_channel_regs {
+ __be32 mr; /* 0x00 - Mode Register */
+ __be32 sr; /* 0x04 - Status Register */
+ __be32 eclndar; /* 0x08 - Current Link Descriptor Extended
+ * Address Register */
+ __be32 clndar; /* 0x0c - Current Link Descriptor
+ * Address Register */
+ __be32 satr; /* 0x10 - Source Attributes Register */
+ __be32 sar; /* 0x14 - Source Address Register */
+ __be32 datr; /* 0x18 - Destination Attributes Register */
+ __be32 dar; /* 0x1c - Destination Address Register */
+ __be32 bcr; /* 0x20 - Byte Count Register */
+ __be32 enlndar; /* 0x24 - Next Link Descriptor Extended
+ * Address Register */
+ __be32 nlndar; /* 0x28 - Next Link Descriptor
+ * Address Register */
+ uint8_t res1[4];
+ __be32 eclsdar; /* 0x30 - Current List Descriptor
+ * Entended Address Register */
+ __be32 clsdar; /* 0x34 - Current List Alternate Base
+ * Descriptor Address Register */
+ __be32 enlsdar; /* 0x38 - Next List Descriptor
+ * Extended Address Register */
+ __be32 nlsdar; /* 0x3c - Next List Descriptor
+ * Address Register */
+ __be32 ssr; /* 0x40 - Source Stride Register */
+ __be32 dsr; /* 0x44 - Destination Stride Register */
+ uint8_t res2[56];
+};
+
+struct fsl_dma_device {
+ struct device *dev;
+ struct dma_device common;
+};
+
+struct fsl_dma_chan {
+ /* The channel register point */
+ volatile struct fsl_dma_channel_regs __iomem *reg_base;
+
+ dma_cookie_t completed_cookie; /* The maximum cookie completed */
+ spinlock_t desc_lock;
+ struct list_head ld_ring; /* List/Link escritpors ring */
+ struct fsl_dma_device *device;
+ struct dma_chan common;
+ struct dma_pool *desc_pool;
+ struct list_head *enque; /* Point to the last
+ * list enqueue node
+ */
+ struct list_head *deque; /* Point to the last
+ * list dequeue node
+ */
+ enum fsl_dma_mode mode;
+ int irq;
+ int id; /* Raw id of this channel */
+ struct device_node *np; /* Device node for OF tree */
+};
--
1.5.1
^ permalink raw reply related
* [PATCH 3/4] Extend the DMA-engine API.
From: Zhang Wei @ 2007-07-10 9:45 UTC (permalink / raw)
To: akpm, paulus, galak; +Cc: linuxppc-dev, linux-kernel
Add channel wait queue and transfer callback dma_xfer_callback().
If the DMA controller and driver support interrupt, when the
transfer is finished, it will wakeup the wait queue
and call the callback function of the channel.
Add dma_async_raw_xfer() to API and device_raw_xfer() to struct dma_device
for RAW physical address DMA transfer, which will be used at transfer
between I/O address and memory address.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
include/linux/dmaengine.h | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c94d8f1..d9dfc57 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -28,6 +28,7 @@
#include <linux/kref.h>
#include <linux/completion.h>
#include <linux/rcupdate.h>
+#include <linux/wait.h>
/**
* enum dma_event - resource PNP/power managment events
@@ -108,6 +109,8 @@ struct dma_chan {
struct list_head client_node;
struct list_head device_node;
struct dma_chan_percpu *local;
+
+ wait_queue_head_t wait_q;
};
void dma_chan_cleanup(struct kref *kref);
@@ -138,6 +141,12 @@ static inline void dma_chan_put(struct dma_chan *chan)
typedef void (*dma_event_callback) (struct dma_client *client,
struct dma_chan *chan, enum dma_event event);
+/*
+ * typedef dma_xfer_callback
+ * - function pointer to a DMA transfer callback when finished
+ */
+typedef void (*dma_xfer_callback) (struct dma_chan *chan, void *data);
+
/**
* struct dma_client - info on the entity making use of DMA services
* @event_callback: func ptr to call when something happens
@@ -187,6 +196,9 @@ struct dma_device {
int (*device_alloc_chan_resources)(struct dma_chan *chan);
void (*device_free_chan_resources)(struct dma_chan *chan);
+ dma_cookie_t (*device_raw_xfer)(struct dma_chan *chan,
+ dma_addr_t dest, dma_addr_t src, size_t len,
+ dma_xfer_callback cb, void *data);
dma_cookie_t (*device_memcpy_buf_to_buf)(struct dma_chan *chan,
void *dest, void *src, size_t len);
dma_cookie_t (*device_memcpy_buf_to_pg)(struct dma_chan *chan,
@@ -209,6 +221,29 @@ void dma_async_client_chan_request(struct dma_client *client,
unsigned int number);
/**
+ * dma_async_raw_xfer - transfor data between physical addresses with callback
+ * @chan: DMA channel to be used
+ * @dest: destination address (physical)
+ * @src: source address (physical)
+ * @len: length
+ */
+static inline dma_cookie_t dma_async_raw_xfer(struct dma_chan *chan,
+ dma_addr_t dest, dma_addr_t src, size_t len,
+ dma_xfer_callback cb, void *data)
+{
+ int cpu = get_cpu();
+ per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
+ per_cpu_ptr(chan->local, cpu)->memcpy_count++;
+ put_cpu();
+
+ if (chan->device->device_raw_xfer)
+ return chan->device->device_raw_xfer(chan, dest, src, len,
+ cb, data);
+ else
+ return -EPERM;
+}
+
+/**
* dma_async_memcpy_buf_to_buf - offloaded copy between virtual addresses
* @chan: DMA channel to offload copy to
* @dest: destination address (virtual)
--
1.5.1
^ permalink raw reply related
* [PATCH 1/4] Add DMA sector to Documentation/powerpc/booting-without-of.txt file.
From: Zhang Wei @ 2007-07-10 9:44 UTC (permalink / raw)
To: paulus, galak; +Cc: linuxppc-dev
In-Reply-To: <1184060662530-git-send-email-wei.zhang@freescale.com>
This patch adds DMA sector to Documentation/powerpc/booting-without-of.txt file.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
Documentation/powerpc/booting-without-of.txt | 60 ++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index c169299..08c619f 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1790,6 +1790,66 @@ platforms are moved over to use the flattened-device-tree model.
partition-names = "fs\0firmware";
};
+ k) DMA
+
+ This sector define DMA for dma-engine driver of Freescale
+ MPC8xxx silicon. For each DMA setor, you should define
+ channels included.
+ Please see below 'l) DMA channel' for DMA channel's definition.
+
+ Required properties:
+
+ - compatible : Should be "fsl,mpc8xxx-dma"
+ - reg : Offset and length of the register set for the device
+ - ranges : Should be defined as specified in 1) to describe the
+ DMA controller's register.
+
+ Example:
+ dma@21000{
+ compatible = "fsl,mpc8xxx-dma";
+ reg = <21000 100>;
+ ranges = <0 21000 1000>;
+ ch0@100{
+ reg = <100 80>;
+ extended;
+ reserved;
+ interrupt-parent = <&mpic>;
+ interrupts = <14 2>;
+ };
+ ch1@180{
+ reg = <180 80>;
+ extended;
+ reserved;
+ interrupt-parent = <&mpic>;
+ interrupts = <15 2>;
+ };
+ ch2@200{
+ reg = <200 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+ ch3@280{
+ reg = <280 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <17 2>;
+ };
+ };
+
+ l) DMA channel
+
+ Required properties:
+
+ - reg : Offset and length of the register set for the device
+
+ Recommended properties :
+
+ - extended : Set the DMA channel to work at extended chain mode.
+ If not set, the DMA channel will work at basic
+ chain mode.
+ - reserved : Reserve the DMA channel to device.
+
More devices will be defined as this spec matures.
VII - Specifying interrupt information for devices
--
1.5.1
^ permalink raw reply related
* [PATCH 2/4] Add dma sector to mpc8641hpcn board dts
From: Zhang Wei @ 2007-07-10 9:44 UTC (permalink / raw)
To: paulus, galak; +Cc: linuxppc-dev
In-Reply-To: <11840606624025-git-send-email-wei.zhang@freescale.com>
This patch add DMA sector to MPC8641HPCN board dts.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Ebony Zhu <ebony.zhu@freescale.com>
---
arch/powerpc/boot/dts/mpc8641_hpcn.dts | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 393cfdf..8a70736 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -405,5 +405,35 @@
device_type = "open-pic";
big-endian;
};
+
+ dma@21000{
+ compatible = "fsl,mpc8xxx-dma";
+ reg = <21000 100>;
+ ranges = <0 21000 1000>;
+ ch0@100{
+ reg = <100 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <14 2>;
+ };
+ ch1@180{
+ reg = <180 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <15 2>;
+ };
+ ch2@200{
+ reg = <200 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+ ch3@280{
+ reg = <280 80>;
+ extended;
+ interrupt-parent = <&mpic>;
+ interrupts = <17 2>;
+ };
+ };
};
};
--
1.5.1
^ permalink raw reply related
* [PATCH 0/4] DMA engine driver for Freescale MPC8xxx processor.
From: Zhang Wei @ 2007-07-10 9:44 UTC (permalink / raw)
To: paulus, galak; +Cc: linuxppc-dev
Hi, All,
These patches are DMA engine driver for Freescale MPC8xxx processor.
They implement the DMA engine API for MEM-2-MEM data DMA transfer
and extend the DMA engine API for IO_ADDR-2-MEM and IO_ADDR-2-IO_ADDR data
transfer.
Patches:
[PATCH 1/4] Add DMA sector to Documentation/powerpc/booting-without-of.txt file.
[PATCH 2/4] Add dma sector to mpc8641hpcn board dts
[PATCH 3/4] Extend the DMA-engine API.
[PATCH 4/4] Add DMA engine driver for Freescale MPC8xxx processors.
Best Regards,
Zhang Wei
^ permalink raw reply
* Re: [patch 0/6] PS3 Storage Drivers for 2.6.23, take 4
From: Jens Axboe @ 2007-07-10 8:32 UTC (permalink / raw)
To: Paul Mackerras
Cc: James E.J. Bottomley, linux-scsi, linux-kernel, Alessandro Rubini,
linuxppc-dev, Geert Uytterhoeven
In-Reply-To: <18067.15564.241168.217875@cargo.ozlabs.ibm.com>
On Tue, Jul 10 2007, Paul Mackerras wrote:
> Jens Axboe writes:
>
> > I have no objections to the block bits, however I feel uneasy merging
> > the full patchset unless patch #1 has been acked by the platform person.
>
> I have the first 3 patches in my queue, so yes I've acked it. It's
> probably easiest if the remaining 3 go through my queue once they've
> been acked - or if you prefer, you can push #4 via your tree once I've
> got Linus to pull my tree. Let me know either way.
If you already have the 3 first patches, just slurp up the rest as well.
No point in making it more complicated than we have to.
--
Jens Axboe
^ permalink raw reply
* Re: [PATCH] xilinxfb: Parameterize xilinxfb platform device registration
From: Andrei Konovalov @ 2007-07-10 8:34 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070709235105.4826.79342.stgit@trillian>
Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch allows multiple xilinxfb devices to be registered and used
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> cc: Andrei Konovalov <akonovalov@ru.mvista.com>
> ---
Looks OK for me.
Thanks,
Andrei
> arch/ppc/syslib/virtex_devices.c | 38 +++++++++++++++++++++++++-------------
> 1 files changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
> index 83f978f..9b473cf 100644
> --- a/arch/ppc/syslib/virtex_devices.c
> +++ b/arch/ppc/syslib/virtex_devices.c
> @@ -152,6 +152,21 @@
> }, \
> }
>
> +/*
> + * ML300/ML403 Video Device: shortcut macro for single instance
> + */
> +#define XPAR_TFT(num) { \
> + .name = "xilinxfb", \
> + .id = num, \
> + .num_resources = 1, \
> + .resource = (struct resource[]) { \
> + { \
> + .start = XPAR_TFT_##num##_BASEADDR, \
> + .end = XPAR_TFT_##num##_BASEADDR+7, \
> + .flags = IORESOURCE_IO, \
> + }, \
> + }, \
> +}
>
> /* UART 8250 driver platform data table */
> struct plat_serial8250_port virtex_serial_platform_data[] = {
> @@ -274,20 +289,17 @@ struct platform_device virtex_platform_devices[] = {
> #endif
> #endif
>
> - /* ML300/403 reference design framebuffer */
> #if defined(XPAR_TFT_0_BASEADDR)
> - {
> - .name = "xilinxfb",
> - .id = 0,
> - .num_resources = 1,
> - .resource = (struct resource[]) {
> - {
> - .start = XPAR_TFT_0_BASEADDR,
> - .end = XPAR_TFT_0_BASEADDR+7,
> - .flags = IORESOURCE_IO,
> - },
> - },
> - },
> + XPAR_TFT(0),
> +#endif
> +#if defined(XPAR_TFT_1_BASEADDR)
> + XPAR_TFT(1),
> +#endif
> +#if defined(XPAR_TFT_2_BASEADDR)
> + XPAR_TFT(2),
> +#endif
> +#if defined(XPAR_TFT_3_BASEADDR)
> + XPAR_TFT(3),
> #endif
> };
>
^ permalink raw reply
* Re: [patch 0/6] PS3 Storage Drivers for 2.6.23, take 4
From: Jens Axboe @ 2007-07-10 7:55 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: James E.J. Bottomley, linux-scsi, Alessandro Rubini, linux-kernel,
linuxppc-dev, Paul Mackerras
In-Reply-To: <Pine.LNX.4.62.0707100944470.22782@pademelon.sonytel.be>
On Tue, Jul 10 2007, Geert Uytterhoeven wrote:
> On Wed, 4 Jul 2007, Geert Uytterhoeven wrote:
> > This is the fourth submission of the new PS3 storage drivers:
> > [1] ps3: Preallocate bootmem memory for the PS3 FLASH ROM storage driver
> > [2] ps3: Storage Driver Core
> > [3] ps3: Storage device registration routines.
> > [4] ps3: Disk Storage Driver
> > [5] ps3: BD/DVD/CD-ROM Storage Driver
> > [6] ps3: FLASH ROM Storage Driver
> >
> > They are based on:
> > - the current Linux kernel source tree,
> > - plus the PS3 patches already submitted by Geoff Levand on linuxppc-dev,
> > - plus the shost_priv() patch in scsi-misc (commit
> > bcd92c9fbcc679ee95003083056f0441a1f474fa).
> >
> > All issues raised during the previous review rounds should be fixed.
> > There were no more comments after the third submission.
> >
> > Paul already integrated Geoff Levand's PS3 patches and the first 3 patches
> > in this series in the for-2.6.23 branch in powerpc.git.
> >
> > Maintainers of block/SCSI/misc, can you please ack the last 3 patches so Paul
> > can take them, too?
>
> Ping block/SCSI/misc maintainers?
I have no objections to the block bits, however I feel uneasy merging
the full patchset unless patch #1 has been acked by the platform person.
--
Jens Axboe
^ permalink raw reply
* Re: [patch 0/6] PS3 Storage Drivers for 2.6.23, take 4
From: Paul Mackerras @ 2007-07-10 8:01 UTC (permalink / raw)
To: Jens Axboe
Cc: James E.J. Bottomley, linux-scsi, Alessandro Rubini, linux-kernel,
linuxppc-dev, Geert Uytterhoeven
In-Reply-To: <20070710075506.GS13902@kernel.dk>
Jens Axboe writes:
> I have no objections to the block bits, however I feel uneasy merging
> the full patchset unless patch #1 has been acked by the platform person.
I have the first 3 patches in my queue, so yes I've acked it. It's
probably easiest if the remaining 3 go through my queue once they've
been acked - or if you prefer, you can push #4 via your tree once I've
got Linus to pull my tree. Let me know either way.
Paul.
^ 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