Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/6] arm/imx6q: add core definitions and low-level debug uart
From: Eric Miao @ 2011-09-19  9:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110919093516.GK31404@pengutronix.de>

On Mon, Sep 19, 2011 at 5:35 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Thu, Sep 15, 2011 at 10:45:22PM +0800, Shawn Guo wrote:
>> It adds the core definitions and low-level debug uart support
>> for imx6q.
>>
>>
>> ?#define UART_VADDR ? IMX_IO_ADDRESS(UART_PADDR)
>> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
>> index 066d464..341f800 100644
>> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
>> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
>> @@ -1,6 +1,6 @@
>> ?/*
>> ? * ?Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
>> - * ?Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
>> + * ?Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
>> ? */
>>
>> ?/*
>> @@ -11,6 +11,17 @@
>>
>> ?#include <mach/hardware.h>
>>
>> +#ifdef CONFIG_ARM_GIC
>> +#include <asm/hardware/entry-macro-gic.S>
>> +
>> + ? ? .macro ?disable_fiq
>> + ? ? .endm
>> +
>> + ? ? .macro ?arch_ret_to_user, tmp1, tmp2
>> + ? ? .endm
>> +
>> +#else
>
> That's the third interrupt entry code handled here with ifdefs. I
> remember there was some infrastructure to have multiple irq
> controllers. I can't find any pointers, but I think Eric (added him
> to Cc) told me about it.
> As this is also the last roadblock to compile i.MX3 and i.MX5 into a
> single kernel this might be the right moment to work on this.

It's CONFIG_MULTIPLE_IRQ_HANDLER. And check arch/arm/mach-pxa/irq.c
for example. Basically to use a C function to handle the interrupts, and
have each machine to specify the correct handler.

E.g. in pxa - there are pxa25x_handle_irq, pxa3xx_handle_irq ...

>
> Sascha
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>

^ permalink raw reply

* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Vinod Koul @ 2011-09-19  9:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5EB3BFCD089AD643B9BB63439F5FD5E9840F3A8D@SHAASIEXM01.ASIA.ROOT.PRI>

On Mon, 2011-09-19 at 09:23 +0000, Barry Song wrote:
> Hi Vinod,
> Thanks!
> 
> > -----Original Message-----
> > From: Vinod Koul [mailto:vinod.koul at intel.com]
> > Sent: 2011?9?19? 17:00
> > To: Barry Song
> > Cc: Arnd Bergmann; Jassi Brar; Linus Walleij; linux-kernel at vger.kernel.org;
> > DL-SHA-WorkGroupLinux; Rongjun Ying; linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
> > 
> > On Fri, 2011-09-16 at 02:56 -0700, Barry Song wrote:
> > > From: Rongjun Ying <rongjun.ying@csr.com>
> > >
> > > Cc: Jassi Brar <jaswinder.singh@linaro.org>
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: Linus Walleij <linus.walleij@linaro.org>
> > > Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> > > Signed-off-by: Barry Song <Baohua.Song@csr.com>
> > > ---
> > >  -v2:
> > >  use generic xfer API from jassi;
> > >  delete sirf self-defined slave config;
> > >  fix feedback from vinod;
> > >  fix filter function: we have two dmac, clients drivers think the chan id as
> > 0~31;
> > >  rename regs to base;
> > >  delete redundant chan_id initialization in probe since dmaengine core will
> > >  re-write it, refer to my patch too:
> > >  [PATCH] dmaengine: delete redundant chan_id and chancnt initialization in
> > dma drivers
> > >  http://www.spinics.net/lists/kernel/msg1237455.html
> > >
> > >  this patch doesn't provide a common way for filter and doesn't use the
> > jassi's v2 patch.
> > > +
> > > +static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
> > > +	struct dma_slave_config *config)
> > > +{
> > > +	u32 addr, direction;
> > > +	unsigned long flags;
> > > +
> > > +	switch (config->direction) {
> > > +	case DMA_FROM_DEVICE:
> > > +		direction = 0;
> > > +		addr = config->dst_addr;
> > > +		break;
> > > +
> > > +	case DMA_TO_DEVICE:
> > > +		direction = 1;
> > > +		addr = config->src_addr;
> > > +		break;
> > > +
> > > +	default:
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
> > > +		(config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
> > > +		return -EINVAL;
> > > +
> > > +	spin_lock_irqsave(&schan->lock, flags);
> > > +	schan->addr = addr;
> > > +	schan->direction = direction;
> > > +	schan->mode = (config->src_maxburst == 4 ? 1 : 0);
> > > +	spin_unlock_irqrestore(&schan->lock, flags);
> > Not sure why you support this, there seem to be no DMA_SLAVE support in
> > this version ate least
> 
> Not. I support dma_slave. But I have no prep_slave_sg function since I can use the gen xfer to replace it.
Yes thats okay...

Then I have questions on genxfer function...
where are you copying either src or dstn_start address, you seem to
completely ignore them?

Do you support only slave transfers or M2M as well for this driver?
If only slave you might want to check if dma_config_slave is set for
this channel or not.

-- 
~Vinod

^ permalink raw reply

* [PATCH v2 2/6] arm/imx6q: add core definitions and low-level debug uart
From: Sascha Hauer @ 2011-09-19  9:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316097926-913-3-git-send-email-shawn.guo@linaro.org>

On Thu, Sep 15, 2011 at 10:45:22PM +0800, Shawn Guo wrote:
> It adds the core definitions and low-level debug uart support
> for imx6q.
> 
>  
>  #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index 066d464..341f800 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -1,6 +1,6 @@
>  /*
>   *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> - *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + *  Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
>   */
>  
>  /*
> @@ -11,6 +11,17 @@
>  
>  #include <mach/hardware.h>
>  
> +#ifdef CONFIG_ARM_GIC
> +#include <asm/hardware/entry-macro-gic.S>
> +
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	arch_ret_to_user, tmp1, tmp2
> +	.endm
> +
> +#else

That's the third interrupt entry code handled here with ifdefs. I
remember there was some infrastructure to have multiple irq
controllers. I can't find any pointers, but I think Eric (added him
to Cc) told me about it.
As this is also the last roadblock to compile i.MX3 and i.MX5 into a
single kernel this might be the right moment to work on this.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH] mmc: sdhci-esdhc-imx: add basic imx6q usdhc support
From: Shawn Guo @ 2011-09-19  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the basic support for imx6q usdhc, which is a
derivative of esdhc controller.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/mmc/host/Kconfig           |    6 +++---
 drivers/mmc/host/sdhci-esdhc-imx.c |   36 ++++++++++++++++++++++++++++++++----
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index c226d54..87d5067 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,13 +130,13 @@ config MMC_SDHCI_CNS3XXX
 	  If unsure, say N.
 
 config MMC_SDHCI_ESDHC_IMX
-	tristate "SDHCI platform support for the Freescale eSDHC i.MX controller"
+	tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
 	depends on ARCH_MXC
 	depends on MMC_SDHCI_PLTFM
 	select MMC_SDHCI_IO_ACCESSORS
 	help
-	  This selects the Freescale eSDHC controller support on the platform
-	  bus, found on i.MX25, i.MX35 and i.MX5x.
+	  This selects the Freescale eSDHC/uSDHC controller support
+	  found on i.MX25, i.MX35 i.MX5x and i.MX6x.
 
 	  If you have a controller with this interface, say Y or M here.
 
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 4557aa1..ae57769 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,7 @@
 /* VENDOR SPEC register */
 #define SDHCI_VENDOR_SPEC		0xC0
 #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK	0x00000002
+#define SDHCI_MIX_CTRL			0x48
 
 /*
  * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
@@ -59,6 +60,7 @@ enum imx_esdhc_type {
 	IMX35_ESDHC,
 	IMX51_ESDHC,
 	IMX53_ESDHC,
+	IMX6Q_USDHC,
 };
 
 struct pltfm_imx_data {
@@ -82,6 +84,9 @@ static struct platform_device_id imx_esdhc_devtype[] = {
 		.name = "sdhci-esdhc-imx53",
 		.driver_data = IMX53_ESDHC,
 	}, {
+		.name = "sdhci-usdhc-imx6q",
+		.driver_data = IMX6Q_USDHC,
+	}, {
 		/* sentinel */
 	}
 };
@@ -92,6 +97,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
 	{ .compatible = "fsl,imx35-esdhc", .data = &imx_esdhc_devtype[IMX35_ESDHC], },
 	{ .compatible = "fsl,imx51-esdhc", .data = &imx_esdhc_devtype[IMX51_ESDHC], },
 	{ .compatible = "fsl,imx53-esdhc", .data = &imx_esdhc_devtype[IMX53_ESDHC], },
+	{ .compatible = "fsl,imx6q-usdhc", .data = &imx_esdhc_devtype[IMX6Q_USDHC], },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -116,6 +122,11 @@ static inline int is_imx53_esdhc(struct pltfm_imx_data *data)
 	return data->devtype == IMX53_ESDHC;
 }
 
+static inline int is_imx6q_usdhc(struct pltfm_imx_data *data)
+{
+	return data->devtype == IMX6Q_USDHC;
+}
+
 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
 {
 	void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -220,8 +231,16 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
 
 static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
 {
-	if (unlikely(reg == SDHCI_HOST_VERSION))
-		reg ^= 2;
+	if (unlikely(reg == SDHCI_HOST_VERSION)) {
+		u16 val = readw(host->ioaddr + (reg ^ 2));
+		/*
+		 * uSDHC supports SDHCI v3.0, but it's encoded as value
+		 * 0x3 in host controller version register, which violates
+		 * SDHCI_SPEC_300 definition.  Work it around here.
+		 */
+		if ((val & SDHCI_SPEC_VER_MASK) == 3)
+			return --val;
+	}
 
 	return readw(host->ioaddr + reg);
 }
@@ -252,8 +271,17 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
 			&& (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
 			val |= SDHCI_CMD_ABORTCMD;
-		writel(val << 16 | imx_data->scratchpad,
-			host->ioaddr + SDHCI_TRANSFER_MODE);
+
+		if (is_imx6q_usdhc(imx_data)) {
+			u32 m = readl(host->ioaddr + SDHCI_MIX_CTRL);
+			m = imx_data->scratchpad | (m & 0xffff0000);
+			writel(m, host->ioaddr + SDHCI_MIX_CTRL);
+			writel(val << 16,
+			       host->ioaddr + SDHCI_TRANSFER_MODE);
+		} else {
+			writel(val << 16 | imx_data->scratchpad,
+			       host->ioaddr + SDHCI_TRANSFER_MODE);
+		}
 		return;
 	case SDHCI_BLOCK_SIZE:
 		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
-- 
1.7.4.1

^ permalink raw reply related

* [RFC PATCH 1/3] genirq: add support for per-cpu dev_id interrupts
From: Marc Zyngier @ 2011-09-19  9:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E767CD6.6090208@codeaurora.org>

On 19/09/11 00:20, Abhijeet Dharmapurikar wrote:
> On 09/15/2011 09:52 AM, Marc Zyngier wrote:
>  > The ARM GIC interrupt controller offers per CPU interrupts (PPIs),
>  > which are usually used to connect local timers to each core.
>  > Each CPU has its own private interface to the GIC,
>  > and only sees the PPIs that are directly connect to it.
>  >
>  > While these timers are separate devices and have a separate
>  > interrupt line to a core, they all use the same IRQ number.
>  >
>  > For these devices, request_irq() is not the right API as it
>  > assumes that an IRQ number is visible by a number of CPUs
>  > (through the affinity setting), but makes it very awkward to
>  > express that an IRQ number can be handled by all CPUs, and
>  > yet be a different interrupt line on each CPU, requiring a
>  > different dev_id cookie to be passed back to the handler.
>  >
>  > The *_percpu_irq() functions is designed to overcome these
>  > limitations, by providing a per-cpu dev_id vector:
>  >
>  > int request_percpu_irq(unsigned int irq, irq_handler_t handler,
>  >                 const char *devname, void __percpu *percpu_dev_id);
>  > void free_percpu_irq(unsigned int, void __percpu *);
>  > int setup_percpu_irq(unsigned int irq, struct irqaction *new);
>  > void remove_percpu_irq(unsigned int irq, struct irqaction *act);
>  > void enable_percpu_irq(unsigned int irq);
>  > void disable_percpu_irq(unsigned int irq);
>  >
>  > The API has a number of limitations:
>  > - no interrupt sharing
>  > - no threading
>  > - common handler across all the CPUs
>  >
>  > Once the interrupt is requested using setup_percpu_irq() or
>  > request_percpu_irq(), it must be enabled by each core that wishes
>  > its local interrupt to be delivered.
>  >
>  > Based on an initial patch by Thomas Gleixner.
>  >
>  > Cc: Thomas Gleixner<tglx@linutronix.de>
>  > Signed-off-by: Marc Zyngier<marc.zyngier@arm.com>
>  > ---
>  >   include/linux/interrupt.h |   40 ++++++---
>  >   include/linux/irq.h       |   25 +++++-
>  >   include/linux/irqdesc.h   |    3 +
>  >   kernel/irq/Kconfig        |    4 +
>  >   kernel/irq/chip.c         |   58 +++++++++++++
>  >   kernel/irq/internals.h    |    2 +
>  >   kernel/irq/manage.c       |  209
> ++++++++++++++++++++++++++++++++++++++++++++-
>  >   kernel/irq/settings.h     |    7 ++
>  >   8 files changed, 332 insertions(+), 16 deletions(-)
>  >
>  > diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
>  > index a103732..f9b7fa3 100644
>  > --- a/include/linux/interrupt.h
>  > +++ b/include/linux/interrupt.h
>  > @@ -95,6 +95,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
>  >    * @flags: flags (see IRQF_* above)
>  >    * @name:  name of the device
>  >    * @dev_id:        cookie to identify the device
>  > + * @percpu_dev_id:  cookie to identify the device
>  >    * @next:  pointer to the next irqaction for shared interrupts
>  >    * @irq:   interrupt number
>  >    * @dir:   pointer to the proc/irq/NN/name entry
>  > @@ -104,17 +105,20 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
>  >    * @thread_mask:   bitmask for keeping track of @thread activity
>  >    */
>  >   struct irqaction {
>  > -    irq_handler_t handler;
>  > -    unsigned long flags;
>  > -    void *dev_id;
>  > -    struct irqaction *next;
>  > -    int irq;
>  > -    irq_handler_t thread_fn;
>  > -    struct task_struct *thread;
>  > -    unsigned long thread_flags;
>  > -    unsigned long thread_mask;
>  > -    const char *name;
>  > -    struct proc_dir_entry *dir;
>  > +    irq_handler_t           handler;
>  > +    unsigned long           flags;
>  > +    void                    *dev_id;
>  > +#ifdef CONFIG_IRQ_PERCPU_DEVID
>  > +    void __percpu           *percpu_dev_id;
>  > +#endif
>  > +    struct irqaction        *next;
>  > +    int                     irq;
>  > +    irq_handler_t           thread_fn;
>  > +    struct task_struct      *thread;
>  > +    unsigned long           thread_flags;
>  > +    unsigned long           thread_mask;
>  > +    const char              *name;
>  > +    struct proc_dir_entry   *dir;
>  >   } ____cacheline_internodealigned_in_smp;
>  >
>  >   extern irqreturn_t no_action(int cpl, void *dev_id);
>  > @@ -136,6 +140,10 @@ extern int __must_check
>  >   request_any_context_irq(unsigned int irq, irq_handler_t handler,
>  >                      unsigned long flags, const char *name, void *dev_id);
>  >
>  > +extern int __must_check
>  > +request_percpu_irq(unsigned int irq, irq_handler_t handler,
>  > +               const char *devname, void __percpu *percpu_dev_id);
>  > +
>  >   extern void exit_irq_thread(void);
>  >   #else
>  >
>  > @@ -164,10 +172,18 @@ request_any_context_irq(unsigned int irq,
> irq_handler_t handler,
>  >      return request_irq(irq, handler, flags, name, dev_id);
>  >   }
>  >
>  > +static inline int __must_check
>  > +request_percpu_irq(unsigned int irq, irq_handler_t handler,
>  > +               const char *devname, void __percpu *percpu_dev_id)
>  > +{
>  > +    return request_irq(irq, handler, 0, name, dev_id);
> 
> you probably meant devname here instead of name and also percpu_dev_id
> instead of dev_id.

Doh. Indeed, thanks for noticing this.

>  > +/*
>  > + * Internal function to unregister a percpu irqaction.
>  > + */
>  > +static struct irqaction *__free_percpu_irq(unsigned int irq, void
> __percpu *dev_id)
>  > +{
>  > +    struct irq_desc *desc = irq_to_desc(irq);
>  > +    struct irqaction *action;
>  > +    unsigned long flags;
>  > +
>  > +    WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
>  > +
>  > +    if (!desc)
>  > +            return NULL;
>  > +
>  > +    raw_spin_lock_irqsave(&desc->lock, flags);
>  > +
>  > +    action = desc->action;
>  > +    if (!action || action->percpu_dev_id != dev_id) {
>  > +            WARN(1, "Trying to free already-free IRQ %d\n", irq);
>  > +            raw_spin_unlock_irqrestore(&desc->lock, flags);
>  > +            return NULL;
>  > +    }
>  > +
>  > +    /* Found it - now remove it from the list of entries: */
>  > +    WARN(!cpumask_empty(desc->percpu_enabled),
>  > +         "percpu IRQ %d still enabled on CPU%d!\n",
>  > +         irq, cpumask_first(desc->percpu_enabled));
>  > +    desc->action = NULL;
>  > +
>  > +#ifdef CONFIG_SMP
>  > +    /* make sure affinity_hint is cleaned up */
>  > +    if (WARN_ON_ONCE(desc->affinity_hint))
>  > +            desc->affinity_hint = NULL;
>  > +#endif
>  > +
>  > +    raw_spin_unlock_irqrestore(&desc->lock, flags);
>  > +
>  > +    unregister_handler_proc(irq, action);
>  > +
>  > +    /* Make sure it's not being used on another CPU: */
>  > +    synchronize_irq(irq);
>  > +
>  > +    module_put(desc->owner);
> 
> Not sure why is this required. Where is the corresponding try_module_get()?

A few lines into __setup_irq().

>  > +/**
>  > + *  request_percpu_irq - allocate a percpu interrupt line
>  > + *  @irq: Interrupt line to allocate
>  > + *  @handler: Function to be called when the IRQ occurs.
>  > + *            Primary handler for threaded interrupts
>  > + *            If NULL and thread_fn != NULL the default
>  > + *            primary handler is installed
> 
> The patch doesnt support threaded percpu interrupts - please set the
> comment accordingly?

Yup, will fix.

>  > + *  @devname: An ascii name for the claiming device
>  > + *  @dev_id: A percpu cookie passed back to the handler function
>  > + *
>  > + *  This call allocates interrupt resources, but doesn't
>  > + *  automatically enable the interrupt. It has to be done on each
>  > + *  CPU using enable_percpu_irq().
>  > + *
>  > + *  Dev_id must be globally unique. It is a per-cpu variable, and
>  > + *  the handler gets called with the interrupted CPU's instance of
>  > + *  that variable.
>  > + */
>  > +int request_percpu_irq(unsigned int irq, irq_handler_t handler,
>  > +                   const char *devname, void __percpu *dev_id)
> 
> Can we add irqflags argument. I think it will be useful to pass flags,
> at least the IRQF_TRIGGER_MASK since it ends up calling __setup_irq().
> The chip could use a set_type callback for ppi's too.

We're entering dangerous territory here. While this would work with the
GIC (the interrupt type is at the distributor level), you could easily
imagine an interrupt controller with the PPI configuration at the CPU
interface level... In that case, calling set_type from __setup_irq()
would end up doing the wrong thing, and I'd hate the API to give the
idea it can do things it may not do in the end...

Furthermore, do we actually have a GIC implementation where PPI
configuration isn't read-only? I only know about the ARM implementation,
and the Qualcomm may well be different (the spec says it's
implementation defined).

Cheers,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [RFC PATCH] ARM: mxc: Select ARCH_HAS_HOLES_MEMORYMODEL
From: Sascha Hauer @ 2011-09-19  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316132981-1104-1-git-send-email-festevam@gmail.com>

On Thu, Sep 15, 2011 at 09:29:41PM -0300, Fabio Estevam wrote:
> Select ARCH_HAS_HOLES_MEMORYMODELfor ARCH_MXC so that the non-contiguous memory block
> can be handled correctly.
> 
> An example of such system is MX35PDK that has a total of 256MB dividedin 
> two RAM banks:128MB at CS0 and another 128MB at CS1. On MX35 each chip select 
> can address up to 256MB, so this configuration leaves a 128MB 'hole' in the 
> memory map that needs to be handled properly.

Why exactly do we need this? I remember a custom i.MX25 board which also
has a memory hole, but I can't remember adding ARCH_HAS_HOLES_MEMORYMODEL
for it.

Sascha

> 
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
>  arch/arm/Kconfig |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 5ebc5d9..29bbd1d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -397,6 +397,7 @@ config ARCH_MXC
>  	select CLKSRC_MMIO
>  	select GENERIC_IRQ_CHIP
>  	select HAVE_SCHED_CLOCK
> +	select ARCH_HAS_HOLES_MEMORYMODEL
>  	help
>  	  Support for Freescale MXC/iMX-based family of processors
>  
> -- 
> 1.6.0.4
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Barry Song @ 2011-09-19  9:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316422774.26662.30.camel@vkoul-udesk3>

Hi Vinod,
Thanks!

> -----Original Message-----
> From: Vinod Koul [mailto:vinod.koul at intel.com]
> Sent: 2011?9?19? 17:00
> To: Barry Song
> Cc: Arnd Bergmann; Jassi Brar; Linus Walleij; linux-kernel at vger.kernel.org;
> DL-SHA-WorkGroupLinux; Rongjun Ying; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
> 
> On Fri, 2011-09-16 at 02:56 -0700, Barry Song wrote:
> > From: Rongjun Ying <rongjun.ying@csr.com>
> >
> > Cc: Jassi Brar <jaswinder.singh@linaro.org>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> > Signed-off-by: Barry Song <Baohua.Song@csr.com>
> > ---
> >  -v2:
> >  use generic xfer API from jassi;
> >  delete sirf self-defined slave config;
> >  fix feedback from vinod;
> >  fix filter function: we have two dmac, clients drivers think the chan id as
> 0~31;
> >  rename regs to base;
> >  delete redundant chan_id initialization in probe since dmaengine core will
> >  re-write it, refer to my patch too:
> >  [PATCH] dmaengine: delete redundant chan_id and chancnt initialization in
> dma drivers
> >  http://www.spinics.net/lists/kernel/msg1237455.html
> >
> >  this patch doesn't provide a common way for filter and doesn't use the
> jassi's v2 patch.
> > +
> > +static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
> > +	struct dma_slave_config *config)
> > +{
> > +	u32 addr, direction;
> > +	unsigned long flags;
> > +
> > +	switch (config->direction) {
> > +	case DMA_FROM_DEVICE:
> > +		direction = 0;
> > +		addr = config->dst_addr;
> > +		break;
> > +
> > +	case DMA_TO_DEVICE:
> > +		direction = 1;
> > +		addr = config->src_addr;
> > +		break;
> > +
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
> > +		(config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
> > +		return -EINVAL;
> > +
> > +	spin_lock_irqsave(&schan->lock, flags);
> > +	schan->addr = addr;
> > +	schan->direction = direction;
> > +	schan->mode = (config->src_maxburst == 4 ? 1 : 0);
> > +	spin_unlock_irqrestore(&schan->lock, flags);
> Not sure why you support this, there seem to be no DMA_SLAVE support in
> this version ate least

Not. I support dma_slave. But I have no prep_slave_sg function since I can use the gen xfer to replace it.

> > +
> > +	return 0;
> > +}
> > +
> > +
> > +
> > +/* Alloc channel resources */
> > +static int sirfsoc_dma_alloc_chan_resources(struct dma_chan *chan)
> > +{
> > +	struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
> > +	struct sirfsoc_dma_chan *schan =
> dma_chan_to_sirfsoc_dma_chan(chan);
> > +	struct sirfsoc_dma_desc *sdesc;
> > +	unsigned long flags;
> > +	LIST_HEAD(descs);
> > +	int i;
> > +
> > +	/* Alloc descriptors for this channel */
> > +	for (i = 0; i < SIRFSOC_DMA_DESCRIPTORS; i++) {
> > +		sdesc = kzalloc(sizeof(struct sirfsoc_dma_desc), GFP_KERNEL);
> kernel convention is kzalloc(sizeof(*sdesc),....)

Ok.
> 
> > +		if (!sdesc) {
> > +			dev_notice(sdma->dma.dev, "Memory allocation error. "
> > +				"Allocated only %u descriptors\n", i);
> > +			break;
> > +		}
> > +
> > +		dma_async_tx_descriptor_init(&sdesc->desc, chan);
> > +		sdesc->desc.flags = DMA_CTRL_ACK;
> > +		sdesc->desc.tx_submit = sirfsoc_dma_tx_submit;
> > +
> > +		list_add_tail(&sdesc->node, &descs);
> > +	}
> > +
> > +	/* Return error only if no descriptors were allocated */
> > +	if (i == 0)
> > +		return -ENOMEM;
> > +
> > +	spin_lock_irqsave(&schan->lock, flags);
> > +
> > +	list_splice_tail_init(&descs, &schan->free);
> > +	spin_unlock_irqrestore(&schan->lock, flags);
> > +
> > +	return 0;
> it should be return i; You are supposed to return the number of desc
> allocated.
> 
Ok.
> 
> > +
> > +/* Check request completion status */
> > +static enum dma_status
> > +sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> > +	struct dma_tx_state *txstate)
> > +{
> > +	struct sirfsoc_dma_chan *schan =
> dma_chan_to_sirfsoc_dma_chan(chan);
> > +	unsigned long flags;
> > +	dma_cookie_t last_used;
> > +	dma_cookie_t last_complete;
> > +
> > +	spin_lock_irqsave(&schan->lock, flags);
> > +	last_used = schan->chan.cookie;
> > +	last_complete = schan->completed_cookie;
> > +	spin_unlock_irqrestore(&schan->lock, flags);
> > +
> > +	dma_set_tx_state(txstate, last_complete, last_used, 0);
> > +	return dma_async_is_complete(cookie, last_complete, last_used);
> > +}
> > +
> > +static struct dma_async_tx_descriptor *sirfsoc_dma_prep_slave_sg(
> > +	struct dma_chan *chan, struct scatterlist *sgl,
> > +	unsigned int sg_len, enum dma_data_direction direction,
> > +	unsigned long flags)
> > +{
> > +	return NULL;
> > +}
> Please remove this until you support it...

Now I am supporting slave by gen xfer. I don't need this function, but a BUG_ON check will cause oops. Jassi would like to delete the BUG_ON check.

         BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
                 !device->device_prep_slave_sg);
> 
> 
> > +}
> > +
> > +/*
> > + * The DMA controller consists of 16 independent DMA channels.
> > + * Each channel is allocated to a different function
> > + */
> > +bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
> > +{
> > +	unsigned int ch_nr = (unsigned int) chan_id;
> > +
> > +	if (ch_nr == chan->chan_id +
> > +		chan->device->dev_id * SIRFSOC_DMA_CHANNELS)
> > +		return true;
> > +
> > +	return false;
> > +}
> > +EXPORT_SYMBOL(sirfsoc_dma_filter_id);
> > +
> > +static int __devinit sirfsoc_dma_probe(struct platform_device *op)
> > +{
> > +	struct device_node *dn = op->dev.of_node;
> > +	struct device *dev = &op->dev;
> > +	struct dma_device *dma;
> > +	struct sirfsoc_dma *sdma;
> > +	struct sirfsoc_dma_chan *schan;
> > +	struct resource res;
> > +	ulong regs_start, regs_size;
> > +	u32 id;
> > +	int retval, i;
> > +
> > +	sdma = devm_kzalloc(dev, sizeof(struct sirfsoc_dma), GFP_KERNEL);
> ditto...

ok. Just copied from mpc, but ignore this :-)

> 
> > +	if (!sdma) {
> > +		dev_err(dev, "Memory exhausted!\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	if (of_property_read_u32(dn, "cell-index", &id)) {
> > +		dev_err(dev, "Fail to get DMAC index\n");
> > +		return -ENODEV;
> kfree(sdma) ??
> 
> > +	}
> > +
> > +	sdma->irq = irq_of_parse_and_map(dn, 0);
> > +	if (sdma->irq == NO_IRQ) {
> > +		dev_err(dev, "Error mapping IRQ!\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	retval = of_address_to_resource(dn, 0, &res);
> > +	if (retval) {
> > +		dev_err(dev, "Error parsing memory region!\n");
> > +		return retval;
> > +	}
> > +
> > +	regs_start = res.start;
> > +	regs_size = resource_size(&res);
> > +
> > +	if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
> > +		dev_err(dev, "Error requesting memory region!\n");
> > +		return -EBUSY;
> > +	}
> > +
> > +	sdma->base = devm_ioremap(dev, regs_start, regs_size);
> > +	if (!sdma->base) {
> > +		dev_err(dev, "Error mapping memory region!\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	retval = devm_request_irq(dev, sdma->irq, &sirfsoc_dma_irq, 0,
> DRV_NAME,
> > +		sdma);
> > +	if (retval) {
> > +		dev_err(dev, "Error requesting IRQ!\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	dma = &sdma->dma;
> > +	dma->dev = dev;
> > +	dma->chancnt = SIRFSOC_DMA_CHANNELS;
> > +
> > +	dma->device_alloc_chan_resources = sirfsoc_dma_alloc_chan_resources;
> > +	dma->device_free_chan_resources = sirfsoc_dma_free_chan_resources;
> > +	dma->device_issue_pending = sirfsoc_dma_issue_pending;
> > +	dma->device_control = sirfsoc_dma_control;
> > +	dma->device_tx_status = sirfsoc_dma_tx_status;
> > +	dma->device_prep_slave_sg = sirfsoc_dma_prep_slave_sg;
> > +	dma->device_prep_dma_genxfer = sirfsoc_dma_prep_genxfer;
> > +
> > +	INIT_LIST_HEAD(&dma->channels);
> > +	dma_cap_set(DMA_SLAVE, dma->cap_mask);
> No you don't support DMA_SLAVE yet.
> 
> 
> > +MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>, "
> > +	"Barry Song <baohua.song@csr.com>");
> > +MODULE_DESCRIPTION("SIRFSOC DMA control driver");
> > +MODULE_LICENSE("GPL");
> Your header says GPLV2 or later, here its GPL only???

Gpl v2 actually

> 
> 
> --
> ~Vinod

-barry



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

^ permalink raw reply

* [PATCH] gpio/mxc: make it work with imx6q
From: Shawn Guo @ 2011-09-19  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

The imx6q is a Cortex-A9 Quad Core SoC, which has GIC as the primary
interrupt controller.  GIC requires gpio irq handler to signal EOI,
otherwise system will hang whenever there is a gpio irq triggered.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/gpio/gpio-mxc.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 4340aca..00b4c9c 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -233,6 +233,9 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 	u32 irq_stat;
 	struct mxc_gpio_port *port = irq_get_handler_data(irq);
 
+	if (desc->irq_data.chip->irq_eoi)
+		desc->irq_data.chip->irq_eoi(&desc->irq_data);
+
 	irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
 
 	mxc_gpio_irq_handler(port, irq_stat);
-- 
1.7.4.1

^ permalink raw reply related

* PLEA: Please fix mach/gpio.h includes (was: Re: [RFC PATCH 2/2] GPIO: add gpiolib and irqchip for CSR SiRFprimaII GPIO controller)
From: Linus Walleij @ 2011-09-19  9:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201108091515.47961.arnd@arndb.de>

On Tuesday 09 August 2011, Barry Song wrote:

> Or do we want to delete the whole arch/arm/mach-xxx/include/mach directory?
>
> If not, it is probably that SoC can still hold some chip-specific APIs
> in arch/arm/mach-xxx/include/mach/yyy.h.

I was actually proposing patches that moved GPIO headers from
<mach/foo-gpio> to <linux/gpio/foo.h> but they were NAK:ed or
frowned upon, so I guess we're keeping the <mach/*> include
union namespace for machine/SoC-specific headers.

Now we just try to make files in this namespace have unqiue
names.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 4/4] net/fec: add imx6q enet support
From: Shawn Guo @ 2011-09-19  9:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110918180912.GA3734@electric-eye.fr.zoreil.com>

On Sun, Sep 18, 2011 at 08:09:12PM +0200, Francois Romieu wrote:
> Shawn Guo <shawn.guo@linaro.org> :
> [...]
> > diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> > index 04206e4..849cb0b 100644
> > --- a/drivers/net/fec.c
> > +++ b/drivers/net/fec.c
> > @@ -442,18 +453,23 @@ fec_restart(struct net_device *ndev, int duplex)
> >  		/* Enable flow control and length check */
> >  		rcntl |= 0x40000000 | 0x00000020;
> >  
> > -		/* MII or RMII */
> > +		/* RGMII, RMII or MII */
> > +		if (fep->phy_interface == PHY_INTERFACE_MODE_RGMII)
> > +			rcntl |= (1 << 6);
> >  		if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
>            ^^^^ missing "else"
> 
Yes, my bad.

> [...]
> > +		/* 1G, 100M or 10M */
> > +		if (fep->phy_dev) {
> > +			if (fep->phy_dev->speed == SPEED_1000)
> > +				ecntl |= (1 << 8);

Right, this is a typo.  It should be (1 << 5);

> > +			else if (fep->phy_dev->speed == SPEED_100)
> > +				rcntl &= ~(1 << 9);
> > +			else
> > +				rcntl |= (1 << 9);
> > +		}
> [...]
> > +	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
> > +		/* enable ENET endian swap */
> > +		ecntl |= (1 << 8);
> 
> I do not understand why the endian swap bit of ecntl needs to be
> set the same in these two different paths, especially as the latter
> handles the old faulty imx28 and the former the newly fixed imx6q.
> Typo ?
> 
Nice catches.  Thanks a lot, Ueimor.

-- 
Regards,
Shawn

^ permalink raw reply

* [RFC v3] arm: Add platform bus driver for memory mapped virtio device
From: Pawel Moll @ 2011-09-19  9:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874o09ryzm.fsf@rustcorp.com.au>

> > Have you written a specification for this device?
> > 
> > Rusty maintains a formal spec for all virtio devices at:
> > 
> > http://ozlabs.org/~rusty/virtio-spec/
> > 
> > The spec should be written before merging the code to make sure that there 
> > aren't future compatibility problems.
> 
> A good idea, but the current spec is for PCI.  I wonder if we should
> move the PCI part out to an appendix and make it more general?
> 
> Meanwhile, perhaps this would be suitable as an appendix.

Yes, that sounds reasonable. I'll work on this during the week, but in
the meantime - does the driver look good enough to ask Peter to invest
his time into QEMU side?

Cheers!

Pawe?

^ permalink raw reply

* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Vinod Koul @ 2011-09-19  8:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316166960-20964-1-git-send-email-Baohua.Song@csr.com>

On Fri, 2011-09-16 at 02:56 -0700, Barry Song wrote:
> From: Rongjun Ying <rongjun.ying@csr.com>
> 
> Cc: Jassi Brar <jaswinder.singh@linaro.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
> ---
>  -v2:
>  use generic xfer API from jassi;
>  delete sirf self-defined slave config;
>  fix feedback from vinod;
>  fix filter function: we have two dmac, clients drivers think the chan id as 0~31;
>  rename regs to base;
>  delete redundant chan_id initialization in probe since dmaengine core will
>  re-write it, refer to my patch too:
>  [PATCH] dmaengine: delete redundant chan_id and chancnt initialization in dma drivers
>  http://www.spinics.net/lists/kernel/msg1237455.html
> 
>  this patch doesn't provide a common way for filter and doesn't use the jassi's v2 patch.
> +
> +static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
> +	struct dma_slave_config *config)
> +{
> +	u32 addr, direction;
> +	unsigned long flags;
> +
> +	switch (config->direction) {
> +	case DMA_FROM_DEVICE:
> +		direction = 0;
> +		addr = config->dst_addr;
> +		break;
> +
> +	case DMA_TO_DEVICE:
> +		direction = 1;
> +		addr = config->src_addr;
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
> +		(config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(&schan->lock, flags);
> +	schan->addr = addr;
> +	schan->direction = direction;
> +	schan->mode = (config->src_maxburst == 4 ? 1 : 0);
> +	spin_unlock_irqrestore(&schan->lock, flags);
Not sure why you support this, there seem to be no DMA_SLAVE support in
this version ate least
> +
> +	return 0;
> +}
> +
> +
> +
> +/* Alloc channel resources */
> +static int sirfsoc_dma_alloc_chan_resources(struct dma_chan *chan)
> +{
> +	struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
> +	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
> +	struct sirfsoc_dma_desc *sdesc;
> +	unsigned long flags;
> +	LIST_HEAD(descs);
> +	int i;
> +
> +	/* Alloc descriptors for this channel */
> +	for (i = 0; i < SIRFSOC_DMA_DESCRIPTORS; i++) {
> +		sdesc = kzalloc(sizeof(struct sirfsoc_dma_desc), GFP_KERNEL);
kernel convention is kzalloc(sizeof(*sdesc),....)

> +		if (!sdesc) {
> +			dev_notice(sdma->dma.dev, "Memory allocation error. "
> +				"Allocated only %u descriptors\n", i);
> +			break;
> +		}
> +
> +		dma_async_tx_descriptor_init(&sdesc->desc, chan);
> +		sdesc->desc.flags = DMA_CTRL_ACK;
> +		sdesc->desc.tx_submit = sirfsoc_dma_tx_submit;
> +
> +		list_add_tail(&sdesc->node, &descs);
> +	}
> +
> +	/* Return error only if no descriptors were allocated */
> +	if (i == 0)
> +		return -ENOMEM;
> +
> +	spin_lock_irqsave(&schan->lock, flags);
> +
> +	list_splice_tail_init(&descs, &schan->free);
> +	spin_unlock_irqrestore(&schan->lock, flags);
> +
> +	return 0;
it should be return i; You are supposed to return the number of desc
allocated.


> +
> +/* Check request completion status */
> +static enum dma_status
> +sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
> +	struct dma_tx_state *txstate)
> +{
> +	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
> +	unsigned long flags;
> +	dma_cookie_t last_used;
> +	dma_cookie_t last_complete;
> +
> +	spin_lock_irqsave(&schan->lock, flags);
> +	last_used = schan->chan.cookie;
> +	last_complete = schan->completed_cookie;
> +	spin_unlock_irqrestore(&schan->lock, flags);
> +
> +	dma_set_tx_state(txstate, last_complete, last_used, 0);
> +	return dma_async_is_complete(cookie, last_complete, last_used);
> +}
> +
> +static struct dma_async_tx_descriptor *sirfsoc_dma_prep_slave_sg(
> +	struct dma_chan *chan, struct scatterlist *sgl,
> +	unsigned int sg_len, enum dma_data_direction direction,
> +	unsigned long flags)
> +{
> +	return NULL;
> +}
Please remove this until you support it...


> +}
> +
> +/*
> + * The DMA controller consists of 16 independent DMA channels.
> + * Each channel is allocated to a different function
> + */
> +bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
> +{
> +	unsigned int ch_nr = (unsigned int) chan_id;
> +
> +	if (ch_nr == chan->chan_id +
> +		chan->device->dev_id * SIRFSOC_DMA_CHANNELS)
> +		return true;
> +
> +	return false;
> +}
> +EXPORT_SYMBOL(sirfsoc_dma_filter_id);
> +
> +static int __devinit sirfsoc_dma_probe(struct platform_device *op)
> +{
> +	struct device_node *dn = op->dev.of_node;
> +	struct device *dev = &op->dev;
> +	struct dma_device *dma;
> +	struct sirfsoc_dma *sdma;
> +	struct sirfsoc_dma_chan *schan;
> +	struct resource res;
> +	ulong regs_start, regs_size;
> +	u32 id;
> +	int retval, i;
> +
> +	sdma = devm_kzalloc(dev, sizeof(struct sirfsoc_dma), GFP_KERNEL);
ditto...

> +	if (!sdma) {
> +		dev_err(dev, "Memory exhausted!\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (of_property_read_u32(dn, "cell-index", &id)) {
> +		dev_err(dev, "Fail to get DMAC index\n");
> +		return -ENODEV;
kfree(sdma) ??

> +	}
> +
> +	sdma->irq = irq_of_parse_and_map(dn, 0);
> +	if (sdma->irq == NO_IRQ) {
> +		dev_err(dev, "Error mapping IRQ!\n");
> +		return -EINVAL;
> +	}
> +
> +	retval = of_address_to_resource(dn, 0, &res);
> +	if (retval) {
> +		dev_err(dev, "Error parsing memory region!\n");
> +		return retval;
> +	}
> +
> +	regs_start = res.start;
> +	regs_size = resource_size(&res);
> +
> +	if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
> +		dev_err(dev, "Error requesting memory region!\n");
> +		return -EBUSY;
> +	}
> +
> +	sdma->base = devm_ioremap(dev, regs_start, regs_size);
> +	if (!sdma->base) {
> +		dev_err(dev, "Error mapping memory region!\n");
> +		return -ENOMEM;
> +	}
> +
> +	retval = devm_request_irq(dev, sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME,
> +		sdma);
> +	if (retval) {
> +		dev_err(dev, "Error requesting IRQ!\n");
> +		return -EINVAL;
> +	}
> +
> +	dma = &sdma->dma;
> +	dma->dev = dev;
> +	dma->chancnt = SIRFSOC_DMA_CHANNELS;
> +
> +	dma->device_alloc_chan_resources = sirfsoc_dma_alloc_chan_resources;
> +	dma->device_free_chan_resources = sirfsoc_dma_free_chan_resources;
> +	dma->device_issue_pending = sirfsoc_dma_issue_pending;
> +	dma->device_control = sirfsoc_dma_control;
> +	dma->device_tx_status = sirfsoc_dma_tx_status;
> +	dma->device_prep_slave_sg = sirfsoc_dma_prep_slave_sg;
> +	dma->device_prep_dma_genxfer = sirfsoc_dma_prep_genxfer;
> +
> +	INIT_LIST_HEAD(&dma->channels);
> +	dma_cap_set(DMA_SLAVE, dma->cap_mask);
No you don't support DMA_SLAVE yet.


> +MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>, "
> +	"Barry Song <baohua.song@csr.com>");
> +MODULE_DESCRIPTION("SIRFSOC DMA control driver");
> +MODULE_LICENSE("GPL");
Your header says GPLV2 or later, here its GPL only???


-- 
~Vinod

^ permalink raw reply

* [PATCH] ARM: supply a DTB file to be appended
From: Linus Walleij @ 2011-09-19  8:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1315476884-28470-1-git-send-email-linus.walleij@stericsson.com>

On Thu, Sep 8, 2011 at 12:14 PM, Linus Walleij
<linus.walleij@stericsson.com> wrote:

> This makes it easy to script the kernel build with
> different device trees, and it also vastly simplifies
> building uImages since "make uImage" will now pick
> up the devcie tree and include it in the final image
> as part of the build process.

A clarification here on what it actually simplifies.

make zImage
cat my.dtb >> arch/arm/boot/zImage
make uImage

Does *not* work.

The reason is that when you issue "make uImage"
the zImage is overwritten due to changed timestamp.
Then a uImage without the DTB is created.

So currently to generate a uImage you have to
do something like:

make zImage
cat my.dtb >> arch/arm/boot/zImage
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000
-n 'Linux-3.0' -d arch/arm/boot/zImage arch/arm/boot/uImage

The patch folds all of this into:

make uImage

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 5/5] ARM: gic: add OF based initialization
From: Cousson, Benoit @ 2011-09-19  8:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110918061526.GE3523@ponder.secretlab.ca>

On 9/18/2011 8:15 AM, Grant Likely wrote:
> On Thu, Sep 15, 2011 at 12:07:25PM +0200, Cousson, Benoit wrote:
>> Hi Rob,
>>
>> On 9/15/2011 9:55 AM, Thomas Abraham wrote:
>>> Hi Rob,
>>>
>>> On 14 September 2011 22:01, Rob Herring<robherring2@gmail.com>   wrote:
>>>> From: Rob Herring<rob.herring@calxeda.com>
>>>>
>>>> This adds gic initialization using device tree data. The initialization
>>>> functions are intended to be called by a generic OF interrupt
>>>> controller parsing function once the right pieces are in place.
>>>>
>>>> PPIs are handled using 3rd cell of interrupts properties to specify the cpu
>>>> mask the PPI is assigned to.
>>>>
>>>> Signed-off-by: Rob Herring<rob.herring@calxeda.com>
>>>> ---
>>>>   Documentation/devicetree/bindings/arm/gic.txt |   53 ++++++++++++++++++++++++
>>>>   arch/arm/common/gic.c                         |   55 +++++++++++++++++++++++--
>>>>   arch/arm/include/asm/hardware/gic.h           |   10 +++++
>>>>   3 files changed, 114 insertions(+), 4 deletions(-)
>>>>   create mode 100644 Documentation/devicetree/bindings/arm/gic.txt
>>>
>>> [...]
>>>
>>>
>>>> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
>>>> index d1ccc72..14de380 100644
>>>> --- a/arch/arm/common/gic.c
>>>> +++ b/arch/arm/common/gic.c
>>>
>>> [...]
>>>
>>>> +void __init gic_of_init(struct device_node *node, struct device_node *parent)
>>>> +{
>>>> +       void __iomem *cpu_base;
>>>> +       void __iomem *dist_base;
>>>> +       int irq;
>>>> +       struct irq_domain *domain =&gic_data[gic_cnt].domain;
>>>> +
>>>> +       if (WARN_ON(!node))
>>>> +               return;
>>>> +
>>>> +       dist_base = of_iomap(node, 0);
>>>> +       WARN(!dist_base, "unable to map gic dist registers\n");
>>>> +
>>>> +       cpu_base = of_iomap(node, 1);
>>>> +       WARN(!cpu_base, "unable to map gic cpu registers\n");
>>>> +
>>>> +       domain->nr_irq = gic_irq_count(dist_base);
>>>> +       domain->irq_base = irq_alloc_descs(-1, 0, domain->nr_irq, numa_node_id());
>>>
>>> For exynos4, all the interrupts originating from GIC are statically
>>> mapped to start from 32 in the linux virq space (GIC SPI interrupts
>>> start from 64). In the above code, since irq_base would be 0 for
>>> exynos4, the interrupt mapping is not working correctly. In your
>>> previous version of the patch, you have given a option to the platform
>>> code to choose the offset. Could that option be added to this series
>>> also. Or a provision to use platform specific translate function
>>> instead of the irq_domain_simple translator.
>>
>> I have another concern on a similar topic.
>>
>> On OMAP4 the SoC interrupts external to the MPU (SPI) have an offset
>> of 32. Only the internal PPI are between 0 and 31.
>>
>> For the moment we add 32 to every SoC interrupts in the irq.h
>> define, but I'm assuming that this offset calculation should be done
>> thanks to a dedicated irq domain for the SPI.
>> The real HW physical number start at 0, and thus this is that value
>> that should be in the irq binding of the device.
>
> Yes.
>
>> So ideally we should have a irq domain for the PPI starting at 0 and
>> another one for the SPI starting at 32. Or 32 and 64 for the exynos4
>> case, but it looks like the PPI/SPI offset is always 32.
>
> Part of the purpose behind irq_domains is to have a translator
> callback that can take care of complex mappings, such as mapping each
> of the GIC irq ranges onto the Linux irq space.  Plus, by being based
> on the DT irq specifiers and dynamically assigning the linux numbers,
> the actual mapping that the kernel chooses to use shouldn't actually
> have any relevance.  So whether or not the driver uses an offset is 32
> becomes an implementation detail.

I do agree, my point was not about the driver usage but about how the 
device node should populate its irq entry. The +32 offset is due to the 
internal implementation of the GIC. That should not be exposed outside 
the MPUSS.

Here are the first IRQs from the OMAP4430 public TRM.

MA_IRQ_0 L2_CACHE_IRQ CORTEXA9 L2 cache controller interrupt
MA_IRQ_1 CTI_IRQ_0 CORTEXA9 Cross-trigger module 0 (CTI0) interrupt
MA_IRQ_2 CTI_IRQ_1 CORTEXA9 Cross-trigger module 1 (CTI1) interrupt
MA_IRQ_3 Reserved Reserved Reserved
MA_IRQ_4 ELM_IRQ ELM Error location process completion
MA_IRQ_5 Reserved Reserved Reserved
MA_IRQ_6 Reserved Reserved Reserved
MA_IRQ_7 sys_nirq1 External External interrupt 1 (active low)
MA_IRQ_8 Reserved Reserved Reserved
MA_IRQ_9 L3_DBG_IRQ L3 L3 interconnect debug error
MA_IRQ_10 L3_APP_IRQ L3 L3 interconnect application error
MA_IRQ_11 PRCM_MPU_IRQ PRCM PRCM interrupt
...

It is a 0 based index, and thus this is the value I'm expecting to enter 
in the irq attribute of the DT node.

Regards,
Benoit

^ permalink raw reply

* [PATCH 36/62] i2c: irq: Remove IRQF_DISABLED
From: Barry Song @ 2011-09-19  8:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1315383059-3673-37-git-send-email-yong.zhang0@gmail.com>

2011/9/7 Yong Zhang <yong.zhang0@gmail.com>:
> This flag is a NOOP and can be removed now.
>
> Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>

Acked-by: Barry Song <21cnbao@gmail.com>

> ---
> ?drivers/i2c/busses/i2c-bfin-twi.c ? | ? ?4 ++--
> ?drivers/i2c/busses/i2c-designware.c | ? ?2 +-
> ?drivers/i2c/busses/i2c-highlander.c | ? ?2 +-
> ?drivers/i2c/busses/i2c-nomadik.c ? ?| ? ?2 +-
> ?drivers/i2c/busses/i2c-nuc900.c ? ? | ? ?2 +-
> ?drivers/i2c/busses/i2c-pmcmsp.c ? ? | ? ?2 +-
> ?drivers/i2c/busses/i2c-s3c2410.c ? ?| ? ?2 +-
> ?drivers/i2c/busses/i2c-sh7760.c ? ? | ? ?2 +-
> ?drivers/i2c/busses/i2c-sh_mobile.c ?| ? ?2 +-
> ?drivers/i2c/busses/i2c-stu300.c ? ? | ? ?2 +-
> ?10 files changed, 11 insertions(+), 11 deletions(-)

^ permalink raw reply

* [PATCH 2/3] at91/gpio: drop PIN_BASE
From: Nicolas Ferre @ 2011-09-19  8:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316285923-12461-2-git-send-email-plagnioj@jcrosoft.com>

Le 17/09/2011 20:58, Jean-Christophe PLAGNIOL-VILLARD :
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  arch/arm/mach-at91/gpio.c              |   54 ++--
>  arch/arm/mach-at91/include/mach/gpio.h |  454 ++++++++++++++++----------------
>  2 files changed, 254 insertions(+), 254 deletions(-)
>  rewrite arch/arm/mach-at91/include/mach/gpio.h (78%)
> 
> diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
> index 04beff1..e709406 100644
> --- a/arch/arm/mach-at91/gpio.c
> +++ b/arch/arm/mach-at91/gpio.c
> @@ -60,18 +60,17 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
>  	}
>  
>  static struct at91_gpio_chip gpio_chip[] = {
> -	AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
> -	AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
> -	AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
> -	AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
> -	AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
> +	AT91_GPIO_CHIP("A", 0x00, 32),
> +	AT91_GPIO_CHIP("B", 0x20, 32),
> +	AT91_GPIO_CHIP("C", 0x40, 32),
> +	AT91_GPIO_CHIP("D", 0x60, 32),
> +	AT91_GPIO_CHIP("E", 0x80, 32),
>  };
>  
>  static int gpio_banks;
>  
>  static inline void __iomem *pin_to_controller(unsigned pin)
>  {
> -	pin -= PIN_BASE;
>  	pin /= 32;
>  	if (likely(pin < gpio_banks))
>  		return gpio_chip[pin].regbase;
> @@ -81,7 +80,6 @@ static inline void __iomem *pin_to_controller(unsigned pin)
>  
>  static inline unsigned pin_to_mask(unsigned pin)
>  {
> -	pin -= PIN_BASE;
>  	return 1 << (pin % 32);
>  }
>  
> @@ -276,8 +274,9 @@ static u32 backups[MAX_GPIO_BANKS];
>  
>  static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
>  {
> -	unsigned	mask = pin_to_mask(d->irq);
> -	unsigned	bank = (d->irq - PIN_BASE) / 32;
> +	unsigned	pin = irq_to_gpio(d->irq);

No, we try to remove the use of this irq_to_gpio() function. So we have
to avoid re-introducing it...

[..]

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH 1/2] ARM: EXYNOS4: Add TVOUT support for SMDKV310
From: Tomasz Stanislawski @ 2011-09-19  8:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1314340747-13816-2-git-send-email-hatim.rv@samsung.com>

Hi Hatim Ali,

On 08/26/2011 08:39 AM, Hatim Ali wrote:
> Add support for TVOUT on SMDKV310 board.
>
> Signed-off-by: Hatim Ali<hatim.rv@samsung.com>
> ---
>   arch/arm/mach-exynos4/Kconfig         |    2 ++
>   arch/arm/mach-exynos4/mach-smdkv310.c |    5 +++++
>   2 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
> index e6925de..4c399c0 100644
> --- a/arch/arm/mach-exynos4/Kconfig
> +++ b/arch/arm/mach-exynos4/Kconfig
> @@ -139,6 +139,7 @@ config MACH_SMDKV310
>   	select S3C_DEV_RTC
>   	select S3C_DEV_WDT
>   	select S3C_DEV_I2C1
> +	select S5P_DEV_I2C_HDMIPHY
>   	select S5P_DEV_MFC
>   	select S3C_DEV_HSMMC
>   	select S3C_DEV_HSMMC1
> @@ -148,6 +149,7 @@ config MACH_SMDKV310
>   	select EXYNOS4_DEV_AHCI
>   	select SAMSUNG_DEV_KEYPAD
>   	select EXYNOS4_DEV_PD
> +	select S5P_DEV_TV
>   	select SAMSUNG_DEV_PWM
>   	select EXYNOS4_DEV_SYSMMU
>   	select EXYNOS4_SETUP_FIMD0
> diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
> index 5f62b2b..8fdba16 100644
> --- a/arch/arm/mach-exynos4/mach-smdkv310.c
> +++ b/arch/arm/mach-exynos4/mach-smdkv310.c
> @@ -173,6 +173,7 @@ static struct platform_device *smdkv310_devices[] __initdata = {
>   	&s3c_device_hsmmc2,
>   	&s3c_device_hsmmc3,
>   	&s3c_device_i2c1,
> +	&s5p_device_i2c_hdmiphy,
>   	&s3c_device_rtc,
>   	&s3c_device_wdt,
>   	&exynos4_device_ac97,
> @@ -194,6 +195,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
>   	&samsung_asoc_idma,
>   	&smdkv310_smsc911x,
>   	&exynos4_device_ahci,
> +	&s5p_device_hdmi,
> +	&s5p_device_mixer,
I should add TV power domain device exynos4_device_pd[PD_TV]  here.
>   };
>
>   static void __init smdkv310_smsc911x_init(void)
> @@ -254,6 +257,8 @@ static void __init smdkv310_machine_init(void)
>   	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
>   	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
>
> +	s5p_i2c_hdmiphy_set_platdata(NULL);
> +
You should set mixer's and hdmi's parents here to device for TV power 
domain.
You should also configure gpio for hot-plug detection. Please refer to 
function s5p_tv_setup
in arch/arm/mach-exynos4/mach-universal_c210.c:1012.
>   	samsung_keypad_set_platdata(&smdkv310_keypad_data);
>
>   	samsung_bl_set(&smdkv310_bl_gpio_info,&smdkv310_bl_data);
I hope you find this information useful.

Best regards,
Tomasz Stanislawski

^ permalink raw reply

* [PATCH v2] arm: omap3evm: Add support for an MT9M032 based camera board.
From: Laurent Pinchart @ 2011-09-19  8:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110919061019.GD9244@neutronstar.dyndns.org>

Hi Martin,

On Monday 19 September 2011 08:10:19 martin at neutronstar.dyndns.org wrote:
> On Sun, Sep 18, 2011 at 11:58:55PM +0200, Laurent Pinchart wrote:
> > On Saturday 17 September 2011 11:34:57 Martin Hostettler wrote:
> > > Adds board support for an MT9M032 based camera to omap3evm.
> > > 
> > > Sigend-off-by: Martin Hostettler <martin@neutronstar.dyndns.org>
> > > ---
> > > 
> > >  arch/arm/mach-omap2/Makefile                |    1 +
> > >  arch/arm/mach-omap2/board-omap3evm-camera.c |  183
> > > 
> > > +++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 0
> > > deletions(-)
> > > 
> > >  create mode 100644 arch/arm/mach-omap2/board-omap3evm-camera.c
> > > 
> > > Changes in V2:
> > >  * ported to current mainline
> > >  * Style fixes
> > >  * Fix error handling
> > > 
> > > diff --git a/arch/arm/mach-omap2/Makefile
> > > b/arch/arm/mach-omap2/Makefile index f343365..8ae3d25 100644
> > > --- a/arch/arm/mach-omap2/Makefile
> > > +++ b/arch/arm/mach-omap2/Makefile
> > > +	return 0;
> > > +
> > > +err_8:
> > > +	gpio_free(EVM_TWL_GPIO_BASE + 8);
> > > +err_2:
> > > +	gpio_free(EVM_TWL_GPIO_BASE + 2);
> > > +err_vdsel:
> > > +	gpio_free(nCAM_VD_SEL);
> > > +err:
> > > +	return ret;
> > > +}
> > > +
> > > +device_initcall(camera_init);
> > 
> > Please don't use device_initcall(), but call the function directly from
> > the OMAP3 EVM init handler. Otherwise camera_init() will be called if
> > OMAP3 EVM support is compiled in the kernel, regardless of the board the
> > kernel runs on.
> 
> Ok, will do.
> In which header should the prototyp of that function go? Or can i just
> add a prototyp to board-omap3evm.c directly?
> I couldn't find anything that looked right, this is rather board specific
> after all.

You can either create arch/arm/mach-omap2/board-omap3evm.h or add the 
prototype to board-omap3evm.c.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Freescale i.mx25 SDIO/Libertas issue
From: albert @ 2011-09-19  7:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <BANLkTi=GSw5HRdiqPB=JcgB9SyEhB1b79A@mail.gmail.com>

> I used this Marvel WiFi 8686 in our previous product powered by i.MX51
> and it worked fine. You need to load the firmware before using it.
> Just put your binaries inside firmware directory on linux kernel and
> setup your kernel config:
> 
>  CONFIG_FW_LOADER=y
>  CONFIG_FIRMWARE_IN_KERNEL=y
> -CONFIG_EXTRA_FIRMWARE=""
> +CONFIG_EXTRA_FIRMWARE="sd8686_helper.bin sd8686.bin"
> +CONFIG_EXTRA_FIRMWARE_DIR="firmware"
> 
> Best Regards,
> 
> Alan
> 

Hi Alan, just a quick question. I am fairly new to all this linux embedded world.
I just wandered what this code you wrote actually does. I searched around and I 
understand that it plugs some extra firmware into the kernel at compiling time, 
however I don't really understand what "firmware" really means in this case. 

I mean, does it mean the driver itself? because I though all you had to do to 
include a driver into the kernel was put the source codes in the "/drivers" 
directory in the kernel's directory and modify a bit the makefile so that it is 
compiled.. is this not right?

Thanks for your time ;)

^ permalink raw reply

* [PATCH 6/6] ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build
From: Thomas Abraham @ 2011-09-19  6:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-6-git-send-email-thomas.abraham@linaro.org>

The pl330 device instances and associated platform data is required only
for non-device-tree builds. With device tree enabled, the data about the
platform is obtained from the device tree. For images that include both
dt and non-dt platforms, an addditional check is added to ensure that
static amba device registrations is applicable to only non-dt platforms.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-exynos4/Kconfig  |   10 ++++++++++
 arch/arm/mach-exynos4/Makefile |    3 ++-
 arch/arm/mach-exynos4/dma.c    |    4 ++++
 3 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index d4d401c..679ba48 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -21,6 +21,11 @@ config EXYNOS4_MCT
 	help
 	  Use MCT (Multi Core Timer) as kernel timers
 
+config EXYNOS4_DEV_DMA
+	bool
+	help
+	  Compile in amba device definitions for DMA controller
+
 config EXYNOS4_DEV_AHCI
 	bool
 	help
@@ -129,6 +134,7 @@ config MACH_SMDKC210
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_SDHCI
+	select EXYNOS4_DEV_DMA
 	help
 	  Machine support for Samsung SMDKC210
 
@@ -153,6 +159,7 @@ config MACH_SMDKV310
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_KEYPAD
 	select EXYNOS4_SETUP_SDHCI
+	select EXYNOS4_DEV_DMA
 	help
 	  Machine support for Samsung SMDKV310
 
@@ -191,6 +198,7 @@ config MACH_UNIVERSAL_C210
 	select EXYNOS4_SETUP_I2C3
 	select EXYNOS4_SETUP_I2C5
 	select EXYNOS4_SETUP_SDHCI
+	select EXYNOS4_DEV_DMA
 	help
 	  Machine support for Samsung Mobile Universal S5PC210 Reference
 	  Board.
@@ -215,6 +223,7 @@ config MACH_NURI
 	select EXYNOS4_SETUP_USB_PHY
 	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_ADC
+	select EXYNOS4_DEV_DMA
 	help
 	  Machine support for Samsung Mobile NURI Board.
 
@@ -222,6 +231,7 @@ config MACH_EXYNOS4_DT
 	bool "Samsung Exynos4 Machine using device tree"
 	select CPU_EXYNOS4210
 	select USE_OF
+	select ARM_AMBA
 	help
 	  Machine support for Samsung Exynos4 machine with device tree enabled.
 
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index d2bf5bf..a2f33dc 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -13,7 +13,8 @@ obj-				:=
 # Core support for EXYNOS4 system
 
 obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o pmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DMA)	+= dma.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index c3c0d17..921d31d 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -24,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl330.h>
+#include <linux/of.h>
 
 #include <asm/irq.h>
 #include <plat/devs.h>
@@ -138,6 +139,9 @@ struct amba_device exynos4_device_pdma1 = {
 
 static int __init exynos4_dma_init(void)
 {
+	if (of_have_populated_dt())
+		return 0;
+
 	dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 5/6] ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
From: Thomas Abraham @ 2011-09-19  6:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-5-git-send-email-thomas.abraham@linaro.org>

A new dma request id 'DMACH_DT_PROP' is introduced for client drivers
requesting a dma channel. This request indicates that a device tree
node property represting the dma channel is available in
'struct samsung_dma_info'. The dma channel request wrapper uses the
node property value as the value for the filter parameter.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/plat-samsung/dma-ops.c                |    9 ++++++++-
 arch/arm/plat-samsung/include/plat/dma-ops.h   |    1 +
 arch/arm/plat-samsung/include/plat/dma-pl330.h |    3 ++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 8d18425..b1135dd 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -23,11 +23,18 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
 	struct dma_slave_config slave_config;
+	void *filter_param;
 
 	dma_cap_zero(mask);
 	dma_cap_set(info->cap, mask);
 
-	chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
+	/*
+	 * If a dma channel property of a device node from device tree is
+	 * specified, use that as the fliter parameter.
+	 */
+	filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
+				(void *)dma_ch;
+	chan = dma_request_channel(mask, pl330_filter, filter_param);
 
 	if (info->direction == DMA_FROM_DEVICE) {
 		memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363..22eafc3 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
 	enum dma_slave_buswidth width;
 	dma_addr_t fifo;
 	struct s3c2410_dma_client *client;
+	struct property *dt_dmach_prop;
 };
 
 struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e59..c5eaad5 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
  * use these just as IDs.
  */
 enum dma_ch {
-	DMACH_UART0_RX,
+	DMACH_DT_PROP = -1,
+	DMACH_UART0_RX = 0,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
 	DMACH_UART1_TX,
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 4/6] DMA: PL330: Add device tree support
From: Thomas Abraham @ 2011-09-19  6:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-4-git-send-email-thomas.abraham@linaro.org>

For PL330 dma controllers instantiated from device tree, the channel
lookup is based on phandle of the dma controller and dma request id
specified by the client node. During probe, the private data of each
channel of the controller is set to point to the device node of the
dma controller. The 'chan_id' of the each channel is used as the
dma request id.

Client driver requesting dma channels specify the phandle of the
dma controller and the request id. The pl330 filter function
converts the phandle to the device node pointer and matches that
with channel's private data. If a match is found, the request id
from the client node and the 'chan_id' of the channel is matched.
A channel is found if both the values match.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 .../devicetree/bindings/dma/arm-pl330.txt          |   30 ++++++++++++++++++
 drivers/dma/pl330.c                                |   33 +++++++++++++++++--
 2 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 0000000..a4cd273
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,30 @@
+* ARM PrimeCell PL330 DMA Controller
+
+The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
+between memory and peripherals or memory to memory.
+
+Required properties:
+  - compatible: should include both "arm,pl330" and "arm,primecell".
+  - reg: physical base address of the controller and length of memory mapped
+    region.
+  - interrupts: interrupt number to the cpu.
+
+Example:
+
+	pdma0: pdma at 12680000 {
+		compatible = "arm,pl330", "arm,primecell";
+		reg = <0x12680000 0x1000>;
+		interrupts = <99>;
+	};
+
+Client drivers (device nodes requiring dma transfers from dev-to-mem or
+mem-to-dev) should specify the DMA channel numbers using a two-value pair
+as shown below.
+
+  [property name]  = <[phandle of the dma controller] [dma request id]>;
+
+      where 'dma request id' is the dma request number which is connected
+      to the client controller. The 'property name' is recommended to be
+      of the form <name>-dma-channel.
+
+  Example:  tx-dma-channel = <&pdma0 12>;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 992bf82..7a4ebf1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
 #include <linux/amba/pl330.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
+#include <linux/of.h>
 
 #define NR_DEFAULT_DESC	16
 
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
+#ifdef CONFIG_OF
+	if (chan->device->dev->of_node) {
+		const __be32 *prop_value;
+		phandle phandle;
+		struct device_node *node;
+
+		prop_value = ((struct property *)param)->value;
+		phandle = be32_to_cpup(prop_value++);
+		node = of_find_node_by_phandle(phandle);
+		return ((chan->private == node) &&
+				(chan->chan_id == be32_to_cpup(prop_value)));
+	}
+#endif
+
 	peri_id = chan->private;
 	return *peri_id == (unsigned)param;
 }
@@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	INIT_LIST_HEAD(&pd->channels);
 
 	/* Initialize channel parameters */
-	num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
+	num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
+			(u8)pi->pcfg.num_chan);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		if (!adev->dev.of_node)
+			pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
+		else
+			pch->chan.private = adev->dev.of_node;
+
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -874,10 +894,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
-	if (pdat)
+	if (pdat) {
 		pd->cap_mask = pdat->cap_mask;
-	else
+	} else {
 		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
+		if (pi->pcfg.num_peri) {
+			dma_cap_set(DMA_SLAVE, pd->cap_mask);
+			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+		}
+	}
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 3/6] ARM: EXYNOS4: Modify platform data for pl330 driver
From: Thomas Abraham @ 2011-09-19  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-3-git-send-email-thomas.abraham@linaro.org>

With the 'struct dma_pl330_peri' removed, the platfrom data for dma
driver can be simplified to a simple list of peripheral request ids.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-exynos4/dma.c |  223 ++++++++++++-------------------------------
 1 files changed, 62 insertions(+), 161 deletions(-)

diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
index 9667c61..c3c0d17 100644
--- a/arch/arm/mach-exynos4/dma.c
+++ b/arch/arm/mach-exynos4/dma.c
@@ -35,95 +35,40 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-struct dma_pl330_peri pdma0_peri[28] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ0,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ2,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS2_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS4_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_AC97_MICIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMIN,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_AC97_PCMOUT,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma0_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM2_RX,
+	DMACH_PCM2_TX,
+	DMACH_MSM_REQ0,
+	DMACH_MSM_REQ2,
+	DMACH_SPI0_RX,
+	DMACH_SPI0_TX,
+	DMACH_SPI2_RX,
+	DMACH_SPI2_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART2_RX,
+	DMACH_UART2_TX,
+	DMACH_UART4_RX,
+	DMACH_UART4_TX,
+	DMACH_SLIMBUS0_RX,
+	DMACH_SLIMBUS0_TX,
+	DMACH_SLIMBUS2_RX,
+	DMACH_SLIMBUS2_TX,
+	DMACH_SLIMBUS4_RX,
+	DMACH_SLIMBUS4_TX,
+	DMACH_AC97_MICIN,
+	DMACH_AC97_PCMIN,
+	DMACH_AC97_PCMOUT,
 };
 
 struct dma_pl330_platdata exynos4_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
-	.peri = pdma0_peri,
+	.peri_id = pdma0_peri,
 };
 
 struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +87,37 @@ struct amba_device exynos4_device_pdma0 = {
 	.periphid = 0x00041330,
 };
 
-struct dma_pl330_peri pdma1_peri[25] = {
-	{
-		.peri_id = (u8)DMACH_PCM0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_PCM1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ1,
-	}, {
-		.peri_id = (u8)DMACH_MSM_REQ3,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SPI1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0S_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_I2S1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART0_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART0_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_UART3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_UART3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS1_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS3_TX,
-		.rqtype = MEMTODEV,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_RX,
-		.rqtype = DEVTOMEM,
-	}, {
-		.peri_id = (u8)DMACH_SLIMBUS5_TX,
-		.rqtype = MEMTODEV,
-	},
+u8 pdma1_peri[] = {
+	DMACH_PCM0_RX,
+	DMACH_PCM0_TX,
+	DMACH_PCM1_RX,
+	DMACH_PCM1_TX,
+	DMACH_MSM_REQ1,
+	DMACH_MSM_REQ3,
+	DMACH_SPI1_RX,
+	DMACH_SPI1_TX,
+	DMACH_I2S0S_TX,
+	DMACH_I2S0_RX,
+	DMACH_I2S0_TX,
+	DMACH_I2S1_RX,
+	DMACH_I2S1_TX,
+	DMACH_UART0_RX,
+	DMACH_UART0_TX,
+	DMACH_UART1_RX,
+	DMACH_UART1_TX,
+	DMACH_UART3_RX,
+	DMACH_UART3_TX,
+	DMACH_SLIMBUS1_RX,
+	DMACH_SLIMBUS1_TX,
+	DMACH_SLIMBUS3_RX,
+	DMACH_SLIMBUS3_TX,
+	DMACH_SLIMBUS5_RX,
+	DMACH_SLIMBUS5_TX,
 };
 
 struct dma_pl330_platdata exynos4_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
-	.peri = pdma1_peri,
+	.peri_id = pdma1_peri,
 };
 
 struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +138,12 @@ struct amba_device exynos4_device_pdma1 = {
 
 static int __init exynos4_dma_init(void)
 {
+	dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+
+	dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
+	dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
 	amba_device_register(&exynos4_device_pdma1, &iomem_resource);
 
 	return 0;
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 2/6] DMA: PL330: Infer transfer direction from transfer request instead of platform data
From: Thomas Abraham @ 2011-09-19  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-2-git-send-email-thomas.abraham@linaro.org>

The transfer direction for a channel can be inferred from the transfer
request and the need for specifying transfer direction in platfrom data
can be eliminated. So the structure definition 'struct dma_pl330_peri'
is no longer required.

The channel's private data is set to point to a channel id specified in
the platform data (instead of an instance of type 'struct dma_pl330_peri').
The filter function is correspondingly modified to match the channel id.

With the 'struct dma_pl330_peri' removed from platform data, the dma
controller transfer capabilities cannot be inferred any more. Hence,
the dma controller capabilities is specified using platform data.

Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Boojin Kim <boojin.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 drivers/dma/pl330.c        |   65 +++++++++++---------------------------------
 include/linux/amba/pl330.h |   13 ++-------
 2 files changed, 19 insertions(+), 59 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 5f1d24c..992bf82 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 
 bool pl330_filter(struct dma_chan *chan, void *param)
 {
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
 
 	if (chan->device->dev->driver != &pl330_driver.drv)
 		return false;
 
-	peri = chan->private;
-	return peri->peri_id == (unsigned)param;
+	peri_id = chan->private;
+	return *peri_id == (unsigned)param;
 }
 EXPORT_SYMBOL(pl330_filter);
 
@@ -512,7 +512,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
 static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 {
 	struct dma_pl330_dmac *pdmac = pch->dmac;
-	struct dma_pl330_peri *peri = pch->chan.private;
+	u8 *peri_id = pch->chan.private;
 	struct dma_pl330_desc *desc;
 
 	/* Pluck one desc from the pool of DMAC */
@@ -537,13 +537,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
 	desc->txd.cookie = 0;
 	async_tx_ack(&desc->txd);
 
-	if (peri) {
-		desc->req.rqtype = peri->rqtype;
-		desc->req.peri = pch->chan.chan_id;
-	} else {
-		desc->req.rqtype = MEMTOMEM;
-		desc->req.peri = 0;
-	}
+	desc->req.peri = peri_id ? pch->chan.chan_id : 0;
 
 	dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
@@ -630,12 +624,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 	case DMA_TO_DEVICE:
 		desc->rqcfg.src_inc = 1;
 		desc->rqcfg.dst_inc = 0;
+		desc->req.rqtype = MEMTODEV;
 		src = dma_addr;
 		dst = pch->fifo_addr;
 		break;
 	case DMA_FROM_DEVICE:
 		desc->rqcfg.src_inc = 0;
 		desc->rqcfg.dst_inc = 1;
+		desc->req.rqtype = DEVTOMEM;
 		src = pch->fifo_addr;
 		dst = dma_addr;
 		break;
@@ -661,16 +657,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 {
 	struct dma_pl330_desc *desc;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct pl330_info *pi;
 	int burst;
 
 	if (unlikely(!pch || !len))
 		return NULL;
 
-	if (peri && peri->rqtype != MEMTOMEM)
-		return NULL;
-
 	pi = &pch->dmac->pif;
 
 	desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -679,6 +671,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
 
 	desc->rqcfg.src_inc = 1;
 	desc->rqcfg.dst_inc = 1;
+	desc->req.rqtype = MEMTOMEM;
 
 	/* Select max possible burst size */
 	burst = pi->pcfg.data_bus_width / 8;
@@ -707,24 +700,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 {
 	struct dma_pl330_desc *first, *desc = NULL;
 	struct dma_pl330_chan *pch = to_pchan(chan);
-	struct dma_pl330_peri *peri = chan->private;
 	struct scatterlist *sg;
 	unsigned long flags;
 	int i;
 	dma_addr_t addr;
 
-	if (unlikely(!pch || !sgl || !sg_len || !peri))
-		return NULL;
-
-	/* Make sure the direction is consistent */
-	if ((direction == DMA_TO_DEVICE &&
-				peri->rqtype != MEMTODEV) ||
-			(direction == DMA_FROM_DEVICE &&
-				peri->rqtype != DEVTOMEM)) {
-		dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
-				__func__, __LINE__);
+	if (unlikely(!pch || !sgl || !sg_len))
 		return NULL;
-	}
 
 	addr = pch->fifo_addr;
 
@@ -765,11 +747,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		if (direction == DMA_TO_DEVICE) {
 			desc->rqcfg.src_inc = 1;
 			desc->rqcfg.dst_inc = 0;
+			desc->req.rqtype = MEMTODEV;
 			fill_px(&desc->px,
 				addr, sg_dma_address(sg), sg_dma_len(sg));
 		} else {
 			desc->rqcfg.src_inc = 0;
 			desc->rqcfg.dst_inc = 1;
+			desc->req.rqtype = DEVTOMEM;
 			fill_px(&desc->px,
 				sg_dma_address(sg), addr, sg_dma_len(sg));
 		}
@@ -876,28 +860,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
-		if (pdat) {
-			struct dma_pl330_peri *peri = &pdat->peri[i];
-
-			switch (peri->rqtype) {
-			case MEMTOMEM:
-				dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-				break;
-			case MEMTODEV:
-			case DEVTOMEM:
-				dma_cap_set(DMA_SLAVE, pd->cap_mask);
-				dma_cap_set(DMA_CYCLIC, pd->cap_mask);
-				break;
-			default:
-				dev_err(&adev->dev, "DEVTODEV Not Supported\n");
-				continue;
-			}
-			pch->chan.private = peri;
-		} else {
-			dma_cap_set(DMA_MEMCPY, pd->cap_mask);
-			pch->chan.private = NULL;
-		}
-
+		pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
 		INIT_LIST_HEAD(&pch->work_list);
 		spin_lock_init(&pch->lock);
 		pch->pl330_chid = NULL;
@@ -911,6 +874,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	pd->dev = &adev->dev;
+	if (pdat)
+		pd->cap_mask = pdat->cap_mask;
+	else
+		dma_cap_set(DMA_MEMCPY, pd->cap_mask);
 
 	pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
 	pd->device_free_chan_resources = pl330_free_chan_resources;
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index 6db72da..12e023c 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -15,15 +15,6 @@
 #include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
-struct dma_pl330_peri {
-	/*
-	 * Peri_Req i/f of the DMAC that is
-	 * peripheral could be reached from.
-	 */
-	u8 peri_id; /* specific dma id */
-	enum pl330_reqtype rqtype;
-};
-
 struct dma_pl330_platdata {
 	/*
 	 * Number of valid peripherals connected to DMAC.
@@ -34,7 +25,9 @@ struct dma_pl330_platdata {
 	 */
 	u8 nr_valid_peri;
 	/* Array of valid peripherals */
-	struct dma_pl330_peri *peri;
+	u8 *peri_id;
+	/* Operational capabilities */
+	dma_cap_mask_t cap_mask;
 	/* Bytes to allocate for MC buffer */
 	unsigned mcbuf_sz;
 };
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 1/6] DMA: PL330: move filter function into driver
From: Thomas Abraham @ 2011-09-19  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316413742-23535-1-git-send-email-thomas.abraham@linaro.org>

The dma channel selection filter function is moved from plat-samsung
into the pl330 driver. In additon to that, a check is added in the
filter function to ensure that the channel on which the filter has
been invoked is pl330 channel instance (and avoid any incorrect
access of chan->private in a system with multiple types of DMA
drivers).

Suggested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/plat-samsung/dma-ops.c |    6 ------
 drivers/dma/pl330.c             |   15 +++++++++++++++
 include/linux/amba/pl330.h      |    2 ++
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 6e3d9ab..8d18425 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -17,12 +17,6 @@
 
 #include <mach/dma.h>
 
-static inline bool pl330_filter(struct dma_chan *chan, void *param)
-{
-	struct dma_pl330_peri *peri = chan->private;
-	return peri->peri_id == (unsigned)param;
-}
-
 static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
 				struct samsung_dma_info *info)
 {
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 621134f..5f1d24c 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -116,6 +116,9 @@ struct dma_pl330_desc {
 	struct dma_pl330_chan *pchan;
 };
 
+/* forward declaration */
+static struct amba_driver pl330_driver;
+
 static inline struct dma_pl330_chan *
 to_pchan(struct dma_chan *ch)
 {
@@ -267,6 +270,18 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
 	tasklet_schedule(&pch->task);
 }
 
+bool pl330_filter(struct dma_chan *chan, void *param)
+{
+	struct dma_pl330_peri *peri;
+
+	if (chan->device->dev->driver != &pl330_driver.drv)
+		return false;
+
+	peri = chan->private;
+	return peri->peri_id == (unsigned)param;
+}
+EXPORT_SYMBOL(pl330_filter);
+
 static int pl330_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct dma_pl330_chan *pch = to_pchan(chan);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index d12f077..6db72da 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -12,6 +12,7 @@
 #ifndef	__AMBA_PL330_H_
 #define	__AMBA_PL330_H_
 
+#include <linux/dmaengine.h>
 #include <asm/hardware/pl330.h>
 
 struct dma_pl330_peri {
@@ -38,4 +39,5 @@ struct dma_pl330_platdata {
 	unsigned mcbuf_sz;
 };
 
+extern bool pl330_filter(struct dma_chan *chan, void *param);
 #endif	/* __AMBA_PL330_H_ */
-- 
1.6.6.rc2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox