亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? dma-sa1111.c

?? linux-2.4.29操作系統的源碼
?? C
字號:
/* *  linux/arch/arm/mach-sa1100/dma-sa1111.c * *  Copyright (C) 2000 John Dorsey * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation. * *  4 September 2000 - created. */#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/spinlock.h>#include <linux/errno.h>#include <asm/system.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/dma.h>#include <asm/hardware/sa1111.h>// #define DEBUG#ifdef DEBUG#define DPRINTK( s, arg... )  printk( "dma<%s>: " s, dma->device_id , ##arg )#else#define DPRINTK( x... )#endif/* * Control register structure for the SA1111 SAC DMA */typedef struct {	volatile u_long SAD_CS;	volatile dma_addr_t SAD_SA;	volatile u_long SAD_CA;	volatile dma_addr_t SAD_SB;	volatile u_long SAD_CB;} dma_regs_t;#include "dma.h"void sa1111_reset_sac_dma(dmach_t channel){	sa1100_dma_t *dma = &dma_chan[channel];	dma->regs->SAD_CS = 0;	mdelay(1);	dma->dma_a = dma->dma_b = 0;}int start_sa1111_sac_dma(sa1100_dma_t *dma, dma_addr_t dma_ptr, size_t size){  	dma_regs_t *sac_regs = dma->regs;	DPRINTK(" SAC DMA %cCS %02x at %08x (%d)\n",		(sac_regs==&SADTCS)?'T':'R', sac_regs->SAD_CS, dma_ptr, size);	/* The minimum transfer length requirement has not yet been	 * verified:	 */	if( size < SA1111_SAC_DMA_MIN_XFER )	  printk(KERN_WARNING "Warning: SAC xfers below %u bytes may be buggy!"		 " (%u bytes)\n", SA1111_SAC_DMA_MIN_XFER, size);	if( dma->dma_a && dma->dma_b ){	  	DPRINTK("  neither engine available! (A %d, B %d)\n",			dma->dma_a, dma->dma_b);	  	return -1;	}	if( sa1111_check_dma_bug(dma_ptr) )	  	printk(KERN_WARNING "Warning: DMA address %08x is buggy!\n",		       dma_ptr);	if( (dma->last_dma || dma->dma_b) && dma->dma_a == 0 ){	  	if( sac_regs->SAD_CS & SAD_CS_DBDB ){		  	DPRINTK("  awaiting \"done B\" interrupt, not starting\n");			return -1;		}		sac_regs->SAD_SA = SA1111_DMA_ADDR((u_int)dma_ptr);		sac_regs->SAD_CA = size;		sac_regs->SAD_CS = SAD_CS_DSTA | SAD_CS_DEN;		++dma->dma_a;		DPRINTK("  with A [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,			sac_regs->SAD_SA, sac_regs->SAD_CA);	} else {	  	if( sac_regs->SAD_CS & SAD_CS_DBDA ){		  	DPRINTK("  awaiting \"done A\" interrupt, not starting\n");			return -1;		}		sac_regs->SAD_SB = SA1111_DMA_ADDR((u_int)dma_ptr);		sac_regs->SAD_CB = size;		sac_regs->SAD_CS = SAD_CS_DSTB | SAD_CS_DEN;		++dma->dma_b;		DPRINTK("  with B [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,			sac_regs->SAD_SB, sac_regs->SAD_CB);	}	/* Additional delay to avoid DMA engine lockup during record: */	if( sac_regs == (dma_regs_t*)&SADRCS )	  	mdelay(1);	/* NP : wouuuh! ugly... */	return 0;}static void sa1111_sac_dma_irq(int irq, void *dev_id, struct pt_regs *regs){  	sa1100_dma_t *dma = (sa1100_dma_t *) dev_id;	DPRINTK("irq %d, last DMA serviced was %c, CS %02x\n", irq,		dma->last_dma?'B':'A', dma->regs->SAD_CS);	/* Occasionally, one of the DMA engines (A or B) will	 * lock up. We try to deal with this by quietly kicking	 * the control register for the afflicted transfer	 * direction.	 *	 * Note for the debugging-inclined: we currently aren't	 * properly flushing the DMA engines during channel	 * shutdown. A slight hiccup at the beginning of playback	 * after a channel has been stopped can be heard as	 * evidence of this. Programmatically, this shows up	 * as either a locked engine, or a spurious interrupt. -jd	 */	if(irq==AUDXMTDMADONEA || irq==AUDRCVDMADONEA){	  	if(dma->last_dma == 0){		  	DPRINTK("DMA B has locked up!\n");			dma->regs->SAD_CS = 0;			mdelay(1);			dma->dma_a = dma->dma_b = 0;		} else {		  	if(dma->dma_a == 0)			  	DPRINTK("spurious SAC IRQ %d\n", irq);			else {			  	--dma->dma_a;				/* Servicing the SAC DMA engines too quickly				 * after they issue a DONE interrupt causes				 * them to lock up.				 */				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)				  	mdelay(1);			}		}		dma->regs->SAD_CS = SAD_CS_DBDA | SAD_CS_DEN; /* w1c */		dma->last_dma = 0;	} else {	  	if(dma->last_dma == 1){		  	DPRINTK("DMA A has locked up!\n");			dma->regs->SAD_CS = 0;			mdelay(1);			dma->dma_a = dma->dma_b = 0;		} else {		  	if(dma->dma_b == 0)			  	DPRINTK("spurious SAC IRQ %d\n", irq);			else {			  	--dma->dma_b;				/* See lock-up note above. */				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)				  	mdelay(1);			}		}		dma->regs->SAD_CS = SAD_CS_DBDB | SAD_CS_DEN; /* w1c */		dma->last_dma = 1;	}	/* NP: maybe this shouldn't be called in all cases? */	sa1100_dma_done (dma);}int sa1111_sac_request_dma(dmach_t *channel, const char *device_id,			   unsigned int direction){	sa1100_dma_t *dma = NULL;	int ch, irq, err;	*channel = -1;		/* to be sure we catch the freeing of a misregistered channel */	ch = SA1111_SAC_DMA_BASE + direction;	if (!channel_is_sa1111_sac(ch)) {	  	printk(KERN_ERR "%s: invalid SA-1111 SAC DMA channel (%d)\n",		       device_id, ch);		return -1;	}	dma = &dma_chan[ch];	if (xchg(&dma->in_use, 1) == 1) {	  	printk(KERN_ERR "%s: SA-1111 SAC DMA channel %d in use\n",		       device_id, ch);		return -EBUSY;	}	irq = AUDXMTDMADONEA + direction;	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,			  device_id, (void *) dma);	if (err) {		printk(KERN_ERR		       "%s: unable to request IRQ %d for DMA channel %d (A)\n",		       device_id, irq, ch);		dma->in_use = 0;		return err;	}	irq = AUDXMTDMADONEB + direction;	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,			  device_id, (void *) dma);	if (err) {		printk(KERN_ERR		       "%s: unable to request IRQ %d for DMA channel %d (B)\n",		       device_id, irq, ch);		dma->in_use = 0;		return err;	}	*channel = ch;	dma->device_id = device_id;	dma->callback = NULL;	dma->spin_size = 0;	return 0;}/* FIXME:  need to complete the three following functions */int sa1111_dma_get_current(dmach_t channel, void **buf_id, dma_addr_t *addr){	sa1100_dma_t *dma = &dma_chan[channel];	int flags, ret;	local_irq_save(flags);	if (dma->curr && dma->spin_ref <= 0) {		dma_buf_t *buf = dma->curr;		if (buf_id)			*buf_id = buf->id;		/* not fully accurate but still... */		*addr = buf->dma_ptr;		ret = 0;	} else {		if (buf_id)			*buf_id = NULL;		*addr = 0;		ret = -ENXIO;	}	local_irq_restore(flags);	return ret;}int sa1111_dma_stop(dmach_t channel){	return 0;}int sa1111_dma_resume(dmach_t channel){	return 0;}void sa1111_cleanup_sac_dma(dmach_t channel){	sa1100_dma_t *dma = &dma_chan[channel];	free_irq(AUDXMTDMADONEA + (channel - SA1111_SAC_DMA_BASE), (void*) dma);	free_irq(AUDXMTDMADONEB + (channel - SA1111_SAC_DMA_BASE), (void*) dma);}/* According to the "Intel StrongARM SA-1111 Microprocessor Companion * Chip Specification Update" (June 2000), erratum #7, there is a * significant bug in Serial Audio Controller DMA. If the SAC is * accessing a region of memory above 1MB relative to the bank base, * it is important that address bit 10 _NOT_ be asserted. Depending * on the configuration of the RAM, bit 10 may correspond to one * of several different (processor-relative) address bits. * * This routine only identifies whether or not a given DMA address * is susceptible to the bug. */int sa1111_check_dma_bug(dma_addr_t addr){	unsigned int physaddr=SA1111_DMA_ADDR((unsigned int)addr);	/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module	 * User's Guide" mentions that jumpers R51 and R52 control the	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or	 * SDRAM bank 1 on Neponset). The default configuration selects	 * Assabet, so any address in bank 1 is necessarily invalid.	 */	if((machine_is_assabet() || machine_is_pfs168() ||            machine_is_graphicsmaster() || machine_is_adsagc()) && addr >= 0xc8000000)	  	return -1;	/* The bug only applies to buffers located more than one megabyte	 * above the start of the target bank:	 */	if(physaddr<(1<<20))	  	return 0;	switch(FExtr(SBI_SMCR, SMCR_DRAC)){	case 01: /* 10 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	case 02: /* 11 row + bank address bits, A<23> must not be set */	  	if(physaddr & (1<<23))		  	return -1;		break;	case 03: /* 12 row + bank address bits, A<24> must not be set */	  	if(physaddr & (1<<24))		  	return -1;		break;	case 04: /* 13 row + bank address bits, A<25> must not be set */	  	if(physaddr & (1<<25))		  	return -1;		break;	case 05: /* 14 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	case 06: /* 15 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	default:	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n",		       __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));		return -1;	}	return 0;}EXPORT_SYMBOL(sa1111_sac_request_dma);EXPORT_SYMBOL(sa1111_check_dma_bug);static int __init sa1111_init_sac_dma(void){	int channel = SA1111_SAC_DMA_BASE;	dma_chan[channel++].regs = (dma_regs_t *) &SADTCS;	dma_chan[channel++].regs = (dma_regs_t *) &SADRCS;	return 0;}__initcall(sa1111_init_sac_dma);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩dvd在线观看| 亚洲超碰97人人做人人爱| 欧美日韩国产综合一区二区| 福利电影一区二区| 久久99精品国产91久久来源| 天天影视涩香欲综合网| 亚洲欧美另类小说视频| 亚洲男人的天堂av| 一区二区三区在线不卡| 亚洲区小说区图片区qvod| 中文字幕色av一区二区三区| 中文字幕精品三区| 亚洲黄色录像片| 亚洲国产成人av好男人在线观看| 亚洲在线一区二区三区| 亚洲va国产va欧美va观看| 亚洲观看高清完整版在线观看| 三级一区在线视频先锋| 99精品欧美一区二区三区综合在线| 777欧美精品| 亚洲在线一区二区三区| 成人黄色小视频| 国产欧美一区二区精品久导航| 午夜亚洲国产au精品一区二区| 99re免费视频精品全部| 欧美国产综合色视频| 久久成人av少妇免费| 欧美日韩国产综合一区二区 | 久久精品一区四区| 午夜激情久久久| 欧美精品aⅴ在线视频| 一区二区三区四区在线播放 | 国产亚洲福利社区一区| 久久99精品一区二区三区三区| 欧美无人高清视频在线观看| 一区二区免费视频| 欧美日韩成人在线一区| 青青青伊人色综合久久| 欧美高清激情brazzers| 强制捆绑调教一区二区| 日韩一二三四区| 高清不卡在线观看av| 国产精品久久久久久久久动漫| 成人免费观看视频| 亚洲精品乱码久久久久久黑人| 99天天综合性| 日本一区中文字幕| 国产欧美精品一区aⅴ影院| 成人激情视频网站| 亚洲国产精品欧美一二99| 日韩欧美的一区| 97久久久精品综合88久久| 日韩黄色一级片| 国产视频在线观看一区二区三区 | 国产精品456| 欧美日韩aaaaa| 亚洲综合男人的天堂| 国产精品区一区二区三区| 久久久久久**毛片大全| 久久精品视频在线看| 国产日本一区二区| 国产精品美女久久久久av爽李琼| 亚洲国产精品二十页| 国产精品美日韩| 亚洲国产色一区| 国产一区二区三区在线看麻豆| 国产成人精品一区二| 国产黄色91视频| 久久99这里只有精品| 蜜桃av一区二区三区| 午夜av电影一区| 亚洲不卡av一区二区三区| 午夜欧美在线一二页| 亚洲小少妇裸体bbw| 一区二区三区不卡视频| 一个色在线综合| 亚洲国产美国国产综合一区二区| 国产精品久久看| 亚洲美女免费视频| 亚洲影院在线观看| 三级在线观看一区二区| 久久国产三级精品| 成人性色生活片| 欧美日韩在线电影| 精品乱人伦一区二区三区| 久久久无码精品亚洲日韩按摩| 中文字幕久久午夜不卡| 亚洲精品videosex极品| 免费看日韩精品| zzijzzij亚洲日本少妇熟睡| 欧美最猛黑人xxxxx猛交| 日韩一区二区三区观看| 中文字幕视频一区| 久久99久久久久久久久久久| 成人午夜av影视| 日韩精品一区二区三区视频在线观看| 精品日韩在线一区| 亚洲一二三四在线观看| 国产麻豆精品theporn| 欧美日韩国产高清一区| 中文字幕亚洲一区二区av在线| 亚洲国产视频直播| av不卡在线播放| 日本一区二区电影| 精品亚洲国产成人av制服丝袜| 欧美色图免费看| 亚洲男同性视频| 99精品视频一区二区| 国产欧美日韩精品在线| 国产中文字幕精品| 精品久久久久久综合日本欧美| 欧美激情一区二区三区全黄| 青青草一区二区三区| 91精品国产综合久久小美女 | 成人午夜视频免费看| 久久丝袜美腿综合| 久久国产夜色精品鲁鲁99| 欧美巨大另类极品videosbest | 免费观看91视频大全| 欧美美女网站色| 午夜在线电影亚洲一区| 欧美日韩在线播| 日韩国产成人精品| 欧美成人午夜电影| 国产在线一区二区| 久久天天做天天爱综合色| www.亚洲国产| 亚洲欧美一区二区久久| 欧美性感一区二区三区| 偷窥少妇高潮呻吟av久久免费| 555夜色666亚洲国产免| 激情图片小说一区| 亚洲精品中文在线| 欧美日韩的一区二区| 国产激情一区二区三区桃花岛亚洲| 2020国产精品自拍| 一本久久a久久免费精品不卡| 亚洲激情欧美激情| 久久蜜桃av一区二区天堂| 99麻豆久久久国产精品免费优播| 午夜精品久久一牛影视| 国产视频一区二区三区在线观看| 欧美在线不卡一区| 国产乱子伦视频一区二区三区| 亚洲一区二区在线视频| 欧美xxx久久| 欧美日韩激情在线| 色婷婷激情综合| 国产福利视频一区二区三区| 亚洲成人av中文| 一区二区三区欧美视频| 国产无遮挡一区二区三区毛片日本| 欧美区在线观看| 色女孩综合影院| 色婷婷国产精品综合在线观看| 精品一区二区在线视频| 日韩专区欧美专区| 性久久久久久久久| 午夜精品123| 日本人妖一区二区| 精品一区二区三区在线视频| 亚洲bdsm女犯bdsm网站| 青草国产精品久久久久久| 偷窥少妇高潮呻吟av久久免费| 亚洲成人第一页| 九一九一国产精品| 成人精品一区二区三区中文字幕 | 国产精品国产精品国产专区不蜜 | 欧美一区二视频| 亚洲精品在线观| 亚洲精品成人天堂一二三| 老司机午夜精品| 色综合天天综合网国产成人综合天 | 日韩美女精品在线| 一个色在线综合| 国产98色在线|日韩| 91精品国产aⅴ一区二区| 自拍偷在线精品自拍偷无码专区| 亚洲一区二区三区中文字幕 | 国产精品久久久久影视| 亚洲一区二区三区在线播放| 国产美女精品一区二区三区| 91国偷自产一区二区三区观看| 国产精品88av| 日本高清免费不卡视频| 欧美性受xxxx| wwwwww.欧美系列| 一区二区三区在线免费视频| 免播放器亚洲一区| 色婷婷综合久久久久中文 | 中文字幕一区二区三区四区| 亚洲黄色小说网站| 国产一区二区三区精品视频| av在线综合网| 日韩欧美一二三区| 亚洲精品视频自拍| 国产真实乱子伦精品视频| 日本精品裸体写真集在线观看| 欧美一二三区在线观看| 1000部国产精品成人观看|