/* * Core driver for the Synopsys DesignWare DMA Controller * * Copyright (C) 2007-2008 Atmel Corporation * Copyright (C) 2010-2011 ST Microelectronics * Copyright (C) 2013 Intel Corporation * * 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. */#include<linux/bitops.h>#include<linux/delay.h>#include<linux/dmaengine.h>#include<linux/dma-mapping.h>#include<linux/dmapool.h>#include<linux/err.h>#include<linux/init.h>#include<linux/interrupt.h>#include<linux/io.h>#include<linux/mm.h>#include<linux/module.h>#include<linux/slab.h>#include<linux/pm_runtime.h>#include"../dmaengine.h"#include"internal.h"/* * This supports the Synopsys "DesignWare AHB Central DMA Controller", * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all * of which use ARM any more). See the "Databook" from Synopsys for * information beyond what licensees probably provide. * * The driver has been tested with the Atmel AT32AP7000, which does not * support descriptor writeback. */#define DWC_DEFAULT_CTLLO(_chan) ({ \ struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \ struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ bool _is_slave = is_slave_direction(_dwc->direction); \ u8 _smsize = _is_slave ? _sconfig->src_maxburst : \ DW_DMA_MSIZE_16; \ u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \ DW_DMA_MSIZE_16; \ u8 _dms = (_dwc->direction == DMA_MEM_TO_DEV) ? \ _dwc->dws.p_master : _dwc->dws.m_master; \ u8 _sms = (_dwc->direction == DMA_DEV_TO_MEM) ? \ _dwc->dws.p_master : _dwc->dws.m_master; \ \ (DWC_CTLL_DST_MSIZE(_dmsize) \ | DWC_CTLL_SRC_MSIZE(_smsize) \ | DWC_CTLL_LLP_D_EN \ | DWC_CTLL_LLP_S_EN \ | DWC_CTLL_DMS(_dms) \ | DWC_CTLL_SMS(_sms)); \ })/* The set of bus widths supported by the DMA controller */#define DW_DMA_BUSWIDTHS \ BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)/*----------------------------------------------------------------------*/staticstructdevice*chan2dev(structdma_chan*chan){return&chan->dev->device;}staticstructdw_desc*dwc_first_active(structdw_dma_chan*dwc){returnto_dw_desc(dwc->active_list.next);}staticdma_cookie_tdwc_tx_submit(structdma_async_tx_descriptor*tx){structdw_desc*desc=txd_to_dw_desc(tx