From a2ba8b19989e038bdf1a9fcc25e860d5077d2474 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 28 Oct 2008 18:19:29 +0800 Subject: Blackfin arch: lookup channel2irq() only once Add irq to struct dma_channel lookup channel2irq() only once, since channel2irq() is fairly large on some Blackfin derivatives. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 6509733bb0f6..9befcbae00b9 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -140,6 +140,7 @@ struct dma_channel { struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ unsigned int ctrl_num; /* controller number */ + unsigned int irq; dma_interrupt_t irq_callback; void *data; unsigned int dma_enable_flag; -- cgit v1.2.3 From 99532fd2a0955e609c53b587b4df79ae40b4a6c7 Mon Sep 17 00:00:00 2001 From: Michael McTernan Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: add const to some function prototype and struct dma_channel Signed-off-by: Michael McTernan Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 4 ++-- arch/blackfin/kernel/bfin_dma_5xx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 9befcbae00b9..3aa4dd3e5fe8 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -135,7 +135,7 @@ typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id); struct dma_channel { struct mutex dmalock; - char *device_id; + const char *device_id; enum dma_chan_status chan_status; struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ @@ -191,7 +191,7 @@ void free_dma(unsigned int channel); int dma_channel_active(unsigned int channel); /* check if a channel is in use */ void disable_dma(unsigned int channel); void enable_dma(unsigned int channel); -int request_dma(unsigned int channel, char *device_id); +int request_dma(unsigned int channel, const char *device_id); int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data); void dma_disable_irq(unsigned int channel); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 2625aa20a92c..22bce17bbb02 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -116,7 +116,7 @@ late_initcall(proc_dma_init); /*------------------------------------------------------------------------------ * Request the specific DMA channel from the system. *-----------------------------------------------------------------------------*/ -int request_dma(unsigned int channel, char *device_id) +int request_dma(unsigned int channel, const char *device_id) { pr_debug("request_dma() : BEGIN \n"); -- cgit v1.2.3 From 211daf9d7252288ad88ab6b97268a8d828e6b696 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:39 +0800 Subject: Blackfin arch: rename MAX_BLACKFIN_DMA_CHANNEL to MAX_DMA_CHANNELS to match everyone else Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 2 +- arch/blackfin/kernel/bfin_dma_5xx.c | 14 +++++++------- arch/blackfin/mach-bf518/dma.c | 2 +- arch/blackfin/mach-bf518/include/mach/dma.h | 2 +- arch/blackfin/mach-bf527/dma.c | 2 +- arch/blackfin/mach-bf527/include/mach/dma.h | 2 +- arch/blackfin/mach-bf533/dma.c | 2 +- arch/blackfin/mach-bf533/include/mach/dma.h | 2 +- arch/blackfin/mach-bf537/dma.c | 2 +- arch/blackfin/mach-bf537/include/mach/dma.h | 2 +- arch/blackfin/mach-bf538/dma.c | 2 +- arch/blackfin/mach-bf538/include/mach/dma.h | 2 +- arch/blackfin/mach-bf548/dma.c | 2 +- arch/blackfin/mach-bf548/include/mach/dma.h | 2 +- arch/blackfin/mach-bf561/dma.c | 2 +- arch/blackfin/mach-bf561/include/mach/dma.h | 2 +- arch/blackfin/mach-common/clocks-init.c | 2 +- 17 files changed, 23 insertions(+), 23 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 3aa4dd3e5fe8..7d1cfa71a9d7 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -201,6 +201,6 @@ void *dma_memcpy(void *dest, const void *src, size_t count); void *safe_dma_memcpy(void *dest, const void *src, size_t count); extern int channel2irq(unsigned int channel); -extern struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL]; +extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; #endif diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 22bce17bbb02..ad936843ecda 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -44,7 +44,7 @@ * Global Variables ***************************************************************************/ -static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL]; +static struct dma_channel dma_ch[MAX_DMA_CHANNELS]; /*------------------------------------------------------------------------------ * Set the Buffer Clear bit in the Configuration register of specific DMA @@ -63,7 +63,7 @@ static int __init blackfin_dma_init(void) printk(KERN_INFO "Blackfin DMA Controller\n"); - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { + for (i = 0; i < MAX_DMA_CHANNELS; i++) { dma_ch[i].chan_status = DMA_CHANNEL_FREE; dma_ch[i].regs = dma_io_base_addr[i]; mutex_init(&(dma_ch[i].dmalock)); @@ -87,7 +87,7 @@ static int proc_dma_show(struct seq_file *m, void *v) { int i; - for (i = 0 ; i < MAX_BLACKFIN_DMA_CHANNEL; ++i) + for (i = 0 ; i < MAX_DMA_CHANNELS; ++i) if (dma_ch[i].chan_status != DMA_CHANNEL_FREE) seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id); @@ -175,7 +175,7 @@ EXPORT_SYMBOL(request_dma); int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data) { BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); + && channel < MAX_DMA_CHANNELS)); if (callback != NULL) { int ret_val; @@ -200,7 +200,7 @@ void free_dma(unsigned int channel) { pr_debug("freedma() : BEGIN \n"); BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); + && channel < MAX_DMA_CHANNELS)); /* Halt the DMA */ disable_dma(channel); @@ -418,7 +418,7 @@ int blackfin_dma_suspend(void) #ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) { #else - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { + for (i = 0; i < MAX_DMA_CHANNELS; i++) { #endif if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); @@ -438,7 +438,7 @@ void blackfin_dma_resume(void) #ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) #else - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) + for (i = 0; i < MAX_DMA_CHANNELS; i++) #endif dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; } diff --git a/arch/blackfin/mach-bf518/dma.c b/arch/blackfin/mach-bf518/dma.c index 0d06ced01ced..698e88ca5104 100644 --- a/arch/blackfin/mach-bf518/dma.c +++ b/arch/blackfin/mach-bf518/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf518/include/mach/dma.h b/arch/blackfin/mach-bf518/include/mach/dma.h index e2a71ba907e9..f46bce087015 100644 --- a/arch/blackfin/mach-bf518/include/mach/dma.h +++ b/arch/blackfin/mach-bf518/include/mach/dma.h @@ -32,7 +32,7 @@ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -#define MAX_BLACKFIN_DMA_CHANNEL 16 +#define MAX_DMA_CHANNELS 16 #define CH_PPI 0 /* PPI receive/transmit */ #define CH_EMAC_RX 1 /* Ethernet MAC receive */ diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c index dfd080cda787..231877578243 100644 --- a/arch/blackfin/mach-bf527/dma.c +++ b/arch/blackfin/mach-bf527/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf527/include/mach/dma.h b/arch/blackfin/mach-bf527/include/mach/dma.h index 49dd693223e8..ab9b274312a5 100644 --- a/arch/blackfin/mach-bf527/include/mach/dma.h +++ b/arch/blackfin/mach-bf527/include/mach/dma.h @@ -32,7 +32,7 @@ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -#define MAX_BLACKFIN_DMA_CHANNEL 16 +#define MAX_DMA_CHANNELS 16 #define CH_PPI 0 /* PPI receive/transmit or NFC */ #define CH_EMAC_RX 1 /* Ethernet MAC receive or HOSTDP */ diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c index 28655c1cb7dc..0a6eb8f24d98 100644 --- a/arch/blackfin/mach-bf533/dma.c +++ b/arch/blackfin/mach-bf533/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf533/include/mach/dma.h b/arch/blackfin/mach-bf533/include/mach/dma.h index bd9d5e94307d..4ff787e3559d 100644 --- a/arch/blackfin/mach-bf533/include/mach/dma.h +++ b/arch/blackfin/mach-bf533/include/mach/dma.h @@ -36,7 +36,7 @@ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -#define MAX_BLACKFIN_DMA_CHANNEL 12 +#define MAX_DMA_CHANNELS 12 #define CH_PPI 0 #define CH_SPORT0_RX 1 diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c index 4edb363ff99c..81185051de91 100644 --- a/arch/blackfin/mach-bf537/dma.c +++ b/arch/blackfin/mach-bf537/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf537/include/mach/dma.h b/arch/blackfin/mach-bf537/include/mach/dma.h index 7a964040870a..4be361a7ff08 100644 --- a/arch/blackfin/mach-bf537/include/mach/dma.h +++ b/arch/blackfin/mach-bf537/include/mach/dma.h @@ -32,7 +32,7 @@ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -#define MAX_BLACKFIN_DMA_CHANNEL 16 +#define MAX_DMA_CHANNELS 16 #define CH_PPI 0 #define CH_EMAC_RX 1 diff --git a/arch/blackfin/mach-bf538/dma.c b/arch/blackfin/mach-bf538/dma.c index 359fdaa12b8f..d6837fbf94ea 100644 --- a/arch/blackfin/mach-bf538/dma.c +++ b/arch/blackfin/mach-bf538/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf538/include/mach/dma.h b/arch/blackfin/mach-bf538/include/mach/dma.h index c2210a996e68..a52ec3a17b05 100644 --- a/arch/blackfin/mach-bf538/include/mach/dma.h +++ b/arch/blackfin/mach-bf538/include/mach/dma.h @@ -60,6 +60,6 @@ #define CH_MEM_STREAM3_DEST 26 #define CH_MEM_STREAM3_SRC 27 -#define MAX_BLACKFIN_DMA_CHANNEL 28 +#define MAX_DMA_CHANNELS 28 #endif diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c index 74730eb8ae1b..535980652bf6 100644 --- a/arch/blackfin/mach-bf548/dma.c +++ b/arch/blackfin/mach-bf548/dma.c @@ -32,7 +32,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA0_NEXT_DESC_PTR, (struct dma_register *) DMA1_NEXT_DESC_PTR, (struct dma_register *) DMA2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf548/include/mach/dma.h b/arch/blackfin/mach-bf548/include/mach/dma.h index 36a2ef7e7849..796c205d8177 100644 --- a/arch/blackfin/mach-bf548/include/mach/dma.h +++ b/arch/blackfin/mach-bf548/include/mach/dma.h @@ -71,6 +71,6 @@ #define CH_MEM_STREAM3_DEST 30 #define CH_MEM_STREAM3_SRC 31 -#define MAX_BLACKFIN_DMA_CHANNEL 32 +#define MAX_DMA_CHANNELS 32 #endif diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c index 24415eb82698..42b0037afe61 100644 --- a/arch/blackfin/mach-bf561/dma.c +++ b/arch/blackfin/mach-bf561/dma.c @@ -31,7 +31,7 @@ #include #include -struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { +struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS] = { (struct dma_register *) DMA1_0_NEXT_DESC_PTR, (struct dma_register *) DMA1_1_NEXT_DESC_PTR, (struct dma_register *) DMA1_2_NEXT_DESC_PTR, diff --git a/arch/blackfin/mach-bf561/include/mach/dma.h b/arch/blackfin/mach-bf561/include/mach/dma.h index 8bc46cd89a02..38ce66ae6c30 100644 --- a/arch/blackfin/mach-bf561/include/mach/dma.h +++ b/arch/blackfin/mach-bf561/include/mach/dma.h @@ -7,7 +7,7 @@ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -#define MAX_BLACKFIN_DMA_CHANNEL 36 +#define MAX_DMA_CHANNELS 36 #define CH_PPI0 0 #define CH_PPI (CH_PPI0) diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index 39a94b3a2ed7..5d182abefc7b 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c @@ -32,7 +32,7 @@ void init_clocks(void) * For example, any automatic DMAs left by U-Boot for splash screens. */ size_t i; - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; ++i) { + for (i = 0; i < MAX_DMA_CHANNELS; ++i) { struct dma_register *dma = dma_io_base_addr[i]; dma->cfg = 0; } -- cgit v1.2.3 From b03f203986dcf51b556e5f86475338b1588d8652 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: cleanup - use scm for changelog, not file headers Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 27 +++-------------------- arch/blackfin/mach-bf518/include/mach/dma.h | 30 +++---------------------- arch/blackfin/mach-bf527/include/mach/dma.h | 30 +++---------------------- arch/blackfin/mach-bf533/include/mach/dma.h | 34 +++-------------------------- arch/blackfin/mach-bf537/include/mach/dma.h | 30 +++---------------------- arch/blackfin/mach-bf538/include/mach/dma.h | 30 +++---------------------- arch/blackfin/mach-bf548/include/mach/dma.h | 30 +++---------------------- arch/blackfin/mach-bf561/include/mach/dma.h | 11 +++++----- 8 files changed, 27 insertions(+), 195 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 7d1cfa71a9d7..d059b2de1629 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -1,29 +1,8 @@ /* - * File: include/asm-blackfin/simple_bf533_dma.h - * Based on: none - original work - * Author: LG Soft India - * Copyright (C) 2004-2005 Analog Devices Inc. - * Created: Tue Sep 21 2004 - * Description: This file contains the major Data structures and constants - * used for DMA Implementation in BF533 - * Modified: + * dma.h - Blackfin DMA defines/structures/etc... * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. - * If not, write to the Free Software Foundation, - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Copyright 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. */ #ifndef _BLACKFIN_DMA_H_ diff --git a/arch/blackfin/mach-bf518/include/mach/dma.h b/arch/blackfin/mach-bf518/include/mach/dma.h index f46bce087015..bbd33c1706e2 100644 --- a/arch/blackfin/mach-bf518/include/mach/dma.h +++ b/arch/blackfin/mach-bf518/include/mach/dma.h @@ -1,32 +1,8 @@ -/* - * file: include/asm-blackfin/mach-bf518/dma.h - * based on: include/asm-blackfin/mach-bf527/dma.h - * author: Michael Hennerich (michael.hennerich@analog.com) +/* mach/dma.h - arch-specific DMA defines * - * created: - * description: - * system DMA map - * rev: + * Copyright 2004-2008 Analog Devices Inc. * - * modified: - * - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf527/include/mach/dma.h b/arch/blackfin/mach-bf527/include/mach/dma.h index ab9b274312a5..eb287da101a2 100644 --- a/arch/blackfin/mach-bf527/include/mach/dma.h +++ b/arch/blackfin/mach-bf527/include/mach/dma.h @@ -1,32 +1,8 @@ -/* - * file: include/asm-blackfin/mach-bf527/dma.h - * based on: include/asm-blackfin/mach-bf537/dma.h - * author: Michael Hennerich (michael.hennerich@analog.com) +/* mach/dma.h - arch-specific DMA defines * - * created: - * description: - * system DMA map - * rev: + * Copyright 2004-2008 Analog Devices Inc. * - * modified: - * - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf533/include/mach/dma.h b/arch/blackfin/mach-bf533/include/mach/dma.h index 4ff787e3559d..d689522b2bfb 100644 --- a/arch/blackfin/mach-bf533/include/mach/dma.h +++ b/arch/blackfin/mach-bf533/include/mach/dma.h @@ -1,36 +1,8 @@ -/***************************************************************************** -* -* BF-533/2/1 Specific Declarations -* -****************************************************************************/ -/* - * File: include/asm-blackfin/mach-bf533/dma.h - * Based on: - * Author: +/* mach/dma.h - arch-specific DMA defines * - * Created: - * Description: + * Copyright 2004-2008 Analog Devices Inc. * - * Rev: - * - * Modified: - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. - * If not, write to the Free Software Foundation, - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf537/include/mach/dma.h b/arch/blackfin/mach-bf537/include/mach/dma.h index 4be361a7ff08..5ae83b1183a1 100644 --- a/arch/blackfin/mach-bf537/include/mach/dma.h +++ b/arch/blackfin/mach-bf537/include/mach/dma.h @@ -1,32 +1,8 @@ -/* - * file: include/asm-blackfin/mach-bf537/dma.h - * based on: - * author: +/* mach/dma.h - arch-specific DMA defines * - * created: - * description: - * system mmr register map - * rev: + * Copyright 2004-2008 Analog Devices Inc. * - * modified: - * - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf538/include/mach/dma.h b/arch/blackfin/mach-bf538/include/mach/dma.h index a52ec3a17b05..eb05cacbf4d3 100644 --- a/arch/blackfin/mach-bf538/include/mach/dma.h +++ b/arch/blackfin/mach-bf538/include/mach/dma.h @@ -1,32 +1,8 @@ -/* - * file: include/asm-blackfin/mach-bf538/dma.h - * based on: - * author: +/* mach/dma.h - arch-specific DMA defines * - * created: - * description: - * system mmr register map - * rev: + * Copyright 2004-2008 Analog Devices Inc. * - * modified: - * - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf548/include/mach/dma.h b/arch/blackfin/mach-bf548/include/mach/dma.h index 796c205d8177..a30d242c7398 100644 --- a/arch/blackfin/mach-bf548/include/mach/dma.h +++ b/arch/blackfin/mach-bf548/include/mach/dma.h @@ -1,32 +1,8 @@ -/* - * file: include/asm-blackfin/mach-bf548/dma.h - * based on: - * author: +/* mach/dma.h - arch-specific DMA defines * - * created: - * description: - * system mmr register map - * rev: + * Copyright 2004-2008 Analog Devices Inc. * - * modified: - * - * - * bugs: enter bugs at http://blackfin.uclinux.org/ - * - * 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, or (at your option) - * any later version. - * - * this program is distributed in the hope that it will be useful, - * but without any warranty; without even the implied warranty of - * merchantability or fitness for a particular purpose. see the - * gnu general public license for more details. - * - * you should have received a copy of the gnu general public license - * along with this program; see the file copying. - * if not, write to the free software foundation, - * 59 temple place - suite 330, boston, ma 02111-1307, usa. + * Licensed under the GPL-2 or later. */ #ifndef _MACH_DMA_H_ diff --git a/arch/blackfin/mach-bf561/include/mach/dma.h b/arch/blackfin/mach-bf561/include/mach/dma.h index 38ce66ae6c30..2597a09a012c 100644 --- a/arch/blackfin/mach-bf561/include/mach/dma.h +++ b/arch/blackfin/mach-bf561/include/mach/dma.h @@ -1,8 +1,9 @@ -/***************************************************************************** -* -* BF-533/2/1 Specific Declarations -* -****************************************************************************/ +/* mach/dma.h - arch-specific DMA defines + * + * Copyright 2004-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ #ifndef _MACH_DMA_H_ #define _MACH_DMA_H_ -- cgit v1.2.3 From dd3dd384df7f9f77fba6875a606e5a663510cd1d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:39 +0800 Subject: Blackfin arch: rewrite dma_memcpy() and dma in/out functions - unify all dma in/out functions (takes ~35 lines of code now) - unify dma_memcpy with dma in/out functions (1 place that touches MDMA0 registers) - add support for 32bit transfers - cleanup dma_memcpy code to be much more readable - irqs are disabled only while programming MDMA registers rather than the entire transaction Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 1 + arch/blackfin/kernel/bfin_dma_5xx.c | 519 +++++++++++------------------------- arch/blackfin/kernel/setup.c | 2 + 3 files changed, 156 insertions(+), 366 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index d059b2de1629..ca8252ab7a10 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -178,6 +178,7 @@ void dma_enable_irq(unsigned int channel); void clear_dma_irqstat(unsigned int channel); void *dma_memcpy(void *dest, const void *src, size_t count); void *safe_dma_memcpy(void *dest, const void *src, size_t count); +void blackfin_dma_early_init(void); extern int channel2irq(unsigned int channel); extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index bafb6aea0bc5..dff979bf8541 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -1,44 +1,24 @@ /* - * File: arch/blackfin/kernel/bfin_dma_5xx.c - * Based on: - * Author: + * bfin_dma_5xx.c - Blackfin DMA implementation * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Copyright 2004-2006 Analog Devices Inc. + * Licensed under the GPL-2 or later. */ #include +#include +#include #include +#include #include #include #include -#include -#include -#include +#include #include -#include #include +#include +#include /************************************************************************** * Global Variables @@ -82,12 +62,11 @@ static int __init blackfin_dma_init(void) arch_initcall(blackfin_dma_init); #ifdef CONFIG_PROC_FS - static int proc_dma_show(struct seq_file *m, void *v) { int i; - for (i = 0 ; i < MAX_DMA_CHANNELS; ++i) + for (i = 0; i < MAX_DMA_CHANNELS; ++i) if (dma_ch[i].chan_status != DMA_CHANNEL_FREE) seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id); @@ -438,385 +417,193 @@ void blackfin_dma_resume(void) } #endif -static void *__dma_memcpy(void *dest, const void *src, size_t size) +/** + * blackfin_dma_early_init - minimal DMA init + * + * Setup a few DMA registers so we can safely do DMA transfers early on in + * the kernel booting process. Really this just means using dma_memcpy(). + */ +void __init blackfin_dma_early_init(void) { - int direction; /* 1 - address decrease, 0 - address increase */ - int flag_align; /* 1 - address aligned, 0 - address unaligned */ - int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */ - unsigned long flags; - - if (size <= 0) - return NULL; - - local_irq_save(flags); - - if ((unsigned long)src < memory_end) - blackfin_dcache_flush_range((unsigned int)src, - (unsigned int)(src + size)); - - if ((unsigned long)dest < memory_end) - blackfin_dcache_invalidate_range((unsigned int)dest, - (unsigned int)(dest + size)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - if ((unsigned long)src < (unsigned long)dest) - direction = 1; - else - direction = 0; - - if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0) - && ((size % 2) == 0)) - flag_align = 1; - else - flag_align = 0; - - if (size > 0x10000) /* size > 64K */ - flag_2D = 1; - else - flag_2D = 0; - - /* Setup destination and source start address */ - if (direction) { - if (flag_align) { - bfin_write_MDMA_D0_START_ADDR(dest + size - 2); - bfin_write_MDMA_S0_START_ADDR(src + size - 2); - } else { - bfin_write_MDMA_D0_START_ADDR(dest + size - 1); - bfin_write_MDMA_S0_START_ADDR(src + size - 1); - } - } else { - bfin_write_MDMA_D0_START_ADDR(dest); - bfin_write_MDMA_S0_START_ADDR(src); - } - - /* Setup destination and source xcount */ - if (flag_2D) { - if (flag_align) { - bfin_write_MDMA_D0_X_COUNT(1024 / 2); - bfin_write_MDMA_S0_X_COUNT(1024 / 2); - } else { - bfin_write_MDMA_D0_X_COUNT(1024); - bfin_write_MDMA_S0_X_COUNT(1024); - } - bfin_write_MDMA_D0_Y_COUNT(size >> 10); - bfin_write_MDMA_S0_Y_COUNT(size >> 10); - } else { - if (flag_align) { - bfin_write_MDMA_D0_X_COUNT(size / 2); - bfin_write_MDMA_S0_X_COUNT(size / 2); - } else { - bfin_write_MDMA_D0_X_COUNT(size); - bfin_write_MDMA_S0_X_COUNT(size); - } - } - - /* Setup destination and source xmodify and ymodify */ - if (direction) { - if (flag_align) { - bfin_write_MDMA_D0_X_MODIFY(-2); - bfin_write_MDMA_S0_X_MODIFY(-2); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(-2); - bfin_write_MDMA_S0_Y_MODIFY(-2); - } - } else { - bfin_write_MDMA_D0_X_MODIFY(-1); - bfin_write_MDMA_S0_X_MODIFY(-1); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(-1); - bfin_write_MDMA_S0_Y_MODIFY(-1); - } - } - } else { - if (flag_align) { - bfin_write_MDMA_D0_X_MODIFY(2); - bfin_write_MDMA_S0_X_MODIFY(2); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(2); - bfin_write_MDMA_S0_Y_MODIFY(2); - } - } else { - bfin_write_MDMA_D0_X_MODIFY(1); - bfin_write_MDMA_S0_X_MODIFY(1); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(1); - bfin_write_MDMA_S0_Y_MODIFY(1); - } - } - } - - /* Enable source DMA */ - if (flag_2D) { - if (flag_align) { - bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16); - } else { - bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D); - } - } else { - if (flag_align) { - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); - } else { - bfin_write_MDMA_S0_CONFIG(DMAEN); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN); - } - } - - SSYNC(); - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) - ; - - bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | - (DMA_DONE | DMA_ERR)); - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - - local_irq_restore(flags); - - return dest; } -void *dma_memcpy(void *dest, const void *src, size_t size) -{ - size_t bulk; - size_t rest; - void * addr; - - bulk = (size >> 16) << 16; - rest = size - bulk; - if (bulk) - __dma_memcpy(dest, src, bulk); - __dma_memcpy(dest+bulk, src+bulk, rest); - return dest; -} -EXPORT_SYMBOL(dma_memcpy); - /** - * safe_dma_memcpy - DMA memcpy w/argument checking + * __dma_memcpy - program the MDMA registers * - * Verify arguments are safe before heading to dma_memcpy(). + * Actually program MDMA0 and wait for the transfer to finish. Disable IRQs + * while programming registers so that everything is fully configured. Wait + * for DMA to finish with IRQs enabled. If interrupted, the initial DMA_DONE + * check will make sure we don't clobber any existing transfer. */ -void *safe_dma_memcpy(void *dest, const void *src, size_t size) -{ - if (!access_ok(VERIFY_WRITE, dst, size)) - return NULL; - if (!access_ok(VERIFY_READ, src, size)) - return NULL; - return dma_memcpy(dst, src, size); -} -EXPORT_SYMBOL(safe_dma_memcpy); - -void dma_outsb(unsigned long addr, const void *buf, unsigned short len) +static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u32 conf) { + static DEFINE_SPINLOCK(mdma_lock); unsigned long flags; - local_irq_save(flags); - - blackfin_dcache_flush_range((unsigned int)buf, - (unsigned int)(buf) + len); + spin_lock_irqsave(&mdma_lock, flags); + + if (bfin_read_MDMA_S0_CONFIG()) + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + continue; + + if (conf & DMA2D) { + /* For larger bit sizes, we've already divided down cnt so it + * is no longer a multiple of 64k. So we have to break down + * the limit here so it is a multiple of the incoming size. + * There is no limitation here in terms of total size other + * than the hardware though as the bits lost in the shift are + * made up by MODIFY (== we can hit the whole address space). + * X: (2^(16 - 0)) * 1 == (2^(16 - 1)) * 2 == (2^(16 - 2)) * 4 + */ + u32 shift = abs(dmod) >> 1; + size_t ycnt = cnt >> (16 - shift); + cnt = 1 << (16 - shift); + bfin_write_MDMA_D0_Y_COUNT(ycnt); + bfin_write_MDMA_S0_Y_COUNT(ycnt); + bfin_write_MDMA_D0_Y_MODIFY(dmod); + bfin_write_MDMA_S0_Y_MODIFY(smod); + } - bfin_write_MDMA_D0_START_ADDR(addr); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(0); + bfin_write_MDMA_D0_START_ADDR(daddr); + bfin_write_MDMA_D0_X_COUNT(cnt); + bfin_write_MDMA_D0_X_MODIFY(dmod); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S0_START_ADDR(buf); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(1); + bfin_write_MDMA_S0_START_ADDR(saddr); + bfin_write_MDMA_S0_X_COUNT(cnt); + bfin_write_MDMA_S0_X_MODIFY(smod); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); + bfin_write_MDMA_S0_CONFIG(DMAEN | conf); + bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | conf); + + spin_unlock_irqrestore(&mdma_lock, flags); SSYNC(); - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + if (bfin_read_MDMA_S0_CONFIG()) + continue; + else + return; bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); - } -EXPORT_SYMBOL(dma_outsb); - -void dma_insb(unsigned long addr, void *buf, unsigned short len) +/** + * _dma_memcpy - translate C memcpy settings into MDMA settings + * + * Handle all the high level steps before we touch the MDMA registers. So + * handle caching, tweaking of sizes, and formatting of addresses. + */ +static void *_dma_memcpy(void *pdst, const void *psrc, size_t size) { - unsigned long flags; + u32 conf, shift; + s16 mod; + unsigned long dst = (unsigned long)pdst; + unsigned long src = (unsigned long)psrc; - blackfin_dcache_invalidate_range((unsigned int)buf, - (unsigned int)(buf) + len); + if (size == 0) + return NULL; - local_irq_save(flags); - bfin_write_MDMA_D0_START_ADDR(buf); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(1); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + if (bfin_addr_dcachable(src)) + blackfin_dcache_flush_range(src, src + size); - bfin_write_MDMA_S0_START_ADDR(addr); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(0); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); + if (bfin_addr_dcachable(dst)) + blackfin_dcache_invalidate_range(dst, dst + size); - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); - - SSYNC(); + if (dst % 4 == 0 && src % 4 == 0 && size % 4 == 0) { + conf = WDSIZE_32; + shift = 2; + } else if (dst % 2 == 0 && src % 2 == 0 && size % 2 == 0) { + conf = WDSIZE_16; + shift = 1; + } else { + conf = WDSIZE_8; + shift = 0; + } - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); + /* If the two memory regions have a chance of overlapping, make + * sure the memcpy still works as expected. Do this by having the + * copy run backwards instead. + */ + mod = 1 << shift; + if (src < dst) { + mod *= -1; + dst += size + mod; + src += size + mod; + } + size >>= shift; - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + if (size > 0x10000) + conf |= DMA2D; - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); + __dma_memcpy(dst, mod, src, mod, size, conf); + return pdst; } -EXPORT_SYMBOL(dma_insb); -void dma_outsw(unsigned long addr, const void *buf, unsigned short len) +/** + * dma_memcpy - DMA memcpy under mutex lock + * + * Do not check arguments before starting the DMA memcpy. Break the transfer + * up into two pieces. The first transfer is in multiples of 64k and the + * second transfer is the piece smaller than 64k. + */ +void *dma_memcpy(void *dst, const void *src, size_t size) { - unsigned long flags; - - local_irq_save(flags); - - blackfin_dcache_flush_range((unsigned int)buf, - (unsigned int)(buf) + len * sizeof(short)); - - bfin_write_MDMA_D0_START_ADDR(addr); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(0); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_START_ADDR(buf); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(2); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); - - SSYNC(); - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); - + size_t bulk, rest; + bulk = size & ~0xffff; + rest = size - bulk; + if (bulk) + _dma_memcpy(dst, src, bulk); + _dma_memcpy(dst + bulk, src + bulk, rest); + return dst; } -EXPORT_SYMBOL(dma_outsw); +EXPORT_SYMBOL(dma_memcpy); -void dma_insw(unsigned long addr, void *buf, unsigned short len) +/** + * safe_dma_memcpy - DMA memcpy w/argument checking + * + * Verify arguments are safe before heading to dma_memcpy(). + */ +void *safe_dma_memcpy(void *dst, const void *src, size_t size) { - unsigned long flags; - - blackfin_dcache_invalidate_range((unsigned int)buf, - (unsigned int)(buf) + len * sizeof(short)); - - local_irq_save(flags); - - bfin_write_MDMA_D0_START_ADDR(buf); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(2); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_START_ADDR(addr); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(0); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); - - SSYNC(); - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); - + if (!access_ok(VERIFY_WRITE, dst, size)) + return NULL; + if (!access_ok(VERIFY_READ, src, size)) + return NULL; + return dma_memcpy(dst, src, size); } -EXPORT_SYMBOL(dma_insw); +EXPORT_SYMBOL(safe_dma_memcpy); -void dma_outsl(unsigned long addr, const void *buf, unsigned short len) +static void _dma_out(unsigned long addr, unsigned long buf, unsigned short len, + u16 size, u16 dma_size) { - unsigned long flags; - - local_irq_save(flags); - - blackfin_dcache_flush_range((unsigned int)buf, - (unsigned int)(buf) + len * sizeof(long)); - - bfin_write_MDMA_D0_START_ADDR(addr); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(0); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_START_ADDR(buf); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(4); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); - - SSYNC(); - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); - + blackfin_dcache_flush_range(buf, buf + len * size); + __dma_memcpy(addr, 0, buf, size, len, dma_size); } -EXPORT_SYMBOL(dma_outsl); -void dma_insl(unsigned long addr, void *buf, unsigned short len) +static void _dma_in(unsigned long addr, unsigned long buf, unsigned short len, + u16 size, u16 dma_size) { - unsigned long flags; - - blackfin_dcache_invalidate_range((unsigned int)buf, - (unsigned int)(buf) + len * sizeof(long)); - - local_irq_save(flags); - - bfin_write_MDMA_D0_START_ADDR(buf); - bfin_write_MDMA_D0_X_COUNT(len); - bfin_write_MDMA_D0_X_MODIFY(4); - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_START_ADDR(addr); - bfin_write_MDMA_S0_X_COUNT(len); - bfin_write_MDMA_S0_X_MODIFY(0); - bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); - - SSYNC(); - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - local_irq_restore(flags); - + blackfin_dcache_invalidate_range(buf, buf + len * size); + __dma_memcpy(buf, size, addr, 0, len, dma_size); } -EXPORT_SYMBOL(dma_insl); + +#define MAKE_DMA_IO(io, bwl, isize, dmasize, cnst) \ +void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned short len) \ +{ \ + _dma_##io(addr, (unsigned long)buf, len, isize, WDSIZE_##dmasize); \ +} \ +EXPORT_SYMBOL(dma_##io##s##bwl) +MAKE_DMA_IO(out, b, 1, 8, const); +MAKE_DMA_IO(in, b, 1, 8, ); +MAKE_DMA_IO(out, w, 2, 16, const); +MAKE_DMA_IO(in, w, 2, 16, ); +MAKE_DMA_IO(out, l, 4, 32, const); +MAKE_DMA_IO(in, l, 4, 32, ); diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index b147ed90cadc..56b8b4cff99c 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -154,6 +154,8 @@ void __init bfin_relocate_l1_mem(void) unsigned long l1_data_b_length; unsigned long l2_length; + blackfin_dma_early_init(); + l1_code_length = _etext_l1 - _stext_l1; if (l1_code_length > L1_CODE_LENGTH) panic("L1 Instruction SRAM Overflow\n"); -- cgit v1.2.3 From 68532bdac35c9cc467c14cb9ea675835e07b5619 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: drop custom dma_interrupt_t and just use irq_handler_t Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 6 ++---- arch/blackfin/kernel/bfin_dma_5xx.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index ca8252ab7a10..045bd1ce72bf 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -110,8 +110,6 @@ struct dma_register { }; -typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id); - struct dma_channel { struct mutex dmalock; const char *device_id; @@ -120,7 +118,7 @@ struct dma_channel { struct dmasg *sg; /* large mode descriptor */ unsigned int ctrl_num; /* controller number */ unsigned int irq; - dma_interrupt_t irq_callback; + irq_handler_t irq_callback; void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; @@ -171,7 +169,7 @@ int dma_channel_active(unsigned int channel); /* check if a channel is in use */ void disable_dma(unsigned int channel); void enable_dma(unsigned int channel); int request_dma(unsigned int channel, const char *device_id); -int set_dma_callback(unsigned int channel, dma_interrupt_t callback, +int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); void dma_disable_irq(unsigned int channel); void dma_enable_irq(unsigned int channel); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index dff979bf8541..b6cf643f5935 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -151,7 +151,7 @@ int request_dma(unsigned int channel, const char *device_id) } EXPORT_SYMBOL(request_dma); -int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data) +int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) { BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE && channel < MAX_DMA_CHANNELS)); -- cgit v1.2.3 From 9b011407d653b92191aa4993222523039d44af52 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: drop irq_callback from struct dma_channel the irq member already serves the same purpose Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 1 - arch/blackfin/kernel/bfin_dma_5xx.c | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 045bd1ce72bf..c327135ff9dd 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -118,7 +118,6 @@ struct dma_channel { struct dmasg *sg; /* large mode descriptor */ unsigned int ctrl_num; /* controller number */ unsigned int irq; - irq_handler_t irq_callback; void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index b6cf643f5935..bdebab41419f 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -140,7 +140,7 @@ int request_dma(unsigned int channel, const char *device_id) #endif dma_ch[channel].device_id = device_id; - dma_ch[channel].irq_callback = NULL; + dma_ch[channel].irq = 0; /* This is to be enabled by putting a restriction - * you have to request DMA, before doing any operations on @@ -169,7 +169,6 @@ int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) "Request irq in DMA engine failed.\n"); return -EPERM; } - dma_ch[channel].irq_callback = callback; } return 0; } @@ -185,7 +184,7 @@ void free_dma(unsigned int channel) disable_dma(channel); clear_dma_buffer(channel); - if (dma_ch[channel].irq_callback != NULL) + if (dma_ch[channel].irq) free_irq(dma_ch[channel].irq, dma_ch[channel].data); /* Clear the DMA Variable in the Channel */ -- cgit v1.2.3 From 4c1ed6a57bc51ecd471989ae744da86a9101912f Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: dma header file: strip down includes to only necessary ones Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index c327135ff9dd..4928e7aa4801 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -8,16 +8,10 @@ #ifndef _BLACKFIN_DMA_H_ #define _BLACKFIN_DMA_H_ -#include -#include -#include -#include - -#include -#include -#include #include +#include #include +#include #define MAX_DMA_ADDRESS PAGE_OFFSET @@ -110,6 +104,7 @@ struct dma_register { }; +struct mutex; struct dma_channel { struct mutex dmalock; const char *device_id; -- cgit v1.2.3 From 9c417a43299edc52931712a54c46cff4db19082c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:39 +0800 Subject: Blackfin arch: move most dma functions into static inlines move most dma functions into static inlines since they are vastly 1 liners that get/set a value in a structure Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 156 +++++++++++++++++------- arch/blackfin/kernel/bfin_dma_5xx.c | 233 ++++-------------------------------- 2 files changed, 137 insertions(+), 252 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 4928e7aa4801..690c25f5f992 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -129,50 +129,126 @@ void blackfin_dma_resume(void); /******************************************************************************* * DMA API's *******************************************************************************/ -/* functions to set register mode */ -void set_dma_start_addr(unsigned int channel, unsigned long addr); -void set_dma_next_desc_addr(unsigned int channel, unsigned long addr); -void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr); -void set_dma_x_count(unsigned int channel, unsigned short x_count); -void set_dma_x_modify(unsigned int channel, short x_modify); -void set_dma_y_count(unsigned int channel, unsigned short y_count); -void set_dma_y_modify(unsigned int channel, short y_modify); -void set_dma_config(unsigned int channel, unsigned short config); -unsigned short set_bfin_dma_config(char direction, char flow_mode, - char intr_mode, char dma_mode, char width, - char syncmode); -void set_dma_curr_addr(unsigned int channel, unsigned long addr); - -/* get curr status for polling */ -unsigned short get_dma_curr_irqstat(unsigned int channel); -unsigned short get_dma_curr_xcount(unsigned int channel); -unsigned short get_dma_curr_ycount(unsigned int channel); -unsigned long get_dma_next_desc_ptr(unsigned int channel); -unsigned long get_dma_curr_desc_ptr(unsigned int channel); -unsigned long get_dma_curr_addr(unsigned int channel); - -/* set large DMA mode descriptor */ -void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg); - -/* check if current channel is in use */ -int dma_channel_active(unsigned int channel); - -/* common functions must be called in any mode */ +extern struct dma_channel dma_ch[MAX_DMA_CHANNELS]; +extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; +extern int channel2irq(unsigned int channel); + +static inline void set_dma_start_addr(unsigned int channel, unsigned long addr) +{ + dma_ch[channel].regs->start_addr = addr; +} +static inline void set_dma_next_desc_addr(unsigned int channel, unsigned long addr) +{ + dma_ch[channel].regs->next_desc_ptr = addr; +} +static inline void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr) +{ + dma_ch[channel].regs->curr_desc_ptr = addr; +} +static inline void set_dma_x_count(unsigned int channel, unsigned short x_count) +{ + dma_ch[channel].regs->x_count = x_count; +} +static inline void set_dma_y_count(unsigned int channel, unsigned short y_count) +{ + dma_ch[channel].regs->y_count = y_count; +} +static inline void set_dma_x_modify(unsigned int channel, short x_modify) +{ + dma_ch[channel].regs->x_modify = x_modify; +} +static inline void set_dma_y_modify(unsigned int channel, short y_modify) +{ + dma_ch[channel].regs->y_modify = y_modify; +} +static inline void set_dma_config(unsigned int channel, unsigned short config) +{ + dma_ch[channel].regs->cfg = config; +} +static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr) +{ + dma_ch[channel].regs->curr_addr_ptr = addr; +} + +static inline unsigned short +set_bfin_dma_config(char direction, char flow_mode, + char intr_mode, char dma_mode, char width, char syncmode) +{ + return (direction << 1) | (width << 2) | (dma_mode << 4) | + (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); +} + +static inline unsigned short get_dma_curr_irqstat(unsigned int channel) +{ + return dma_ch[channel].regs->irq_status; +} +static inline unsigned short get_dma_curr_xcount(unsigned int channel) +{ + return dma_ch[channel].regs->curr_x_count; +} +static inline unsigned short get_dma_curr_ycount(unsigned int channel) +{ + return dma_ch[channel].regs->curr_y_count; +} +static inline unsigned long get_dma_next_desc_ptr(unsigned int channel) +{ + return dma_ch[channel].regs->next_desc_ptr; +} +static inline unsigned long get_dma_curr_desc_ptr(unsigned int channel) +{ + return dma_ch[channel].regs->curr_desc_ptr; +} +static inline unsigned long get_dma_curr_addr(unsigned int channel) +{ + return dma_ch[channel].regs->curr_addr_ptr; +} + +static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize) +{ + dma_ch[channel].regs->cfg |= ((ndsize & 0x0F) << 8); + dma_ch[channel].regs->next_desc_ptr = (unsigned long)sg; +} + +static inline int dma_channel_active(unsigned int channel) +{ + if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) + return 0; + else + return 1; +} + +static inline void disable_dma(unsigned int channel) +{ + dma_ch[channel].regs->cfg &= ~DMAEN; + SSYNC(); + dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; +} +static inline void enable_dma(unsigned int channel) +{ + dma_ch[channel].regs->curr_x_count = 0; + dma_ch[channel].regs->curr_y_count = 0; + dma_ch[channel].regs->cfg |= DMAEN; + dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; +} void free_dma(unsigned int channel); -int dma_channel_active(unsigned int channel); /* check if a channel is in use */ -void disable_dma(unsigned int channel); -void enable_dma(unsigned int channel); int request_dma(unsigned int channel, const char *device_id); -int set_dma_callback(unsigned int channel, irq_handler_t callback, - void *data); -void dma_disable_irq(unsigned int channel); -void dma_enable_irq(unsigned int channel); -void clear_dma_irqstat(unsigned int channel); +int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); + +static inline void dma_disable_irq(unsigned int channel) +{ + disable_irq(dma_ch[channel].irq); +} +static inline void dma_enable_irq(unsigned int channel) +{ + enable_irq(dma_ch[channel].irq); +} +static inline void clear_dma_irqstat(unsigned int channel) +{ + dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR; +} + void *dma_memcpy(void *dest, const void *src, size_t count); void *safe_dma_memcpy(void *dest, const void *src, size_t count); void blackfin_dma_early_init(void); -extern int channel2irq(unsigned int channel); -extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; - #endif diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index ed7d2859a626..917b5b8e32c8 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -1,7 +1,7 @@ /* * bfin_dma_5xx.c - Blackfin DMA implementation * - * Copyright 2004-2006 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * Licensed under the GPL-2 or later. */ @@ -20,22 +20,8 @@ #include #include -/************************************************************************** - * Global Variables -***************************************************************************/ - -static struct dma_channel dma_ch[MAX_DMA_CHANNELS]; - -/*------------------------------------------------------------------------------ - * Set the Buffer Clear bit in the Configuration register of specific DMA - * channel. This will stop the descriptor based DMA operation. - *-----------------------------------------------------------------------------*/ -static void clear_dma_buffer(unsigned int channel) -{ - dma_ch[channel].regs->cfg |= RESTART; - SSYNC(); - dma_ch[channel].regs->cfg &= ~RESTART; -} +struct dma_channel dma_ch[MAX_DMA_CHANNELS]; +EXPORT_SYMBOL(dma_ch); static int __init blackfin_dma_init(void) { @@ -92,9 +78,11 @@ static int __init proc_dma_init(void) late_initcall(proc_dma_init); #endif -/*------------------------------------------------------------------------------ - * Request the specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ +/** + * request_dma - request a DMA channel + * + * Request the specific DMA channel from the system if it's available. + */ int request_dma(unsigned int channel, const char *device_id) { pr_debug("request_dma() : BEGIN \n"); @@ -172,6 +160,19 @@ int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) } EXPORT_SYMBOL(set_dma_callback); +/** + * clear_dma_buffer - clear DMA fifos for specified channel + * + * Set the Buffer Clear bit in the Configuration register of specific DMA + * channel. This will stop the descriptor based DMA operation. + */ +static void clear_dma_buffer(unsigned int channel) +{ + dma_ch[channel].regs->cfg |= RESTART; + SSYNC(); + dma_ch[channel].regs->cfg &= ~RESTART; +} + void free_dma(unsigned int channel) { pr_debug("freedma() : BEGIN \n"); @@ -194,198 +195,6 @@ void free_dma(unsigned int channel) } EXPORT_SYMBOL(free_dma); -void dma_enable_irq(unsigned int channel) -{ - pr_debug("dma_enable_irq() : BEGIN \n"); - enable_irq(dma_ch[channel].irq); -} -EXPORT_SYMBOL(dma_enable_irq); - -void dma_disable_irq(unsigned int channel) -{ - pr_debug("dma_disable_irq() : BEGIN \n"); - disable_irq(dma_ch[channel].irq); -} -EXPORT_SYMBOL(dma_disable_irq); - -int dma_channel_active(unsigned int channel) -{ - if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) { - return 0; - } else { - return 1; - } -} -EXPORT_SYMBOL(dma_channel_active); - -/*------------------------------------------------------------------------------ -* stop the specific DMA channel. -*-----------------------------------------------------------------------------*/ -void disable_dma(unsigned int channel) -{ - pr_debug("stop_dma() : BEGIN \n"); - dma_ch[channel].regs->cfg &= ~DMAEN; /* Clean the enable bit */ - SSYNC(); - dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; - /* Needs to be enabled Later */ - pr_debug("stop_dma() : END \n"); - return; -} -EXPORT_SYMBOL(disable_dma); - -void enable_dma(unsigned int channel) -{ - pr_debug("enable_dma() : BEGIN \n"); - dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; - dma_ch[channel].regs->curr_x_count = 0; - dma_ch[channel].regs->curr_y_count = 0; - - dma_ch[channel].regs->cfg |= DMAEN; /* Set the enable bit */ - pr_debug("enable_dma() : END \n"); - return; -} -EXPORT_SYMBOL(enable_dma); - -/*------------------------------------------------------------------------------ -* Set the Start Address register for the specific DMA channel -* This function can be used for register based DMA, -* to setup the start address -* addr: Starting address of the DMA Data to be transferred. -*-----------------------------------------------------------------------------*/ -void set_dma_start_addr(unsigned int channel, unsigned long addr) -{ - pr_debug("set_dma_start_addr() : BEGIN \n"); - dma_ch[channel].regs->start_addr = addr; - pr_debug("set_dma_start_addr() : END\n"); -} -EXPORT_SYMBOL(set_dma_start_addr); - -void set_dma_next_desc_addr(unsigned int channel, unsigned long addr) -{ - pr_debug("set_dma_next_desc_addr() : BEGIN \n"); - dma_ch[channel].regs->next_desc_ptr = addr; - pr_debug("set_dma_next_desc_addr() : END\n"); -} -EXPORT_SYMBOL(set_dma_next_desc_addr); - -void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr) -{ - pr_debug("set_dma_curr_desc_addr() : BEGIN \n"); - dma_ch[channel].regs->curr_desc_ptr = addr; - pr_debug("set_dma_curr_desc_addr() : END\n"); -} -EXPORT_SYMBOL(set_dma_curr_desc_addr); - -void set_dma_x_count(unsigned int channel, unsigned short x_count) -{ - dma_ch[channel].regs->x_count = x_count; -} -EXPORT_SYMBOL(set_dma_x_count); - -void set_dma_y_count(unsigned int channel, unsigned short y_count) -{ - dma_ch[channel].regs->y_count = y_count; -} -EXPORT_SYMBOL(set_dma_y_count); - -void set_dma_x_modify(unsigned int channel, short x_modify) -{ - dma_ch[channel].regs->x_modify = x_modify; -} -EXPORT_SYMBOL(set_dma_x_modify); - -void set_dma_y_modify(unsigned int channel, short y_modify) -{ - dma_ch[channel].regs->y_modify = y_modify; -} -EXPORT_SYMBOL(set_dma_y_modify); - -void set_dma_config(unsigned int channel, unsigned short config) -{ - dma_ch[channel].regs->cfg = config; -} -EXPORT_SYMBOL(set_dma_config); - -unsigned short -set_bfin_dma_config(char direction, char flow_mode, - char intr_mode, char dma_mode, char width, char syncmode) -{ - unsigned short config; - - config = - ((direction << 1) | (width << 2) | (dma_mode << 4) | - (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5)); - return config; -} -EXPORT_SYMBOL(set_bfin_dma_config); - -void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg) -{ - dma_ch[channel].regs->cfg |= ((nr_sg & 0x0F) << 8); - dma_ch[channel].regs->next_desc_ptr = (unsigned int)sg; -} -EXPORT_SYMBOL(set_dma_sg); - -void set_dma_curr_addr(unsigned int channel, unsigned long addr) -{ - dma_ch[channel].regs->curr_addr_ptr = addr; -} -EXPORT_SYMBOL(set_dma_curr_addr); - -/*------------------------------------------------------------------------------ - * Get the DMA status of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_irqstat(unsigned int channel) -{ - return dma_ch[channel].regs->irq_status; -} -EXPORT_SYMBOL(get_dma_curr_irqstat); - -/*------------------------------------------------------------------------------ - * Clear the DMA_DONE bit in DMA status. Stop the DMA completion interrupt. - *-----------------------------------------------------------------------------*/ -void clear_dma_irqstat(unsigned int channel) -{ - dma_ch[channel].regs->irq_status |= 3; -} -EXPORT_SYMBOL(clear_dma_irqstat); - -/*------------------------------------------------------------------------------ - * Get current DMA xcount of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_xcount(unsigned int channel) -{ - return dma_ch[channel].regs->curr_x_count; -} -EXPORT_SYMBOL(get_dma_curr_xcount); - -/*------------------------------------------------------------------------------ - * Get current DMA ycount of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_ycount(unsigned int channel) -{ - return dma_ch[channel].regs->curr_y_count; -} -EXPORT_SYMBOL(get_dma_curr_ycount); - -unsigned long get_dma_next_desc_ptr(unsigned int channel) -{ - return dma_ch[channel].regs->next_desc_ptr; -} -EXPORT_SYMBOL(get_dma_next_desc_ptr); - -unsigned long get_dma_curr_desc_ptr(unsigned int channel) -{ - return dma_ch[channel].regs->curr_desc_ptr; -} -EXPORT_SYMBOL(get_dma_curr_desc_ptr); - -unsigned long get_dma_curr_addr(unsigned int channel) -{ - return dma_ch[channel].regs->curr_addr_ptr; -} -EXPORT_SYMBOL(get_dma_curr_addr); - #ifdef CONFIG_PM # ifndef MAX_DMA_SUSPEND_CHANNELS # define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS -- cgit v1.2.3 From 6ab729d82f1fa1f7d9896be1bd689ee2a1f17860 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: desc_ptr is a pointer, so declare it as such Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 690c25f5f992..264feb4eb175 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -52,7 +52,7 @@ enum dma_chan_status { #define DMA_SYNC_RESTART 1 struct dmasg { - unsigned long next_desc_addr; + void *next_desc_addr; unsigned long start_addr; unsigned short cfg; unsigned short x_count; @@ -62,7 +62,7 @@ struct dmasg { } __attribute__((packed)); struct dma_register { - unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */ + void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ unsigned long start_addr; /* DMA Start address register */ unsigned short cfg; /* DMA Configuration register */ @@ -82,7 +82,7 @@ struct dma_register { short y_modify; /* DMA y_modify register */ unsigned short dummy5; - unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer + void *curr_desc_ptr; /* DMA Current Descriptor Pointer register */ unsigned long curr_addr_ptr; /* DMA Current Address Pointer register */ @@ -137,11 +137,11 @@ static inline void set_dma_start_addr(unsigned int channel, unsigned long addr) { dma_ch[channel].regs->start_addr = addr; } -static inline void set_dma_next_desc_addr(unsigned int channel, unsigned long addr) +static inline void set_dma_next_desc_addr(unsigned int channel, void *addr) { dma_ch[channel].regs->next_desc_ptr = addr; } -static inline void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr) +static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr) { dma_ch[channel].regs->curr_desc_ptr = addr; } @@ -190,11 +190,11 @@ static inline unsigned short get_dma_curr_ycount(unsigned int channel) { return dma_ch[channel].regs->curr_y_count; } -static inline unsigned long get_dma_next_desc_ptr(unsigned int channel) +static inline void *get_dma_next_desc_ptr(unsigned int channel) { return dma_ch[channel].regs->next_desc_ptr; } -static inline unsigned long get_dma_curr_desc_ptr(unsigned int channel) +static inline void *get_dma_curr_desc_ptr(unsigned int channel) { return dma_ch[channel].regs->curr_desc_ptr; } @@ -206,7 +206,7 @@ static inline unsigned long get_dma_curr_addr(unsigned int channel) static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize) { dma_ch[channel].regs->cfg |= ((ndsize & 0x0F) << 8); - dma_ch[channel].regs->next_desc_ptr = (unsigned long)sg; + dma_ch[channel].regs->next_desc_ptr = sg; } static inline int dma_channel_active(unsigned int channel) -- cgit v1.2.3 From d41e8009994f429ef7198a750c37fd9660366fab Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: dma code: cannot simply OR the ndsize cannot simply OR the ndsize ... need to clear out the old value first Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 264feb4eb175..f58ca64d729c 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -205,7 +205,9 @@ static inline unsigned long get_dma_curr_addr(unsigned int channel) static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize) { - dma_ch[channel].regs->cfg |= ((ndsize & 0x0F) << 8); + dma_ch[channel].regs->cfg = + (dma_ch[channel].regs->cfg & ~(0xf << 8)) | + ((ndsize & 0xf) << 8); dma_ch[channel].regs->next_desc_ptr = sg; } -- cgit v1.2.3 From 36478585d994f82654cf8435b34c1a8df3c6ae69 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:39 +0800 Subject: Blackfin arch: remove unused members of dma_channel struct Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index f58ca64d729c..65bf3d610a4c 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -111,11 +111,8 @@ struct dma_channel { enum dma_chan_status chan_status; struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ - unsigned int ctrl_num; /* controller number */ unsigned int irq; void *data; - unsigned int dma_enable_flag; - unsigned int loopback_flag; #ifdef CONFIG_PM unsigned short saved_peripheral_map; #endif -- cgit v1.2.3 From 4ce1873634e1b0bf34fd0f00bff2144029e89247 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: add volatile markings to DMA MMRs Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 65bf3d610a4c..30595bf3ccbd 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -109,7 +109,7 @@ struct dma_channel { struct mutex dmalock; const char *device_id; enum dma_chan_status chan_status; - struct dma_register *regs; + volatile struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ unsigned int irq; void *data; -- cgit v1.2.3 From 71f5ca35d5aa1c27920c2a223993bef551c723b5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 7 Jan 2009 23:14:38 +0800 Subject: Blackfin arch: add get_dma_config() func to match set_dma_config() Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/include/asm/dma.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/blackfin/include/asm/dma.h') diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 30595bf3ccbd..e4f7b8043f02 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -195,6 +195,10 @@ static inline void *get_dma_curr_desc_ptr(unsigned int channel) { return dma_ch[channel].regs->curr_desc_ptr; } +static inline unsigned short get_dma_config(unsigned int channel) +{ + return dma_ch[channel].regs->cfg; +} static inline unsigned long get_dma_curr_addr(unsigned int channel) { return dma_ch[channel].regs->curr_addr_ptr; -- cgit v1.2.3