Commit 5240bcbf authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 5c79e500 491c6040
/* linux/arch/arm/mach-bast/dma.c /* linux/arch/arm/mach-bast/dma.c
* *
* (c) 2003,2004 Simtec Electronics * (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk> * Ben Dooks <ben@simtec.co.uk>
* *
* S3C2410 DMA core * S3C2410 DMA core
* *
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* Changelog: * Changelog:
* 10-Nov-2004 BJD Ensure all external symbols exported for modules
* 10-Nov-2004 BJD Use sys_device and sysdev_class for power management
* 08-Aug-2004 BJD Apply rmk's suggestions * 08-Aug-2004 BJD Apply rmk's suggestions
* 21-Jul-2004 BJD Ported to linux 2.6 * 21-Jul-2004 BJD Ported to linux 2.6
* 12-Jul-2004 BJD Finished re-write and change of API * 12-Jul-2004 BJD Finished re-write and change of API
...@@ -38,6 +40,7 @@ ...@@ -38,6 +40,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -501,6 +504,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, ...@@ -501,6 +504,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_enqueue);
static inline void static inline void
s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf) s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf)
{ {
...@@ -736,6 +741,8 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client, ...@@ -736,6 +741,8 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_request);
/* s3c2410_dma_free /* s3c2410_dma_free
* *
* release the given channel back to the system, will stop and flush * release the given channel back to the system, will stop and flush
...@@ -780,6 +787,8 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) ...@@ -780,6 +787,8 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_free);
static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan) static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -886,6 +895,7 @@ s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op) ...@@ -886,6 +895,7 @@ s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
return -ENOENT; /* unknown, don't bother */ return -ENOENT; /* unknown, don't bother */
} }
EXPORT_SYMBOL(s3c2410_dma_ctrl);
/* DMA configuration for each channel /* DMA configuration for each channel
* *
...@@ -941,6 +951,7 @@ int s3c2410_dma_config(dmach_t channel, ...@@ -941,6 +951,7 @@ int s3c2410_dma_config(dmach_t channel,
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_config);
int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
{ {
...@@ -955,6 +966,9 @@ int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) ...@@ -955,6 +966,9 @@ int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_setflags);
/* do we need to protect the settings of the fields from /* do we need to protect the settings of the fields from
* irq? * irq?
*/ */
...@@ -972,6 +986,8 @@ int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) ...@@ -972,6 +986,8 @@ int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_set_opfn);
int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
{ {
s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
...@@ -985,6 +1001,8 @@ int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) ...@@ -985,6 +1001,8 @@ int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
return 0; return 0;
} }
EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
/* s3c2410_dma_devconfig /* s3c2410_dma_devconfig
* *
* configure the dma source/destination hardware type and address * configure the dma source/destination hardware type and address
...@@ -1042,12 +1060,57 @@ int s3c2410_dma_devconfig(int channel, ...@@ -1042,12 +1060,57 @@ int s3c2410_dma_devconfig(int channel,
return -EINVAL; return -EINVAL;
} }
EXPORT_SYMBOL(s3c2410_dma_devconfig);
/* system device class */
#ifdef CONFIG_PM
static int s3c2410_dma_suspend(struct sys_device *dev, u32 state)
{
s3c2410_dma_chan_t *cp = container_of(dev, s3c2410_dma_chan_t, dev);
printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
/* the dma channel is still working, which is probably
* a bad thing to do over suspend/resume. We stop the
* channel and assume that the client is either going to
* retry after resume, or that it is broken.
*/
printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
cp->number);
s3c2410_dma_dostop(cp);
}
return 0;
}
static int s3c2410_dma_resume(struct sys_device *dev)
{
return 0;
}
#else
#define s3c2410_dma_suspend NULL
#define s3c2410_dma_resume NULL
#endif /* CONFIG_PM */
static struct sysdev_class dma_sysclass = {
set_kset_name("s3c24xx-dma"),
.suspend = s3c2410_dma_suspend,
.resume = s3c2410_dma_resume,
};
/* initialisation code */ /* initialisation code */
static int __init s3c2410_init_dma(void) static int __init s3c2410_init_dma(void)
{ {
int channel;
s3c2410_dma_chan_t *cp; s3c2410_dma_chan_t *cp;
int channel;
int ret;
printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n");
...@@ -1057,6 +1120,12 @@ static int __init s3c2410_init_dma(void) ...@@ -1057,6 +1120,12 @@ static int __init s3c2410_init_dma(void)
return -ENOMEM; return -ENOMEM;
} }
ret = sysdev_class_register(&dma_sysclass);
if (ret != 0) {
printk(KERN_ERR "dma sysclass registration failed\n");
goto err;
}
for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
cp = &s3c2410_chans[channel]; cp = &s3c2410_chans[channel];
...@@ -1075,11 +1144,22 @@ static int __init s3c2410_init_dma(void) ...@@ -1075,11 +1144,22 @@ static int __init s3c2410_init_dma(void)
cp->load_timeout = 1<<18; cp->load_timeout = 1<<18;
/* register system device */
cp->dev.cls = &dma_sysclass;
cp->dev.id = channel;
ret = sysdev_register(&cp->dev);
printk("DMA channel %d at %p, irq %d\n", printk("DMA channel %d at %p, irq %d\n",
cp->number, cp->regs, cp->irq); cp->number, cp->regs, cp->irq);
} }
return 0; return 0;
err:
iounmap(dma_base);
dma_base = NULL;
return ret;
} }
__initcall(s3c2410_init_dma); __initcall(s3c2410_init_dma);
/* linux/include/asm-arm/arch-bast/dma.h /* linux/include/asm-arm/arch-bast/dma.h
* *
* Copyright (C) 2003 Simtec Electronics * Copyright (C) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk> * Ben Dooks <ben@simtec.co.uk>
* *
* Samsung S3C2410X DMA support * Samsung S3C2410X DMA support
* *
...@@ -12,13 +12,14 @@ ...@@ -12,13 +12,14 @@
* Changelog: * Changelog:
* ??-May-2003 BJD Created file * ??-May-2003 BJD Created file
* ??-Jun-2003 BJD Added more dma functionality to go with arch * ??-Jun-2003 BJD Added more dma functionality to go with arch
* 10-Nov-2004 BJD Added sys_device support
*/ */
#ifndef __ASM_ARCH_DMA_H #ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H __FILE__
#include <linux/config.h> #include <linux/config.h>
#include <linux/sysdev.h>
#include "hardware.h" #include "hardware.h"
...@@ -215,6 +216,9 @@ struct s3c2410_dma_chan_s { ...@@ -215,6 +216,9 @@ struct s3c2410_dma_chan_s {
s3c2410_dma_buf_t *curr; /* current dma buffer */ s3c2410_dma_buf_t *curr; /* current dma buffer */
s3c2410_dma_buf_t *next; /* next buffer to load */ s3c2410_dma_buf_t *next; /* next buffer to load */
s3c2410_dma_buf_t *end; /* end of queue */ s3c2410_dma_buf_t *end; /* end of queue */
/* system device */
struct sys_device dev;
}; };
/* the currently allocated channel information */ /* the currently allocated channel information */
...@@ -296,18 +300,46 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); ...@@ -296,18 +300,46 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
#define S3C2410_DMA_DCDST (0x1C) #define S3C2410_DMA_DCDST (0x1C)
#define S3C2410_DMA_DMASKTRIG (0x20) #define S3C2410_DMA_DMASKTRIG (0x20)
#define S3C2410_DISRCC_INC (1<<0)
#define S3C2410_DISRCC_APB (1<<1)
#define S3C2410_DMASKTRIG_STOP (1<<2) #define S3C2410_DMASKTRIG_STOP (1<<2)
#define S3C2410_DMASKTRIG_ON (1<<1) #define S3C2410_DMASKTRIG_ON (1<<1)
#define S3C2410_DMASKTRIG_SWTRIG (1<<0) #define S3C2410_DMASKTRIG_SWTRIG (1<<0)
#define S3C2410_DCOM_DEMAND (0<<31) #define S3C2410_DCON_DEMAND (0<<31)
#define S3C2410_DCON_HANDSHAKE (1<<31) #define S3C2410_DCON_HANDSHAKE (1<<31)
#define S3C2410_DCON_SYNC_PCLK (0<<30) #define S3C2410_DCON_SYNC_PCLK (0<<30)
#define S3C2410_DCON_SYNC_HCLK (1<<30) #define S3C2410_DCON_SYNC_HCLK (1<<30)
#define S3C2410_DCON_INTREQ (1<<29) #define S3C2410_DCON_INTREQ (1<<29)
#define S3C2410_DCON_CH0_XDREQ0 (0<<24)
#define S3C2410_DCON_CH0_UART0 (1<<24)
#define S3C2410_DCON_CH0_SDI (2<<24)
#define S3C2410_DCON_CH0_TIMER (3<<24)
#define S3C2410_DCON_CH0_USBEP1 (4<<24)
#define S3C2410_DCON_CH1_XDREQ1 (0<<24)
#define S3C2410_DCON_CH1_UART1 (1<<24)
#define S3C2410_DCON_CH1_I2SSDI (2<<24)
#define S3C2410_DCON_CH1_SPI (3<<24)
#define S3C2410_DCON_CH1_USBEP2 (4<<24)
#define S3C2410_DCON_CH2_I2SSDO (0<<24)
#define S3C2410_DCON_CH2_I2SSDI (1<<24)
#define S3C2410_DCON_CH2_SDI (2<<24)
#define S3C2410_DCON_CH2_TIMER (3<<24)
#define S3C2410_DCON_CH2_USBEP3 (4<<24)
#define S3C2410_DCON_CH3_UART2 (0<<24)
#define S3C2410_DCON_CH3_SDI (1<<24)
#define S3C2410_DCON_CH3_SPI (2<<24)
#define S3C2410_DCON_CH3_TIMER (3<<24)
#define S3C2410_DCON_CH3_USBEP4 (4<<24)
#define S3C2410_DCON_SRCSHIFT (24) #define S3C2410_DCON_SRCSHIFT (24)
#define S3C2410_DCON_SRCMASK (7<<24)
#define S3C2410_DCON_BYTE (0<<20) #define S3C2410_DCON_BYTE (0<<20)
#define S3C2410_DCON_HALFWORD (1<<20) #define S3C2410_DCON_HALFWORD (1<<20)
...@@ -317,4 +349,20 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); ...@@ -317,4 +349,20 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
#define S3C2410_DCON_NORELOAD (1<<22) #define S3C2410_DCON_NORELOAD (1<<22)
#define S3C2410_DCON_HWTRIG (1<<23) #define S3C2410_DCON_HWTRIG (1<<23)
#ifdef CONFIG_CPU_S3C2440
#define S3C2440_DIDSTC_CHKINT (1<<2)
#define S3C2440_DCON_CH0_I2SSDO (5<<24)
#define S3C2440_DCON_CH0_PCMIN (6<<24)
#define S3C2440_DCON_CH1_PCMOUT (5<<24)
#define S3C2440_DCON_CH1_SDI (6<<24)
#define S3C2440_DCON_CH2_PCMIN (5<<24)
#define S3C2440_DCON_CH2_MICIN (6<<24)
#define S3C2440_DCON_CH3_MICIN (5<<24)
#define S3C2440_DCON_CH3_PCMOUT (6<<24)
#endif
#endif /* __ASM_ARCH_DMA_H */ #endif /* __ASM_ARCH_DMA_H */
...@@ -342,7 +342,7 @@ static inline unsigned long __ffs(unsigned long word) ...@@ -342,7 +342,7 @@ static inline unsigned long __ffs(unsigned long word)
* the clz instruction for much better code efficiency. * the clz instruction for much better code efficiency.
*/ */
extern __inline__ int generic_fls(int x); static __inline__ int generic_fls(int x);
#define fls(x) \ #define fls(x) \
( __builtin_constant_p(x) ? generic_fls(x) : \ ( __builtin_constant_p(x) ? generic_fls(x) : \
({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment