summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch2469
1 files changed, 0 insertions, 2469 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch
deleted file mode 100644
index d539b6092..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-langwell-dma-driver-3.0.patch
+++ /dev/null
@@ -1,2469 +0,0 @@
-Index: linux-2.6.33/drivers/dma/Kconfig
-===================================================================
---- linux-2.6.33.orig/drivers/dma/Kconfig
-+++ linux-2.6.33/drivers/dma/Kconfig
-@@ -20,6 +20,37 @@ comment "DMA Devices"
- config ASYNC_TX_DISABLE_CHANNEL_SWITCH
- bool
-
-+config INTEL_LNW_DMAC1
-+ bool "Intel MID DMA support for LPE DMA"
-+ depends on PCI && X86 && (SND_INTEL_SST||SND_INTEL_LPE)
-+ select DMA_ENGINE
-+ help
-+ Enable support for the Intel(R) MID DMA1 engine present
-+ in Intel MID chipsets.
-+
-+ Say Y here if you have such a chipset.
-+
-+ If unsure, say N.
-+
-+config INTEL_LNW_DMAC2
-+ bool "Intel MID DMA support for SC DMA"
-+ depends on PCI && X86
-+ select DMA_ENGINE
-+ help
-+ Enable support for the Intel(R) MID DMA2 engine present
-+ in Intel MID chipsets.
-+
-+ Say Y here if you have such a chipset.
-+
-+ If unsure, say N.
-+
-+config LNW_DMA_DEBUG
-+ bool "LNW DMA Debugging Enable"
-+ depends on INTEL_LNW_DMAC1 || INTEL_LNW_DMAC2
-+ default N
-+ help
-+ Enable logging in the LNW DMA drivers
-+
- config INTEL_IOATDMA
- tristate "Intel I/OAT DMA support"
- depends on PCI && X86
-Index: linux-2.6.33/drivers/dma/Makefile
-===================================================================
---- linux-2.6.33.orig/drivers/dma/Makefile
-+++ linux-2.6.33/drivers/dma/Makefile
-@@ -1,5 +1,7 @@
- obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
- obj-$(CONFIG_NET_DMA) += iovlock.o
-+obj-$(CONFIG_INTEL_LNW_DMAC2) += lnw_dmac2.o
-+obj-$(CONFIG_INTEL_LNW_DMAC1) += lnw_dmac1.o
- obj-$(CONFIG_DMATEST) += dmatest.o
- obj-$(CONFIG_INTEL_IOATDMA) += ioat/
- obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
-Index: linux-2.6.33/drivers/dma/lnw_dma_regs.h
-===================================================================
---- /dev/null
-+++ linux-2.6.33/drivers/dma/lnw_dma_regs.h
-@@ -0,0 +1,176 @@
-+/*
-+ * lnw_dma.c - Intel Langwell DMA Drivers
-+ *
-+ * Copyright (C) 2008-09 Intel Corp
-+ * Author: Vinod Koul <vinod.koul@intel.com>
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * 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; version 2 of the License.
-+ *
-+ * 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, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ *
-+ */
-+#ifndef __LNW_DMA_REGS_H__
-+#define __LNW_DMA_REGS_H__
-+
-+#include <linux/dmaengine.h>
-+#include <linux/dmapool.h>
-+#include <linux/pci_ids.h>
-+
-+#define LNW_DMA_DRIVER_VERSION "0.3.1"
-+
-+#define DMA_DEBUG
-+
-+#define REG_BIT0 0x00000001
-+#define REG_BIT8 0x00000100
-+
-+#define UNMASK_INTR_REG(chan_num) \
-+ ((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num))
-+#define MASK_INTR_REG(chan_num) (REG_BIT8 << chan_num)
-+
-+#define ENABLE_CHANNEL(chan_num) \
-+ ((REG_BIT0 << chan_num) | (REG_BIT8 << chan_num))
-+
-+#define DESCS_PER_CHANNEL 16
-+/*DMA Registers*/
-+/*registers associated with channel programming*/
-+#define DMA_REG_SIZE 0x400
-+#define DMA_CH_SIZE 0x58
-+
-+/*CH X REG = (DMA_CH_SIZE)*CH_NO + REG*/
-+#define SAR 0x00 /* Source Address Register*/
-+#define DAR 0x08 /* Destination Address Register*/
-+#define CTL_LOW 0x18 /* Control Register*/
-+#define CTL_HIGH 0x1C /* Control Register*/
-+#define CFG_LOW 0x40 /* Configuration Register Low*/
-+#define CFG_HIGH 0x44 /* Configuration Register high*/
-+
-+#define STATUS_TFR 0x2E8
-+#define STATUS_BLOCK 0x2F0
-+#define STATUS_ERR 0x308
-+
-+#define RAW_TFR 0x2C0
-+#define RAW_BLOCK 0x2C8
-+#define RAW_ERR 0x2E0
-+
-+#define MASK_TFR 0x310
-+#define MASK_BLOCK 0x318
-+#define MASK_SRC_TRAN 0x320
-+#define MASK_DST_TRAN 0x328
-+#define MASK_ERR 0x330
-+
-+#define CLEAR_TFR 0x338
-+#define CLEAR_BLOCK 0x340
-+#define CLEAR_SRC_TRAN 0x348
-+#define CLEAR_DST_TRAN 0x350
-+#define CLEAR_ERR 0x358
-+
-+#define INTR_STATUS 0x360
-+#define DMA_CFG 0x398
-+#define DMA_CHAN_EN 0x3A0
-+
-+/**
-+ * struct lnw_dma_chan - internal representation of a DMA channel
-+ */
-+struct lnw_dma_chan {
-+ struct dma_chan chan;
-+ void __iomem *ch_regs;
-+ void __iomem *dma_base;
-+ int ch_id;
-+ spinlock_t lock;
-+ dma_cookie_t completed;
-+ struct list_head active_list;
-+ struct list_head queue;
-+ struct list_head free_list;
-+ struct lnw_dma_slave *slave;
-+ unsigned int descs_allocated;
-+ struct lnwdma_device *dma;
-+ bool in_use;
-+};
-+static inline struct lnw_dma_chan *to_lnw_dma_chan(struct dma_chan *chan)
-+{
-+ return container_of(chan, struct lnw_dma_chan, chan);
-+}
-+
-+/**
-+ * struct lnwdma_device - internal representation of a DMA device
-+ * @pdev: PCI device
-+ * @dma_base: MMIO register space base address of DMA
-+ * @lpe_base: MMIO register space base address of LPE
-+ * @dma_pool: for allocating DMA descriptors
-+ * @common: embedded struct dma_device
-+ * @idx: per channel data
-+ */
-+struct lnwdma_device {
-+ struct pci_dev *pdev;
-+ void __iomem *dma_base;
-+ struct pci_pool *dma_pool;
-+ struct dma_device common;
-+ struct tasklet_struct tasklet;
-+ struct lnw_dma_chan ch[MAX_CHAN];
-+};
-+
-+static inline struct lnwdma_device *to_lnwdma_device(struct dma_device *common)
-+{
-+ return container_of(common, struct lnwdma_device, common);
-+}
-+
-+struct lnw_dma_desc {
-+ void __iomem *block; /*ch ptr*/
-+ struct list_head desc_node;
-+ struct dma_async_tx_descriptor txd;
-+ size_t len;
-+ dma_addr_t sar;
-+ dma_addr_t dar;
-+ u32 cfg_hi;
-+ u32 cfg_lo;
-+ u32 ctl_lo;
-+ u32 ctl_hi;
-+ dma_addr_t next;
-+ enum dma_data_direction dirn;
-+ enum dma_status status;
-+ dma_async_tx_callback callback;
-+ void *callback_param;
-+ enum lnw_dma_width width; /*width of DMA txn*/
-+ enum lnw_dma_mode cfg_mode; /*mode configuration*/
-+
-+};
-+
-+static inline int test_ch_en(void __iomem *dma, u32 ch_no)
-+{
-+ u32 en_reg = ioread32(dma + DMA_CHAN_EN);
-+ return (en_reg >> ch_no) & 0x1;
-+}
-+
-+static inline struct lnw_dma_desc *to_lnw_dma_desc
-+ (struct dma_async_tx_descriptor *txd)
-+{
-+ return container_of(txd, struct lnw_dma_desc, txd);
-+}
-+
-+#define _dma_printk(level, format, arg...) \
-+ printk(level "LNW_DMA: %s %d " format, __func__, __LINE__, ## arg)
-+
-+#ifdef CONFIG_LNW_DMA_DEBUG
-+#define dma_dbg(format, arg...) _dma_printk(KERN_DEBUG, "DBG " format , ## arg)
-+#else
-+#define dma_dbg(format, arg...) do {} while (0);
-+#endif
-+
-+#define dma_err(format, arg...) _dma_printk(KERN_ERR, "ERR " format , ## arg)
-+#define dma_info(format, arg...) \
-+ _dma_printk(KERN_INFO , "INFO " format , ## arg)
-+
-+#endif /*__LNW_DMA_REGS_H__*/
-Index: linux-2.6.33/drivers/dma/lnw_dmac1.c
-===================================================================
---- /dev/null
-+++ linux-2.6.33/drivers/dma/lnw_dmac1.c
-@@ -0,0 +1,957 @@
-+/*
-+ * lnw_dmac1.c - Intel Langwell DMA Drivers
-+ *
-+ * Copyright (C) 2008-09 Intel Corp
-+ * Authhor: Vinod Koul <vinod.koul@intel.com>
-+ * The driver design is based on dw_dmac driver
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * 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; version 2 of the License.
-+ *
-+ * 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, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ *
-+ */
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include <sound/intel_lpe.h>
-+#include <linux/lnw_dma.h>
-+
-+#define MAX_CHAN 2
-+#include "lnw_dma_regs.h"
-+
-+MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-+MODULE_DESCRIPTION("Intel (R) Moorestown Langwell DMAC1 Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_VERSION(LNW_DMA_DRIVER_VERSION);
-+
-+#define DMA_CH0 6
-+#define DMA_CH1 7
-+#define CH_BLOCK_SIZE 4095
-+
-+static int __devinit lnw_dma1_probe(struct pci_dev *pdev,
-+ const struct pci_device_id *id);
-+static void __devexit lnw_dma1_remove(struct pci_dev *pdev);
-+static void enable_dma1_interrupt(struct lnw_dma_chan *lnwc);
-+static void disable_dma1_interrupt(struct lnw_dma_chan *lnwc);
-+
-+struct lnw_device {
-+ struct pci_dev *pdev;
-+ void __iomem *dma_base;
-+ struct lnwdma_device *dma;
-+};
-+
-+/*CH dep code, if ch no's mapping changes only change here*/
-+static int get_ch_id(int index)
-+{
-+ if (index == 0)
-+ return DMA_CH0;
-+ else if (index == 1)
-+ return DMA_CH1;
-+ else
-+ return -1;
-+}
-+
-+static int get_ch_index(int ch_id)
-+{
-+ if (ch_id == DMA_CH0)
-+ return 0;
-+ if (ch_id == DMA_CH1)
-+ return 1;
-+ else
-+ return -1;
-+}
-+
-+static int get_ch_num(int *status)
-+{
-+ if (*status & (1 << DMA_CH0)) {
-+ *status = *status & (~(1 << DMA_CH0));
-+ return DMA_CH0;
-+ } else if (*status & (1 << DMA_CH1)) {
-+ *status = *status & (~(1 << DMA_CH1));
-+ return DMA_CH1;
-+ } else
-+ return -1;
-+}
-+
-+static int get_block_ts(int len, int tx_width)
-+{
-+ int byte_width = 0, block_ts = 0;
-+
-+ switch (tx_width) {
-+ case LNW_DMA_WIDTH_8BIT:
-+ byte_width = 1;
-+ break;
-+ case LNW_DMA_WIDTH_16BIT:
-+ byte_width = 2;
-+ break;
-+ case LNW_DMA_WIDTH_32BIT:
-+ default:
-+ byte_width = 4;
-+ break;
-+ }
-+
-+ block_ts = len/byte_width;
-+ if (block_ts > CH_BLOCK_SIZE)
-+ block_ts = 0xFFFF;
-+ return block_ts;
-+}
-+
-+static struct lnw_dma_desc *lnwc_desc_get1(struct lnw_dma_chan *lnwc)
-+{
-+ struct lnw_dma_desc *desc, *_desc;
-+ struct lnw_dma_desc *ret = NULL;
-+
-+ dma_dbg("called \n");
-+ spin_lock_bh(&lnwc->lock);
-+ list_for_each_entry_safe(desc, _desc, &lnwc->free_list, desc_node) {
-+ if (async_tx_test_ack(&desc->txd)) {
-+ list_del(&desc->desc_node);
-+ ret = desc;
-+ dma_dbg("got free desc \n");
-+ break;
-+ }
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ return ret;
-+}
-+
-+
-+static void lnwc_desc_put1(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *desc)
-+{
-+ if (desc) {
-+ spin_lock_bh(&lnwc->lock);
-+ list_add_tail(&desc->desc_node, &lnwc->free_list);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+}
-+
-+/* Called with dwc->lock held and bh disabled */
-+static void lnwc_dostart1(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *first)
-+{
-+ struct lnwdma_device *lnw = to_lnwdma_device(lnwc->chan.device);
-+
-+ dma_dbg("called \n");
-+ /* ASSERT: channel is idle */
-+ if (lnwc->in_use && test_ch_en(lnwc->dma_base, lnwc->ch_id)) {
-+ /*error*/
-+ dma_err("channel is busy \n");
-+ /* The tasklet will hopefully advance the queue... */
-+ return;
-+ }
-+
-+ /*write registers and en*/
-+ iowrite32(first->sar, lnwc->ch_regs + SAR);
-+ iowrite32(first->dar, lnwc->ch_regs + DAR);
-+ iowrite32(first->cfg_hi, lnwc->ch_regs + CFG_HIGH);
-+ iowrite32(first->cfg_lo, lnwc->ch_regs + CFG_LOW);
-+ iowrite32(first->ctl_lo, lnwc->ch_regs + CTL_LOW);
-+ iowrite32(first->ctl_hi, lnwc->ch_regs + CTL_HIGH);
-+ dma_dbg("TX SAR %lx, DAR %lx, CFGL %x, CFGH %x, CTLH %x, CTLL %x \n",
-+ first->sar, first->dar, first->cfg_hi,
-+ first->cfg_lo, first->ctl_hi, first->ctl_lo);
-+
-+ iowrite32(ENABLE_CHANNEL(lnwc->ch_id), lnw->dma_base + DMA_CHAN_EN);
-+ first->status = DMA_IN_PROGRESS;
-+}
-+
-+static void
-+lnwc_descriptor_complete1(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *desc)
-+{
-+ struct dma_async_tx_descriptor *txd = &desc->txd;
-+ dma_async_tx_callback callback = NULL;
-+ dma_async_tx_callback callback_txd = NULL;
-+ void *param = NULL;
-+ void *param_txd = NULL;
-+ u32 sar, dar, len;
-+ union lnw_dma_ctl_hi ctl_hi;
-+
-+ dma_dbg("called \n");
-+
-+ /*check if full tx is complete or not*/
-+ sar = ioread32(lnwc->ch_regs + SAR);
-+ dar = ioread32(lnwc->ch_regs + DAR);
-+
-+ if (desc->dirn == DMA_FROM_DEVICE)
-+ len = dar - desc->dar;
-+ else
-+ len = sar - desc->sar;
-+
-+ dma_dbg("SAR %x DAR %x, DMA done: %x \n", sar, dar, len);
-+ if (desc->len > len) {
-+ dma_dbg("dirn = %d\n", desc->dirn);
-+ dma_dbg("SAR %x DAR %x, len: %x \n", sar, dar, len);
-+ /*we have to copy more bytes*/
-+ desc->len -= len;
-+ ctl_hi.ctl_hi = desc->ctl_hi;
-+ ctl_hi.ctlx.block_ts = get_block_ts(desc->len, desc->width);
-+ dma_dbg("setting for %x bytes \n", ctl_hi.ctlx.block_ts);
-+ desc->ctl_hi = ctl_hi.ctl_hi;
-+ if (desc->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ sar++;
-+ dar++;
-+ } else if (desc->dirn == DMA_TO_DEVICE)
-+ sar++;
-+ else if (desc->dirn == DMA_FROM_DEVICE)
-+ dar++;
-+ desc->sar = sar;
-+ desc->dar = dar;
-+ dma_dbg("New SAR %x DAR %x \n", sar, dar);
-+ lnwc_dostart1(lnwc, desc);
-+ return;
-+ }
-+
-+ lnwc->completed = txd->cookie;
-+ callback = desc->callback;
-+ param = desc->callback_param;
-+ callback_txd = txd->callback;
-+ param_txd = txd->callback_param;
-+
-+ list_move(&desc->desc_node, &lnwc->free_list);
-+
-+ spin_unlock_bh(&lnwc->lock);
-+ dma_dbg("Now we are calling callback \n");
-+ if (callback_txd) {
-+ dma_dbg("lnw TXD callback set ... calling \n");
-+ callback_txd(param_txd);
-+ spin_lock_bh(&lnwc->lock);
-+ return;
-+ }
-+ if (callback) {
-+ dma_dbg("lnw callback set ... calling \n");
-+ callback(param);
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+}
-+
-+/*check desc, mark as complete when tx is complete*/
-+static void
-+lnwc_scan_descriptors1(struct lnwdma_device *lnw, struct lnw_dma_chan *lnwc)
-+{
-+ struct lnw_dma_desc *desc = NULL, *_desc = NULL;
-+ u32 status_xfer;
-+
-+ dma_dbg("called \n");
-+ status_xfer = ioread32(lnwc->dma_base + RAW_BLOCK);
-+ status_xfer = (status_xfer >> lnwc->ch_id) & 0x1;
-+ dma_dbg("ch[%d]: status_xfer %x \n", lnwc->ch_id, status_xfer);
-+ if (!status_xfer)
-+ return;
-+
-+ list_for_each_entry_safe(desc, _desc, &lnwc->active_list, desc_node) {
-+ if (desc == NULL)
-+ continue;
-+ if (desc->status == DMA_IN_PROGRESS) {
-+ desc->status = DMA_SUCCESS;
-+ lnwc_descriptor_complete1(lnwc, desc);
-+ }
-+ }
-+ return;
-+}
-+
-+/*****************************************************************************
-+DMA Functions*/
-+static dma_cookie_t lnw_dma1_tx_submit(struct dma_async_tx_descriptor *tx)
-+{
-+ struct lnw_dma_desc *desc = to_lnw_dma_desc(tx);
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(tx->chan);
-+ dma_cookie_t cookie;
-+
-+ dma_dbg("called \n");
-+ spin_lock_bh(&lnwc->lock);
-+ cookie = lnwc->chan.cookie;
-+
-+ if (++cookie < 0)
-+ cookie = 1;
-+
-+ lnwc->chan.cookie = cookie;
-+ desc->txd.cookie = cookie;
-+
-+
-+ if (list_empty(&lnwc->active_list)) {
-+ lnwc_dostart1(lnwc, desc);
-+ list_add_tail(&desc->desc_node, &lnwc->active_list);
-+ } else {
-+ list_add_tail(&desc->desc_node, &lnwc->queue);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+
-+ return cookie;
-+}
-+
-+static void lnw_dma1_issue_pending(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+
-+ spin_lock_bh(&lnwc->lock);
-+ if (!list_empty(&lnwc->queue))
-+ lnwc_scan_descriptors1(to_lnwdma_device(chan->device), lnwc);
-+ spin_unlock_bh(&lnwc->lock);
-+}
-+
-+static enum dma_status
-+lnw_dma1_tx_is_complete(struct dma_chan *chan,
-+ dma_cookie_t cookie,
-+ dma_cookie_t *done,
-+ dma_cookie_t *used)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ dma_cookie_t last_used;
-+ dma_cookie_t last_complete;
-+ int ret;
-+
-+ last_complete = lnwc->completed;
-+ last_used = chan->cookie;
-+
-+ ret = dma_async_is_complete(cookie, last_complete, last_used);
-+ if (ret != DMA_SUCCESS) {
-+ lnwc_scan_descriptors1(to_lnwdma_device(chan->device), lnwc);
-+
-+ last_complete = lnwc->completed;
-+ last_used = chan->cookie;
-+
-+ ret = dma_async_is_complete(cookie, last_complete, last_used);
-+ }
-+
-+ if (done)
-+ *done = last_complete;
-+ if (used)
-+ *used = last_used;
-+
-+ return ret;
-+}
-+
-+static void lnw_dma1_terminate_all(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc, *_desc;
-+ LIST_HEAD(list);
-+
-+ /* ASSERT: channel is idle */
-+ if (lnwc->in_use == false) {
-+ /*ch is not in use, wrong call*/
-+ return;
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+ list_splice_init(&lnwc->free_list, &list);
-+ lnwc->descs_allocated = 0;
-+ lnwc->slave = NULL;
-+
-+ /* Disable interrupts */
-+ disable_dma1_interrupt(lnwc);
-+
-+ spin_unlock_bh(&lnwc->lock);
-+ list_for_each_entry_safe(desc, _desc, &list, desc_node) {
-+ dma_dbg("freeing descriptor %p\n", desc);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ return;
-+}
-+
-+static struct dma_async_tx_descriptor *
-+lnw_dma1_prep_slave_sg(struct dma_chan *chan,
-+ struct scatterlist *sgl, unsigned int sg_len,
-+ enum dma_data_direction direction,
-+ unsigned long flags)
-+{
-+ /*not supported now*/
-+ return NULL;
-+}
-+
-+static struct dma_async_tx_descriptor *
-+lnw_dma1_prep_memcpy(struct dma_chan *chan, dma_addr_t dest,
-+ dma_addr_t src, size_t len, unsigned long flags)
-+{
-+ struct lnw_dma_chan *lnwc;
-+ struct lnw_dma_desc *desc = NULL;
-+ struct lnw_dma_slave *lnws;
-+ union lnw_dma_ctl_lo ctl_lo;
-+ union lnw_dma_ctl_hi ctl_hi;
-+ union lnw_dma_cfg_lo cfg_lo;
-+ union lnw_dma_cfg_hi cfg_hi;
-+ enum lnw_dma_width width = 0;
-+
-+ dma_dbg("called \n");
-+ WARN_ON(!chan);
-+ if (!len)
-+ return NULL;
-+
-+ lnws = chan->private;
-+ WARN_ON(!lnws);
-+
-+ lnwc = to_lnw_dma_chan(chan);
-+ WARN_ON(!lnwc);
-+
-+ dma_dbg("called for CH %d\n", lnwc->ch_id);
-+ dma_dbg("Cfg passed Mode %x, Dirn %x, HS %x, Width %x \n",
-+ lnws->cfg_mode, lnws->dirn, lnws->hs_mode, lnws->src_width);
-+
-+ /*calculate CFG_LO*/
-+ if (lnws->hs_mode == LNW_DMA_SW_HS) {
-+ cfg_lo.cfg_lo = 0;
-+ cfg_lo.cfgx.hs_sel_dst = 1;
-+ cfg_lo.cfgx.hs_sel_src = 1;
-+ } else if (lnws->hs_mode == LNW_DMA_HW_HS)
-+ cfg_lo.cfg_lo = 0x00000;
-+
-+ /*calculate CFG_HI*/
-+ if (lnws->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ /*SW HS only*/
-+ dma_dbg("CFG: Mem to mem dma \n");
-+ cfg_hi.cfg_hi = 0;
-+ } else {
-+ dma_dbg("HW DMA \n");
-+ cfg_hi.cfg_hi = 0;
-+ cfg_hi.cfgx.protctl = 0x0; /*default value*/
-+ cfg_hi.cfgx.fifo_mode = 1;
-+ if (lnws->dirn == DMA_TO_DEVICE) {
-+ cfg_hi.cfgx.src_per = 0;
-+ cfg_hi.cfgx.dst_per = 3;
-+ } else if (lnws->dirn == DMA_FROM_DEVICE) {
-+ cfg_hi.cfgx.src_per = 2;
-+ cfg_hi.cfgx.dst_per = 0;
-+ }
-+ }
-+
-+ /*calculate CTL_HI*/
-+ ctl_hi.ctlx.reser = 0;
-+ width = lnws->src_width;
-+
-+ ctl_hi.ctlx.block_ts = get_block_ts(len, width);
-+
-+ /*calculate CTL_LO*/
-+ ctl_lo.ctl_lo = 0;
-+ ctl_lo.ctlx.int_en = 1;
-+ ctl_lo.ctlx.dst_tr_width = lnws->dst_width;
-+ ctl_lo.ctlx.src_tr_width = lnws->src_width;
-+ ctl_lo.ctlx.dst_msize = lnws->src_msize;
-+ ctl_lo.ctlx.src_msize = lnws->dst_msize;
-+
-+ if (lnws->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ dma_dbg("CTL: Mem to mem dma \n");
-+ ctl_lo.ctlx.tt_fc = 0;
-+ ctl_lo.ctlx.sinc = 0;
-+ ctl_lo.ctlx.dinc = 0;
-+ } else {
-+ if (lnws->dirn == DMA_TO_DEVICE) {
-+ dma_dbg("CTL: DMA_TO_DEVICE \n");
-+ ctl_lo.ctlx.sinc = 0;
-+ ctl_lo.ctlx.dinc = 2;
-+ ctl_lo.ctlx.tt_fc = 1;
-+ } else if (lnws->dirn == DMA_FROM_DEVICE) {
-+ dma_dbg("CTL: DMA_FROM_DEVICE \n");
-+ ctl_lo.ctlx.sinc = 2;
-+ ctl_lo.ctlx.dinc = 0;
-+ ctl_lo.ctlx.tt_fc = 2;
-+ }
-+ }
-+
-+ dma_dbg("Calc CTL LO %x, CTL HI %x, CFG LO %x, CFG HI %x\n",
-+ ctl_lo.ctl_lo, ctl_hi.ctl_hi, cfg_lo.cfg_lo, cfg_hi.cfg_hi);
-+
-+ enable_dma1_interrupt(lnwc);
-+
-+ desc = lnwc_desc_get1(lnwc);
-+ if (desc == NULL)
-+ goto err_desc_get;
-+ desc->sar = src;
-+ desc->dar = dest ;
-+ desc->len = len;
-+ desc->cfg_hi = cfg_hi.cfg_hi;
-+ desc->cfg_lo = cfg_lo.cfg_lo;
-+ desc->ctl_lo = ctl_lo.ctl_lo;
-+ desc->ctl_hi = ctl_hi.ctl_hi;
-+ desc->width = width;
-+ desc->dirn = lnws->dirn;
-+ if (lnws->callback) {
-+ desc->callback = lnws->callback;
-+ desc->callback_param = lnws->callback_param;
-+ dma_dbg("Callback passed... setting\n");
-+ } else
-+ desc->callback = NULL;
-+ return &desc->txd;
-+
-+err_desc_get:
-+ dma_err("Failed to get desc \n");
-+ lnwc_desc_put1(lnwc, desc);
-+ return NULL;
-+}
-+
-+static void lnw_dma1_free_chan_resources(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc, *_desc;
-+
-+ dma_dbg("..called for ch_id %d, lnwch_id %d\n",
-+ chan->chan_id, lnwc->ch_id);
-+ if (true == lnwc->in_use) {
-+ /*trying to free ch in use!!!!!*/
-+ dma_err("trying to free ch in use \n");
-+ }
-+
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc->descs_allocated = 0;
-+ list_for_each_entry_safe(desc, _desc, &lnwc->active_list, desc_node) {
-+ dma_dbg("del active \n");
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ list_for_each_entry_safe(desc, _desc, &lnwc->free_list, desc_node) {
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ list_for_each_entry_safe(desc, _desc, &lnwc->queue, desc_node) {
-+ dma_dbg("del queue \n");
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ lnwc->in_use = false;
-+ chan->client_count--;
-+ /* Disable CH interrupts */
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_ERR);
-+ dma_dbg("done \n");
-+}
-+
-+static int lnw_dma1_alloc_chan_resources(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc;
-+ dma_addr_t phys;
-+ int i = 0;
-+
-+ dma_dbg("called \n");
-+
-+ /* ASSERT: channel is idle */
-+ if (test_ch_en(lnw->dma_base, lnwc->ch_id)) {
-+ /*ch is not idle*/
-+ dma_err(".ch not idle\n");
-+ return -EIO;
-+ }
-+ dma_dbg("..called for ch_id %d, lnwch_id %d\n",
-+ chan->chan_id, lnwc->ch_id);
-+ lnwc->completed = chan->cookie = 1;
-+
-+ chan->client_count++;
-+
-+ spin_lock_bh(&lnwc->lock);
-+ while (lnwc->descs_allocated < DESCS_PER_CHANNEL) {
-+ spin_unlock_bh(&lnwc->lock);
-+ desc = pci_pool_alloc(lnw->dma_pool, GFP_KERNEL, &phys);
-+ if (!desc) {
-+ dma_err("desc failed\n");
-+ return -ENOMEM;
-+ /*check*/
-+ }
-+ dma_async_tx_descriptor_init(&desc->txd, chan);
-+ desc->txd.tx_submit = lnw_dma1_tx_submit;
-+ desc->txd.flags = DMA_CTRL_ACK;
-+ desc->txd.phys = phys;
-+ spin_lock_bh(&lnwc->lock);
-+ i = ++lnwc->descs_allocated;
-+ list_add_tail(&desc->desc_node, &lnwc->free_list);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ lnwc->in_use = false;
-+ dma_dbg("Desc alloc done ret: %d desc\n", i);
-+ return i;
-+}
-+
-+static void lnwc_handle_error1(struct lnwdma_device *lnw,
-+ struct lnw_dma_chan *lnwc)
-+{
-+ lnwc_scan_descriptors1(lnw, lnwc);
-+}
-+
-+/******************************************************************************
-+* PCI stuff
-+*/
-+static struct pci_device_id lnw_dma1_ids[] = {
-+ { PCI_VENDOR_ID_INTEL, 0x0814, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+ { 0, }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, lnw_dma1_ids);
-+
-+static struct pci_driver lnw_dma1_pci = {
-+ .name = "Intel LNW DMA1",
-+ .id_table = lnw_dma1_ids,
-+ .probe = lnw_dma1_probe,
-+ .remove = __devexit_p(lnw_dma1_remove),
-+};
-+
-+static void dma_tasklet1(unsigned long data)
-+{
-+ struct lnwdma_device *lnw = NULL;
-+ struct lnw_dma_chan *lnwc = NULL;
-+ u32 status;
-+ int i, ch_no;
-+
-+ dma_dbg("called \n");
-+ lnw = (struct lnwdma_device *)data;
-+ if (lnw == NULL) {
-+ dma_err("Null param \n");
-+ return;
-+ }
-+ status = ioread32(lnw->dma_base + RAW_BLOCK);
-+ dma_dbg("RAW_TFR %x \n", status);
-+ status &= 0xC0;
-+ while (status) {
-+ /*txn interrupt*/
-+ ch_no = get_ch_num(&status);
-+ if (ch_no < 0) {
-+ dma_err("Ch no is invalid %x, abort!\n", ch_no);
-+ return;
-+ }
-+ dma_dbg("Got Ch %x, new Status %x \n", ch_no, status);
-+ i = get_ch_index(ch_no);
-+ if (i < 0) {
-+ dma_err("Invalid ch index %x\n", i);
-+ return;
-+ }
-+ dma_dbg("Tx complete interrupt %x, Ch No %d Index %d \n",
-+ status, ch_no, i);
-+ lnwc = &lnw->ch[i];
-+ if (lnwc == NULL) {
-+ dma_err("Null param lnwc\n");
-+ return;
-+ }
-+ dma_dbg("CH %x \n", lnwc->ch_id);
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc_scan_descriptors1(lnw, lnwc);
-+ dma_dbg("Scan of desc... complete, unmasking\n");
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_TFR);
-+ dma_dbg("Wrote to clear %x\n", (1 << lnwc->ch_id));
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_BLOCK);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id),
-+ lnw->dma_base + MASK_TFR);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+
-+ dma_dbg("Trf interrupt done... \n");
-+ status = ioread32(lnw->dma_base + RAW_ERR);
-+ status &= 0xC0;
-+ while (status) {
-+ /*err interrupt*/
-+ ch_no = get_ch_num(&status);
-+ if (ch_no < 0) {
-+ dma_err("Ch no is invalid %x, abort!\n", ch_no);
-+ return;
-+ }
-+ dma_dbg("Got Ch %x, new Status %x \n", ch_no, status);
-+ i = get_ch_index(ch_no);
-+ if (i < 0) {
-+ dma_err("Invalid CH lnwc\n");
-+ return;
-+ }
-+ dma_dbg("Tx error interrupt %x, No %d Index %d \n",
-+ status, ch_no, i);
-+ lnwc = &lnw->ch[i];
-+ if (lnwc == NULL) {
-+ dma_err("Null param lnwc\n");
-+ return;
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc_handle_error1(lnw, lnwc);
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_ERR);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id),
-+ lnw->dma_base + MASK_ERR);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+ dma_dbg("Exiting takslet... \n");
-+ return;
-+}
-+
-+static irqreturn_t lnw_dma1_interrupt(int irq, void *data)
-+{
-+ struct lnw_device *lnw = data;
-+ u32 status;
-+ int call_tasklet = 0;
-+
-+ /*check interrupt src*/
-+ lpe_periphral_intr_status(LPE_DMA, &status);
-+ if (!status) {
-+ /*not our interrupt*/
-+ return IRQ_NONE;
-+ }
-+
-+ /*DMA Interrupt*/
-+ status = ioread32(lnw->dma_base + RAW_TFR);
-+ status &= 0xC0;
-+ if (status) {
-+ iowrite32((status << 8), lnw->dma_base + MASK_TFR);
-+ call_tasklet = 1;
-+ }
-+ status = ioread32(lnw->dma_base + RAW_ERR);
-+ status &= 0xC0;
-+ if (status) {
-+ iowrite32(MASK_INTR_REG(status), lnw->dma_base + MASK_ERR);
-+ call_tasklet = 1;
-+ }
-+
-+ if (call_tasklet)
-+ tasklet_schedule(&lnw->dma->tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void enable_dma1_interrupt(struct lnw_dma_chan *lnwc)
-+{
-+ dma_dbg("Called for ch_id %d\n", lnwc->ch_id);
-+
-+ lpe_unmask_periphral_intr(LPE_DMA);
-+
-+ /*en ch interrupts*/
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_TFR);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_ERR);
-+ return;
-+}
-+
-+static void disable_dma1_interrupt(struct lnw_dma_chan *lnwc)
-+{
-+ /*Check LPE PISR, make sure fwd is disabled*/
-+ lpe_mask_periphral_intr(LPE_DMA);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_TFR);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_ERR);
-+ dma_dbg(" called \n");
-+ return;
-+}
-+
-+static int lnw_setup_dma1(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+ struct lnwdma_device *dma = NULL;
-+ int err, i;
-+
-+ dma_dbg("setup_dma called \n");
-+ dma = kzalloc(sizeof(*dma), GFP_KERNEL);
-+ if (NULL == dma) {
-+ dma_err("kzalloc failed \n");
-+ err = -ENOMEM;
-+ goto err_kzalloc;
-+ }
-+ device->dma = dma;
-+ dma->pdev = pdev;
-+ dma->dma_base = device->dma_base;
-+
-+ /* DMA coherent memory pool for DMA descriptor allocations */
-+ dma->dma_pool = pci_pool_create("dma_desc_pool", pdev,
-+ sizeof(struct lnw_dma_desc),
-+ 32, 0);
-+ if (NULL == dma->dma_pool) {
-+ dma_err("pci_pool_create failed \n");
-+ err = -ENOMEM;
-+ kfree(dma);
-+ goto err_dma_pool;
-+ }
-+
-+ INIT_LIST_HEAD(&dma->common.channels);
-+
-+
-+ /*init CH structures*/
-+ for (i = 0; i < MAX_CHAN; i++) {
-+ struct lnw_dma_chan *lnwch = &dma->ch[i];
-+
-+ lnwch->chan.device = &dma->common;
-+ lnwch->chan.cookie = 1;
-+ lnwch->chan.chan_id = i;
-+ lnwch->ch_id = get_ch_id(i);
-+ dma_dbg("Init CH %d, ID %d \n", i, lnwch->ch_id);
-+
-+ lnwch->dma_base = dma->dma_base;
-+ lnwch->ch_regs = dma->dma_base + DMA_CH_SIZE * lnwch->ch_id;
-+ lnwch->dma = dma;
-+ spin_lock_init(&lnwch->lock);
-+
-+ INIT_LIST_HEAD(&lnwch->active_list);
-+ INIT_LIST_HEAD(&lnwch->queue);
-+ INIT_LIST_HEAD(&lnwch->free_list);
-+ /*mask interrupts*/
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_SRC_TRAN);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_DST_TRAN);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_ERR);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_TFR);
-+
-+ disable_dma1_interrupt(lnwch);
-+ list_add_tail(&lnwch->chan.device_node, &dma->common.channels);
-+ }
-+
-+ /*init dma structure*/
-+ dma_cap_zero(dma->common.cap_mask);
-+ dma_cap_set(DMA_MEMCPY, dma->common.cap_mask);
-+ dma_cap_set(DMA_SLAVE, dma->common.cap_mask);
-+ dma_cap_set(DMA_PRIVATE, dma->common.cap_mask);
-+ dma->common.dev = &pdev->dev;
-+ dma->common.chancnt = MAX_CHAN;
-+
-+ dma->common.device_alloc_chan_resources =
-+ lnw_dma1_alloc_chan_resources;
-+ dma->common.device_free_chan_resources =
-+ lnw_dma1_free_chan_resources;
-+
-+ dma->common.device_is_tx_complete = lnw_dma1_tx_is_complete;
-+ dma->common.device_prep_dma_memcpy = lnw_dma1_prep_memcpy;
-+ dma->common.device_issue_pending = lnw_dma1_issue_pending;
-+ dma->common.device_prep_slave_sg = lnw_dma1_prep_slave_sg;
-+ dma->common.device_terminate_all = lnw_dma1_terminate_all;
-+
-+ /*enable dma cntrl*/
-+ iowrite32(REG_BIT0, dma->dma_base + DMA_CFG);
-+
-+ /*register irq*/
-+ err = request_irq(pdev->irq, lnw_dma1_interrupt,
-+ IRQF_SHARED, lnw_dma1_pci.name, device);
-+ if (0 != err)
-+ goto err_irq;
-+
-+ /*register device w/ engine*/
-+ err = dma_async_device_register(&dma->common);
-+ if (0 != err) {
-+ dma_err("device_register failed: %d \n", err);
-+ goto err_engine;
-+ }
-+ tasklet_init(&dma->tasklet, dma_tasklet1, (unsigned long)dma);
-+ dma_dbg("...done \n");
-+ return 0;
-+
-+err_engine:
-+ free_irq(pdev->irq, device);
-+err_irq:
-+ pci_pool_destroy(dma->dma_pool);
-+ kfree(dma);
-+err_dma_pool:
-+err_kzalloc:
-+ dma_err("setup_dma failed: %d \n", err);
-+ return err;
-+
-+}
-+
-+static void lnwdma_shutdown1(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+
-+ dma_dbg("shutdown called \n");
-+ dma_async_device_unregister(&device->dma->common);
-+ pci_pool_destroy(device->dma->dma_pool);
-+ if (device->dma_base)
-+ iounmap(device->dma_base);
-+ free_irq(pdev->irq, device);
-+ return;
-+}
-+
-+static int __devinit
-+lnw_dma1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+ struct lnw_device *device = NULL;
-+ u32 base_addr = 0, bar_size = 0;
-+ int err = 0;
-+
-+ dma_info("probe called for %x \n", pdev->device);
-+ err = pci_enable_device(pdev);
-+ if (err)
-+ goto err_enable_device;
-+
-+ err = pci_request_regions(pdev, lnw_dma1_pci.name);
-+ if (err)
-+ goto err_request_regions;
-+
-+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-+ if (err)
-+ goto err_set_dma_mask;
-+
-+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-+ if (err)
-+ goto err_set_dma_mask;
-+
-+ device = kzalloc(sizeof(*device), GFP_KERNEL);
-+ if (!device) {
-+ dma_err("kzalloc failed \n");
-+ err = -ENOMEM;
-+ goto err_kzalloc;
-+ }
-+ device->pdev = pci_dev_get(pdev);
-+
-+ base_addr = pci_resource_start(pdev, 0);
-+ bar_size = pci_resource_len(pdev, 0);
-+ dma_dbg("BAR0 %x Size %x \n", base_addr, bar_size);
-+ device->dma_base = ioremap_nocache(base_addr, DMA_REG_SIZE);
-+ if (!device->dma_base) {
-+ dma_err("ioremap failed \n");
-+ err = -ENOMEM;
-+ goto err_ioremap1;
-+ }
-+ pci_set_drvdata(pdev, device);
-+ pci_set_master(pdev);
-+
-+ err = lnw_setup_dma1(pdev);
-+ if (err)
-+ goto err_dma;
-+
-+ return 0;
-+
-+err_dma:
-+ iounmap(device->dma_base);
-+err_ioremap1:
-+ pci_dev_put(pdev);
-+ kfree(device);
-+err_kzalloc:
-+err_set_dma_mask:
-+ pci_release_regions(pdev);
-+ pci_disable_device(pdev);
-+err_request_regions:
-+err_enable_device:
-+ dma_err("Probe failed %d\n", err);
-+ return err;
-+}
-+
-+static void __devexit lnw_dma1_remove(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+
-+ lnwdma_shutdown1(pdev);
-+ pci_dev_put(pdev);
-+ kfree(device);
-+ pci_release_regions(pdev);
-+ pci_disable_device(pdev);
-+}
-+
-+static int __init lnw_dma1_init(void)
-+{
-+ dma_info("LNW DMA Driver\n Version %s \n", LNW_DMA_DRIVER_VERSION);
-+ return pci_register_driver(&lnw_dma1_pci);
-+}
-+late_initcall(lnw_dma1_init);
-+
-+static void __exit lnw_dma1_exit(void)
-+{
-+ pci_unregister_driver(&lnw_dma1_pci);
-+}
-+module_exit(lnw_dma1_exit);
-+
-Index: linux-2.6.33/drivers/dma/lnw_dmac2.c
-===================================================================
---- /dev/null
-+++ linux-2.6.33/drivers/dma/lnw_dmac2.c
-@@ -0,0 +1,947 @@
-+/*
-+ * lnw_dmac2.c - Intel Langwell DMA Drivers
-+ *
-+ * Copyright (C) 2008-09 Intel Corp
-+ * Author: Vinod Koul <vinod.koul@intel.com>
-+ * The driver design is based on dw_dmac driver
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * 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; version 2 of the License.
-+ *
-+ * 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, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ *
-+ */
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include <linux/lnw_dma.h>
-+
-+#define MAX_CHAN 2
-+#include "lnw_dma_regs.h"
-+
-+MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-+MODULE_DESCRIPTION("Intel (R) Moorestown Langwell DMAC2 Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_VERSION(LNW_DMA_DRIVER_VERSION);
-+
-+#define DMA_CH0 0
-+#define DMA_CH1 1
-+#define CH_BLOCK_SIZE 2047
-+
-+static int __devinit lnw_dma2_probe(struct pci_dev *pdev,
-+ const struct pci_device_id *id);
-+static void __devexit lnw_dma2_remove(struct pci_dev *pdev);
-+static void enable_dma2_interrupt(struct lnw_dma_chan *lnwc);
-+
-+struct lnw_device {
-+ struct pci_dev *pdev;
-+ void __iomem *dma_base;
-+ struct lnwdma_device *dma;
-+};
-+
-+/*CH dep code, if ch no's mapping changes only change here*/
-+static int get_ch_id(int index)
-+{
-+ if (index == 0)
-+ return DMA_CH0;
-+ else if (index == 1)
-+ return DMA_CH1;
-+ else
-+ return -1;
-+}
-+
-+static int get_ch_index(int ch_id)
-+{
-+ if (ch_id == DMA_CH0)
-+ return 0;
-+ if (ch_id == DMA_CH1)
-+ return 1;
-+ else
-+ return -1;
-+}
-+
-+static int get_ch_num(int *status)
-+{
-+ if (*status & (1 << DMA_CH0)) {
-+ *status = *status & (~(1 << DMA_CH0));
-+ return DMA_CH0;
-+ } else if (*status & (1 << DMA_CH1)) {
-+ *status = *status & (~(1 << DMA_CH1));
-+ return DMA_CH1;
-+ } else
-+ return -1;
-+}
-+
-+static int get_block_ts(int len, int tx_width)
-+{
-+ int byte_width = 0, block_ts = 0;
-+
-+ switch (tx_width) {
-+ case LNW_DMA_WIDTH_8BIT:
-+ byte_width = 1;
-+ break;
-+ case LNW_DMA_WIDTH_16BIT:
-+ byte_width = 2;
-+ break;
-+ case LNW_DMA_WIDTH_32BIT:
-+ default:
-+ byte_width = 4;
-+ break;
-+ }
-+
-+ block_ts = len/byte_width;
-+ if (block_ts > CH_BLOCK_SIZE)
-+ block_ts = 0xFFFF;
-+ return block_ts;
-+}
-+
-+static struct lnw_dma_desc *lnwc_desc_get(struct lnw_dma_chan *lnwc)
-+{
-+ struct lnw_dma_desc *desc, *_desc;
-+ struct lnw_dma_desc *ret = NULL;
-+
-+ dma_dbg("called \n");
-+ spin_lock_bh(&lnwc->lock);
-+ list_for_each_entry_safe(desc, _desc, &lnwc->free_list, desc_node) {
-+ if (async_tx_test_ack(&desc->txd)) {
-+ list_del(&desc->desc_node);
-+ ret = desc;
-+ dma_dbg("got free desc \n");
-+ break;
-+ }
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ return ret;
-+}
-+
-+static void lnwc_desc_put(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *desc)
-+{
-+ if (desc) {
-+ spin_lock_bh(&lnwc->lock);
-+ list_add_tail(&desc->desc_node, &lnwc->free_list);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+}
-+
-+/* Called with lock held and bh disabled */
-+static void lnwc_dostart(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *first)
-+{
-+ struct lnwdma_device *lnw = to_lnwdma_device(lnwc->chan.device);
-+
-+ dma_dbg("called \n");
-+ /* channel is idle */
-+ if (lnwc->in_use && test_ch_en(lnwc->dma_base, lnwc->ch_id)) {
-+ /*error*/
-+ dma_err("channel is busy \n");
-+ /* The tasklet will hopefully advance the queue... */
-+ return;
-+ }
-+
-+ /*write registers and en*/
-+ iowrite32(first->sar, lnwc->ch_regs + SAR);
-+ iowrite32(first->dar, lnwc->ch_regs + DAR);
-+ iowrite32(first->cfg_hi, lnwc->ch_regs + CFG_HIGH);
-+ iowrite32(first->cfg_lo, lnwc->ch_regs + CFG_LOW);
-+ iowrite32(first->ctl_lo, lnwc->ch_regs + CTL_LOW);
-+ iowrite32(first->ctl_hi, lnwc->ch_regs + CTL_HIGH);
-+ dma_dbg("TX SAR %lx, DAR %lx, CFGL %x, CFGH %x, CTLH %x, CTLL %x \n",
-+ first->sar, first->dar, first->cfg_hi,
-+ first->cfg_lo, first->ctl_hi, first->ctl_lo);
-+
-+ iowrite32(ENABLE_CHANNEL(lnwc->ch_id), lnw->dma_base + DMA_CHAN_EN);
-+ first->status = DMA_IN_PROGRESS;
-+}
-+
-+static void
-+lnwc_descriptor_complete(struct lnw_dma_chan *lnwc, struct lnw_dma_desc *desc)
-+{
-+ struct dma_async_tx_descriptor *txd = &desc->txd;
-+ dma_async_tx_callback callback = NULL;
-+ dma_async_tx_callback callback_txd = NULL;
-+ void *param = NULL;
-+ void *param_txd = NULL;
-+ u32 sar, dar, len;
-+ union lnw_dma_ctl_hi ctl_hi;
-+
-+ dma_dbg("called \n");
-+
-+ /*check if full tx is complete or not*/
-+ sar = ioread32(lnwc->ch_regs + SAR);
-+ dar = ioread32(lnwc->ch_regs + DAR);
-+
-+ if (desc->dirn == DMA_FROM_DEVICE)
-+ len = dar - desc->dar;
-+ else
-+ len = sar - desc->sar;
-+
-+ dma_dbg("SAR %x DAR %x, DMA done: %x \n", sar, dar, len);
-+ if (desc->len > len) {
-+ dma_dbg("dirn = %d\n", desc->dirn);
-+ dma_dbg("SAR %x DAR %x, len: %x \n", sar, dar, len);
-+ /*we have to copy more bytes*/
-+ desc->len -= len;
-+ ctl_hi.ctl_hi = desc->ctl_hi;
-+ ctl_hi.ctlx.block_ts = get_block_ts(desc->len, desc->width);
-+ dma_dbg("setting for %x bytes \n", ctl_hi.ctlx.block_ts);
-+ desc->ctl_hi = ctl_hi.ctl_hi;
-+ if (desc->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ sar++;
-+ dar++;
-+ } else if (desc->dirn == DMA_TO_DEVICE)
-+ sar++;
-+ else if (desc->dirn == DMA_FROM_DEVICE)
-+ dar++;
-+ desc->sar = sar;
-+ desc->dar = dar;
-+ dma_dbg("New SAR %x DAR %x \n", sar, dar);
-+ lnwc_dostart(lnwc, desc);
-+ return;
-+ }
-+
-+ lnwc->completed = txd->cookie;
-+ callback = desc->callback;
-+ param = desc->callback_param;
-+ callback_txd = txd->callback;
-+ param_txd = txd->callback_param;
-+
-+ list_move(&desc->desc_node, &lnwc->free_list);
-+
-+ spin_unlock_bh(&lnwc->lock);
-+ dma_dbg("Now we are calling callback \n");
-+ if (callback_txd) {
-+ dma_dbg("lnw TXD callback set ... calling \n");
-+ callback_txd(param_txd);
-+ spin_lock_bh(&lnwc->lock);
-+ return;
-+ }
-+ if (callback) {
-+ dma_dbg("lnw callback set ... calling \n");
-+ callback(param);
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+
-+}
-+
-+/*check desc, mark as complete when tx is complete*/
-+static void
-+lnwc_scan_descriptors(struct lnwdma_device *lnw, struct lnw_dma_chan *lnwc)
-+{
-+ struct lnw_dma_desc *desc = NULL, *_desc = NULL;
-+ u32 status_xfer;
-+
-+ dma_dbg("called \n");
-+ status_xfer = ioread32(lnwc->dma_base + RAW_TFR);
-+ status_xfer = (status_xfer >> lnwc->ch_id) & 0x1;
-+ dma_dbg("ch[%d]: status_xfer %x \n", lnwc->ch_id, status_xfer);
-+ if (!status_xfer)
-+ return;
-+
-+ /*tx is complete*/
-+ list_for_each_entry_safe(desc, _desc, &lnwc->active_list, desc_node) {
-+ if (desc == NULL)
-+ continue;
-+ if (desc->status == DMA_IN_PROGRESS) {
-+ desc->status = DMA_SUCCESS;
-+ lnwc_descriptor_complete(lnwc, desc);
-+ }
-+ }
-+ return;
-+}
-+
-+/*****************************************************************************
-+DMA Functions*/
-+static dma_cookie_t lnw_dma2_tx_submit(struct dma_async_tx_descriptor *tx)
-+{
-+ struct lnw_dma_desc *desc = to_lnw_dma_desc(tx);
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(tx->chan);
-+ dma_cookie_t cookie;
-+
-+ dma_dbg("called \n");
-+
-+ spin_lock_bh(&lnwc->lock);
-+ cookie = lnwc->chan.cookie;
-+
-+ if (++cookie < 0)
-+ cookie = 1;
-+
-+ lnwc->chan.cookie = cookie;
-+ desc->txd.cookie = cookie;
-+
-+ if (list_empty(&lnwc->active_list)) {
-+ lnwc_dostart(lnwc, desc);
-+ list_add_tail(&desc->desc_node, &lnwc->active_list);
-+ } else {
-+ list_add_tail(&desc->desc_node, &lnwc->queue);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+
-+ return cookie;
-+}
-+
-+static void lnw_dma2_issue_pending(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+
-+ spin_lock_bh(&lnwc->lock);
-+ if (!list_empty(&lnwc->queue))
-+ lnwc_scan_descriptors(to_lnwdma_device(chan->device), lnwc);
-+ spin_unlock_bh(&lnwc->lock);
-+}
-+
-+static enum dma_status
-+lnw_dma2_tx_is_complete(struct dma_chan *chan,
-+ dma_cookie_t cookie,
-+ dma_cookie_t *done,
-+ dma_cookie_t *used)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ dma_cookie_t last_used;
-+ dma_cookie_t last_complete;
-+ int ret;
-+
-+ last_complete = lnwc->completed;
-+ last_used = chan->cookie;
-+
-+ ret = dma_async_is_complete(cookie, last_complete, last_used);
-+ if (ret != DMA_SUCCESS) {
-+ lnwc_scan_descriptors(to_lnwdma_device(chan->device), lnwc);
-+
-+ last_complete = lnwc->completed;
-+ last_used = chan->cookie;
-+
-+ ret = dma_async_is_complete(cookie, last_complete, last_used);
-+ }
-+
-+ if (done)
-+ *done = last_complete;
-+ if (used)
-+ *used = last_used;
-+
-+ return ret;
-+}
-+
-+static void lnw_dma2_terminate_all(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc, *_desc;
-+ LIST_HEAD(list);
-+
-+ /* ASSERT: channel is idle */
-+ if (lnwc->in_use == false) {
-+ /*ch is not in use, wrong call*/
-+ return;
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+ list_splice_init(&lnwc->free_list, &list);
-+ lnwc->descs_allocated = 0;
-+ lnwc->slave = NULL;
-+
-+ /* Disable interrupts*/
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_ERR);
-+
-+ spin_unlock_bh(&lnwc->lock);
-+ list_for_each_entry_safe(desc, _desc, &list, desc_node) {
-+ dma_dbg("freeing descriptor %p\n", desc);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+
-+ return;
-+}
-+
-+static struct dma_async_tx_descriptor *
-+lnw_dma2_prep_slave_sg(struct dma_chan *chan,
-+ struct scatterlist *sgl, unsigned int sg_len,
-+ enum dma_data_direction direction,
-+ unsigned long flags)
-+{
-+ /*not supported now*/
-+ return NULL;
-+}
-+
-+static struct dma_async_tx_descriptor *
-+lnw_dma2_prep_memcpy(struct dma_chan *chan, dma_addr_t dest,
-+ dma_addr_t src, size_t len, unsigned long flags)
-+{
-+ struct lnw_dma_chan *lnwc;
-+ struct lnw_dma_desc *desc = NULL;
-+ struct lnw_dma_slave *lnws;
-+ union lnw_dma_ctl_lo ctl_lo;
-+ union lnw_dma_ctl_hi ctl_hi;
-+ union lnw_dma_cfg_lo cfg_lo;
-+ union lnw_dma_cfg_hi cfg_hi;
-+ enum lnw_dma_width width = 0;
-+
-+ dma_dbg("called \n");
-+ WARN_ON(!chan);
-+ if (!len)
-+ return NULL;
-+
-+ lnws = chan->private;
-+ WARN_ON(!lnws);
-+
-+ lnwc = to_lnw_dma_chan(chan);
-+ WARN_ON(!lnwc);
-+
-+ dma_dbg("called for CH %d\n", lnwc->ch_id);
-+ dma_dbg("Cfg passed Mode %x, Dirn %x, HS %x, Width %x \n",
-+ lnws->cfg_mode, lnws->dirn, lnws->hs_mode, lnws->src_width);
-+
-+ /*calculate CFG_LO*/
-+ if (lnws->hs_mode == LNW_DMA_SW_HS) {
-+ cfg_lo.cfg_lo = 0;
-+ cfg_lo.cfgx.hs_sel_dst = 1;
-+ cfg_lo.cfgx.hs_sel_src = 1;
-+ } else if (lnws->hs_mode == LNW_DMA_HW_HS)
-+ cfg_lo.cfg_lo = 0x00000;
-+
-+ /*calculate CFG_HI*/
-+ if (lnws->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ /*SW HS only*/
-+ dma_dbg("CFG: Mem to mem dma \n");
-+ cfg_hi.cfg_hi = 0;
-+ } else {
-+ dma_dbg("HW DMA \n");
-+ cfg_hi.cfg_hi = 0;
-+ cfg_hi.cfgx.protctl = 0x1; /*default value*/
-+ cfg_hi.cfgx.src_per = get_ch_index(lnwc->ch_id);
-+ cfg_hi.cfgx.dst_per = get_ch_index(lnwc->ch_id);
-+ }
-+
-+ /*calculate CTL_HI*/
-+ ctl_hi.ctlx.reser = 0;
-+ width = lnws->src_width;
-+ ctl_hi.ctlx.block_ts = get_block_ts(len, width);
-+
-+ /*calculate CTL_LO*/
-+ ctl_lo.ctl_lo = 0;
-+ ctl_lo.ctlx.int_en = 1;
-+ ctl_lo.ctlx.dst_tr_width = lnws->dst_width;
-+ ctl_lo.ctlx.src_tr_width = lnws->src_width;
-+ ctl_lo.ctlx.dst_msize = lnws->src_msize;
-+ ctl_lo.ctlx.src_msize = lnws->dst_msize;
-+
-+ if (lnws->cfg_mode == LNW_DMA_MEM_TO_MEM) {
-+ dma_dbg("CTL: Mem to mem dma \n");
-+ ctl_lo.ctlx.tt_fc = 0;
-+ ctl_lo.ctlx.sinc = 0;
-+ ctl_lo.ctlx.dinc = 0;
-+ } else {
-+ if (lnws->dirn == DMA_TO_DEVICE) {
-+ dma_dbg("CTL: DMA_TO_DEVICE \n");
-+ ctl_lo.ctlx.sinc = 0;
-+ ctl_lo.ctlx.dinc = 2;
-+ ctl_lo.ctlx.tt_fc = 1;
-+ } else if (lnws->dirn == DMA_FROM_DEVICE) {
-+ dma_dbg("CTL: DMA_FROM_DEVICE \n");
-+ ctl_lo.ctlx.sinc = 2;
-+ ctl_lo.ctlx.dinc = 0;
-+ ctl_lo.ctlx.tt_fc = 2;
-+ }
-+ }
-+
-+ dma_dbg("Calc CTL LO %x, CTL HI %x, CFG LO %x, CFG HI %x\n",
-+ ctl_lo.ctl_lo, ctl_hi.ctl_hi, cfg_lo.cfg_lo, cfg_hi.cfg_hi);
-+
-+ enable_dma2_interrupt(lnwc);
-+
-+ desc = lnwc_desc_get(lnwc);
-+ if (desc == NULL)
-+ goto err_desc_get;
-+ desc->sar = src;
-+ desc->dar = dest ;
-+ desc->len = len;
-+ desc->cfg_hi = cfg_hi.cfg_hi;
-+ desc->cfg_lo = cfg_lo.cfg_lo;
-+ desc->ctl_lo = ctl_lo.ctl_lo;
-+ desc->ctl_hi = ctl_hi.ctl_hi;
-+ desc->width = width;
-+ desc->dirn = lnws->dirn;
-+ if (lnws->callback) {
-+ desc->callback = lnws->callback;
-+ desc->callback_param = lnws->callback_param;
-+ dma_dbg("Callback passed... setting\n");
-+ } else
-+ desc->callback = NULL;
-+ return &desc->txd;
-+
-+err_desc_get:
-+ dma_err("Failed to get desc \n");
-+ lnwc_desc_put(lnwc, desc);
-+ return NULL;
-+}
-+
-+
-+static void lnw_dma2_free_chan_resources(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc, *_desc;
-+
-+ dma_dbg("..called for ch_id %d, lnwch_id %d\n",
-+ chan->chan_id, lnwc->ch_id);
-+ if (true == lnwc->in_use) {
-+ /*trying to free ch in use!!!!!*/
-+ dma_err("trying to free ch in use \n");
-+ }
-+
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc->descs_allocated = 0;
-+ list_for_each_entry_safe(desc, _desc, &lnwc->active_list, desc_node) {
-+ dma_dbg("del active \n");
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ list_for_each_entry_safe(desc, _desc, &lnwc->free_list, desc_node) {
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ list_for_each_entry_safe(desc, _desc, &lnwc->queue, desc_node) {
-+ dma_dbg("del queue \n");
-+ list_del(&desc->desc_node);
-+ pci_pool_free(lnw->dma_pool, desc, desc->txd.phys);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ lnwc->in_use = false;
-+ chan->client_count--;
-+ /* Disable CH interrupts*/
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwc->ch_id), lnw->dma_base + MASK_ERR);
-+ dma_dbg("done \n");
-+}
-+
-+static int lnw_dma2_alloc_chan_resources(struct dma_chan *chan)
-+{
-+ struct lnw_dma_chan *lnwc = to_lnw_dma_chan(chan);
-+ struct lnwdma_device *lnw = to_lnwdma_device(chan->device);
-+ struct lnw_dma_desc *desc;
-+ dma_addr_t phys;
-+ int i = 0;
-+
-+ dma_dbg("called \n");
-+
-+ /* ASSERT: channel is idle */
-+ if (test_ch_en(lnw->dma_base, lnwc->ch_id)) {
-+ /*ch is not idle*/
-+ dma_err(".ch not idle\n");
-+ return -EIO;
-+ }
-+ dma_dbg("..called for ch_id %d, lnwch_id %d\n",
-+ chan->chan_id, lnwc->ch_id);
-+ lnwc->completed = chan->cookie = 1;
-+
-+ chan->client_count++;
-+
-+ spin_lock_bh(&lnwc->lock);
-+ while (lnwc->descs_allocated < DESCS_PER_CHANNEL) {
-+ spin_unlock_bh(&lnwc->lock);
-+ desc = pci_pool_alloc(lnw->dma_pool, GFP_KERNEL, &phys);
-+ if (!desc) {
-+ dma_err("desc failed\n");
-+ return -ENOMEM;
-+ /*check*/
-+ }
-+ dma_async_tx_descriptor_init(&desc->txd, chan);
-+ desc->txd.tx_submit = lnw_dma2_tx_submit;
-+ desc->txd.flags = DMA_CTRL_ACK;
-+ desc->txd.phys = phys;
-+ spin_lock_bh(&lnwc->lock);
-+ i = ++lnwc->descs_allocated;
-+ list_add_tail(&desc->desc_node, &lnwc->free_list);
-+ }
-+ spin_unlock_bh(&lnwc->lock);
-+ lnwc->in_use = false;
-+ dma_dbg("Desc alloc done ret: %d desc\n", i);
-+ return i;
-+}
-+
-+static void lnwc_handle_error(struct lnwdma_device *lnw,
-+ struct lnw_dma_chan *lnwc)
-+{
-+ lnwc_scan_descriptors(lnw, lnwc);
-+}
-+
-+/******************************************************************************
-+* PCI stuff
-+*/
-+static struct pci_device_id lnw_dma2_ids[] = {
-+ { PCI_VENDOR_ID_INTEL, 0x0813, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+ { 0, }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, lnw_dma2_ids);
-+
-+static struct pci_driver lnw_dma2_pci = {
-+ .name = "Intel LNW DMA2",
-+ .id_table = lnw_dma2_ids,
-+ .probe = lnw_dma2_probe,
-+ .remove = __devexit_p(lnw_dma2_remove),
-+};
-+
-+static void dma_tasklet(unsigned long data)
-+{
-+ struct lnwdma_device *lnw = NULL;
-+ struct lnw_dma_chan *lnwc = NULL;
-+ u32 status;
-+ int i, ch_no;
-+
-+ dma_dbg("called \n");
-+ lnw = (struct lnwdma_device *)data;
-+ if (lnw == NULL) {
-+ dma_err("Null param \n");
-+ return;
-+ }
-+
-+ status = ioread32(lnw->dma_base + RAW_TFR);
-+ dma_dbg("RAW_TFR %x \n", status);
-+ while (status) {
-+ /*txn interrupt*/
-+ ch_no = get_ch_num(&status);
-+ if (ch_no < 0) {
-+ dma_err("Ch no is invalid %x, abort!\n", ch_no);
-+ return;
-+ }
-+ dma_dbg("Got Ch %x, new Status %x \n", ch_no, status);
-+ i = get_ch_index(ch_no);
-+ if (i < 0) {
-+ dma_err("Invalid ch index %x\n", i);
-+ return;
-+ }
-+ dma_dbg("Tx complete interrupt %x, Ch No %d Index %d \n",
-+ status, ch_no, i);
-+ lnwc = &lnw->ch[i];
-+ if (lnwc == NULL) {
-+ dma_err("Null param lnwc\n");
-+ return;
-+ }
-+ dma_dbg("CH %x \n", lnwc->ch_id);
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc_scan_descriptors(lnw, lnwc);
-+ dma_dbg("Scan of desc... complete, unmasking\n");
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_TFR);
-+ dma_dbg("Wrote to clear %x\n", (1 << lnwc->ch_id));
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_BLOCK);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id),
-+ lnw->dma_base + MASK_TFR);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+
-+ dma_dbg("Trf interrupt done... \n");
-+ status = ioread32(lnw->dma_base + RAW_ERR);
-+ while (status) {
-+ /*err interrupt*/
-+ ch_no = get_ch_num(&status);
-+ if (ch_no < 0) {
-+ dma_err("Ch no is invalid %x, abort!\n", ch_no);
-+ return;
-+ }
-+ dma_dbg("Got Ch %x, new Status %x \n", ch_no, status);
-+ i = get_ch_index(ch_no);
-+ if (i < 0) {
-+ dma_err("Invalid CH lnwc\n");
-+ return;
-+ }
-+ dma_dbg("Tx error interrupt %x, No %d Index %d \n",
-+ status, ch_no, i);
-+ lnwc = &lnw->ch[i];
-+ if (lnwc == NULL) {
-+ dma_err("Null param lnwc\n");
-+ return;
-+ }
-+ spin_lock_bh(&lnwc->lock);
-+ lnwc_handle_error(lnw, lnwc);
-+ iowrite32((1 << lnwc->ch_id),
-+ lnw->dma_base + CLEAR_ERR);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id),
-+ lnw->dma_base + MASK_ERR);
-+ spin_unlock_bh(&lnwc->lock);
-+ }
-+ dma_dbg("Exiting takslet... \n");
-+ return;
-+}
-+
-+static irqreturn_t lnw_dma2_interrupt(int irq, void *data)
-+{
-+ struct lnw_device *lnw = data;
-+ u32 status;
-+ int call_tasklet = 0;
-+
-+ /*will mask interrupt for now and schedule tasklet
-+ tasklet shud unmask and clear*/
-+ status = ioread32(lnw->dma_base + STATUS_TFR);
-+ status &= 0x03;
-+ if (status) {
-+ iowrite32((status << 8), lnw->dma_base + MASK_TFR);
-+ call_tasklet = 1;
-+ }
-+ status = ioread32(lnw->dma_base + STATUS_ERR);
-+ status &= 0x03;
-+ if (status) {
-+ iowrite32(MASK_INTR_REG(status), lnw->dma_base + MASK_ERR);
-+ call_tasklet = 1;
-+ }
-+
-+ if (call_tasklet)
-+ tasklet_schedule(&lnw->dma->tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void enable_dma2_interrupt(struct lnw_dma_chan *lnwc)
-+{
-+ dma_dbg("Called for ch_id %d\n", lnwc->ch_id);
-+
-+ iowrite32(REG_BIT0, lnwc->dma->dma_base + DMA_CFG);
-+ /*en ch interrupts */
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_TFR);
-+ iowrite32(UNMASK_INTR_REG(lnwc->ch_id), lnwc->dma_base + MASK_ERR);
-+ return;
-+}
-+
-+static void disable_dma2_interrupt(struct lnw_device *device)
-+{
-+ u32 status = 0;
-+
-+ /*todo*/
-+ dma_dbg(" called \n");
-+ status = 1;
-+ return;
-+
-+}
-+
-+static int lnw_setup_dma2(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+ struct lnwdma_device *dma = NULL;
-+ int err, i;
-+
-+ dma_dbg("setup_dma called \n");
-+ dma = kzalloc(sizeof(*dma), GFP_KERNEL);
-+ if (NULL == dma) {
-+ dma_err("kzalloc failed \n");
-+ err = -ENOMEM;
-+ goto err_kzalloc;
-+ }
-+ device->dma = dma;
-+ dma->pdev = pdev;
-+ dma->dma_base = device->dma_base;
-+
-+ /* DMA coherent memory pool for DMA descriptor allocations */
-+ dma->dma_pool = pci_pool_create("dma_desc_pool", pdev,
-+ sizeof(struct lnw_dma_desc),
-+ 32, 0);
-+ if (NULL == dma->dma_pool) {
-+ dma_err("pci_pool_create failed \n");
-+ err = -ENOMEM;
-+ kfree(dma);
-+ goto err_dma_pool;
-+ }
-+
-+ INIT_LIST_HEAD(&dma->common.channels);
-+
-+
-+ /*init CH structures*/
-+ for (i = 0; i < MAX_CHAN; i++) {
-+ struct lnw_dma_chan *lnwch = &dma->ch[i];
-+
-+ lnwch->chan.device = &dma->common;
-+ lnwch->chan.cookie = 1;
-+ lnwch->chan.chan_id = i;
-+ lnwch->ch_id = get_ch_id(i);
-+ dma_dbg("Init CH %d, ID %d \n", i, lnwch->ch_id);
-+
-+ lnwch->dma_base = dma->dma_base;
-+ lnwch->ch_regs = dma->dma_base + DMA_CH_SIZE * lnwch->ch_id;
-+ lnwch->dma = dma;
-+ spin_lock_init(&lnwch->lock);
-+
-+ INIT_LIST_HEAD(&lnwch->active_list);
-+ INIT_LIST_HEAD(&lnwch->queue);
-+ INIT_LIST_HEAD(&lnwch->free_list);
-+
-+ /*mask interrupts*/
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_BLOCK);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_SRC_TRAN);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_DST_TRAN);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_ERR);
-+ iowrite32(MASK_INTR_REG(lnwch->ch_id),
-+ dma->dma_base + MASK_TFR);
-+
-+ dma_dbg("Init CH %d, ID %d \n", i, lnwch->ch_id);
-+ list_add_tail(&lnwch->chan.device_node, &dma->common.channels);
-+ }
-+
-+ /*init dma structure*/
-+ dma_cap_zero(dma->common.cap_mask);
-+ dma_cap_set(DMA_MEMCPY, dma->common.cap_mask);
-+ dma_cap_set(DMA_SLAVE, dma->common.cap_mask);
-+ dma_cap_set(DMA_PRIVATE, dma->common.cap_mask);
-+ dma->common.dev = &pdev->dev;
-+ dma->common.chancnt = MAX_CHAN;
-+
-+ dma->common.device_alloc_chan_resources =
-+ lnw_dma2_alloc_chan_resources;
-+ dma->common.device_free_chan_resources =
-+ lnw_dma2_free_chan_resources;
-+
-+ dma->common.device_is_tx_complete = lnw_dma2_tx_is_complete;
-+ dma->common.device_prep_dma_memcpy = lnw_dma2_prep_memcpy;
-+ dma->common.device_issue_pending = lnw_dma2_issue_pending;
-+ dma->common.device_prep_slave_sg = lnw_dma2_prep_slave_sg;
-+ dma->common.device_terminate_all = lnw_dma2_terminate_all;
-+
-+ /*enable dma cntrl*/
-+ iowrite32(REG_BIT0, dma->dma_base + DMA_CFG);
-+
-+ disable_dma2_interrupt(device);
-+
-+ /*register irq*/
-+ err = request_irq(pdev->irq, lnw_dma2_interrupt,
-+ 0, lnw_dma2_pci.name, device);
-+ if (0 != err)
-+ goto err_irq;
-+
-+ /*register device w/ engine*/
-+ err = dma_async_device_register(&dma->common);
-+ if (0 != err) {
-+ dma_err("device_register failed: %d \n", err);
-+ goto err_engine;
-+ }
-+ tasklet_init(&dma->tasklet, dma_tasklet, (unsigned long)dma);
-+ dma_dbg("...done\n");
-+ return 0;
-+
-+err_engine:
-+ free_irq(pdev->irq, device);
-+err_irq:
-+ pci_pool_destroy(dma->dma_pool);
-+ kfree(dma);
-+err_dma_pool:
-+err_kzalloc:
-+ dma_err("setup_dma failed: %d \n", err);
-+ return err;
-+
-+}
-+
-+static void lnwdma_shutdown(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+
-+ dma_dbg("shutdown called \n");
-+ dma_async_device_unregister(&device->dma->common);
-+ pci_pool_destroy(device->dma->dma_pool);
-+ if (device->dma_base)
-+ iounmap(device->dma_base);
-+ free_irq(pdev->irq, device);
-+ return;
-+}
-+static int __devinit
-+lnw_dma2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+ struct lnw_device *device = NULL;
-+ u32 base_addr = 0, bar_size = 0;
-+ int err = 0;
-+
-+ dma_info("probe called for %x \n", pdev->device);
-+ err = pci_enable_device(pdev);
-+ if (err)
-+ goto err_enable_device;
-+
-+ err = pci_request_regions(pdev, lnw_dma2_pci.name);
-+ if (err)
-+ goto err_request_regions;
-+
-+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-+ if (err)
-+ goto err_set_dma_mask;
-+
-+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-+ if (err)
-+ goto err_set_dma_mask;
-+
-+ device = kzalloc(sizeof(*device), GFP_KERNEL);
-+ if (!device) {
-+ dma_err("kzalloc failed \n");
-+ err = -ENOMEM;
-+ goto err_kzalloc;
-+ }
-+ device->pdev = pci_dev_get(pdev);
-+
-+ base_addr = pci_resource_start(pdev, 0);
-+ bar_size = pci_resource_len(pdev, 0);
-+ dma_dbg("BAR0 %x Size %x \n", base_addr, bar_size);
-+ device->dma_base = ioremap_nocache(base_addr, DMA_REG_SIZE);
-+ if (!device->dma_base) {
-+ dma_err("ioremap failed \n");
-+ err = -ENOMEM;
-+ goto err_ioremap;
-+ }
-+
-+ pci_set_drvdata(pdev, device);
-+ pci_set_master(pdev);
-+
-+ err = lnw_setup_dma2(pdev);
-+ if (err)
-+ goto err_dma;
-+
-+ return 0;
-+
-+err_dma:
-+ iounmap(device->dma_base);
-+err_ioremap:
-+ pci_dev_put(pdev);
-+ kfree(device);
-+err_kzalloc:
-+err_set_dma_mask:
-+ pci_release_regions(pdev);
-+ pci_disable_device(pdev);
-+err_request_regions:
-+err_enable_device:
-+ dma_err("Probe failed %d\n", err);
-+ return err;
-+}
-+
-+static void __devexit lnw_dma2_remove(struct pci_dev *pdev)
-+{
-+ struct lnw_device *device = pci_get_drvdata(pdev);
-+
-+ lnwdma_shutdown(pdev);
-+ pci_dev_put(pdev);
-+ kfree(device);
-+ pci_release_regions(pdev);
-+ pci_disable_device(pdev);
-+}
-+
-+static int __init lnw_dma2_init(void)
-+{
-+ dma_info("LNW DMA Driver\n Version %s \n", LNW_DMA_DRIVER_VERSION);
-+ return pci_register_driver(&lnw_dma2_pci);
-+}
-+fs_initcall(lnw_dma2_init);
-+
-+static void __exit lnw_dma2_exit(void)
-+{
-+ pci_unregister_driver(&lnw_dma2_pci);
-+}
-+module_exit(lnw_dma2_exit);
-+
-Index: linux-2.6.33/include/linux/lnw_dma.h
-===================================================================
---- /dev/null
-+++ linux-2.6.33/include/linux/lnw_dma.h
-@@ -0,0 +1,166 @@
-+/*
-+ * lnw_dma.c - Intel Langwell DMA Drivers
-+ *
-+ * Copyright (C) 2008i-09 Intel Corp
-+ * Author: Vinod Koul <vinod.koul@intel.com>
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * 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; version 2 of the License.
-+ *
-+ * 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, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ *
-+ */
-+#ifndef __LNW_DMA_H__
-+#define __LNW_DMA_H__
-+
-+#include <linux/dmaengine.h>
-+
-+/*DMA transaction width, src and dstn width would be same
-+The DMA length must be width aligned,
-+for 32 bit width the length must be 32 bit (4bytes) aligned only*/
-+enum lnw_dma_width {
-+ LNW_DMA_WIDTH_8BIT = 0x0,
-+ LNW_DMA_WIDTH_16BIT = 0x1,
-+ LNW_DMA_WIDTH_32BIT = 0x2,
-+};
-+
-+/*DMA mode configurations*/
-+enum lnw_dma_mode {
-+ LNW_DMA_PER_TO_MEM = 0, /*periphral to memory configuration*/
-+ LNW_DMA_MEM_TO_PER, /*memory to periphral configuration*/
-+ LNW_DMA_MEM_TO_MEM, /*mem to mem confg (testing only)*/
-+};
-+
-+/*DMA handshaking*/
-+enum lnw_dma_hs_mode {
-+ LNW_DMA_HW_HS = 0, /*HW Handshaking only*/
-+ LNW_DMA_SW_HS = 1, /*SW Handshaking not recommended*/
-+};
-+
-+/*Burst size configuration*/
-+enum lnw_dma_msize {
-+ LNW_DMA_MSIZE_1 = 0x0,
-+ LNW_DMA_MSIZE_4 = 0x1,
-+ LNW_DMA_MSIZE_8 = 0x2,
-+ LNW_DMA_MSIZE_16 = 0x3,
-+ LNW_DMA_MSIZE_32 = 0x4,
-+ LNW_DMA_MSIZE_64 = 0x5,
-+};
-+
-+/**
-+ * struct lnw_dma_slave - DMA slave structure
-+ *
-+ * @dma_dev: DMA master client
-+ * @tx_reg: physical address of data register used for
-+ * memory-to-peripheral transfers
-+ * @rx_reg: physical address of data register used for
-+ * peripheral-to-memory transfers
-+ * @tx_width: tx register width
-+ * @rx_width: rx register width
-+ * @dirn: DMA trf direction
-+
-+ * @cfg_hi: Platform-specific initializer for the CFG_HI register
-+ * @cfg_lo: Platform-specific initializer for the CFG_LO register
-+
-+ * @ tx_width: width of src and dstn
-+ * @ hs_mode: SW or HW handskaking mode
-+ * @ cfg_mode: Mode configuration, DMA mem to mem to dev & mem
-+ */
-+struct lnw_dma_slave {
-+ enum dma_data_direction dirn;
-+ enum lnw_dma_width src_width; /*width of DMA src txn*/
-+ enum lnw_dma_width dst_width; /*width of DMA dst txn*/
-+ enum lnw_dma_hs_mode hs_mode; /*handshaking*/
-+ enum lnw_dma_mode cfg_mode; /*mode configuration*/
-+ enum lnw_dma_msize src_msize; /*size if src burst*/
-+ enum lnw_dma_msize dst_msize; /*size of dst burst*/
-+ dma_async_tx_callback callback; /*callback function*/
-+ void *callback_param; /*param for callback*/
-+};
-+
-+/*DMA channel control registers*/
-+union lnw_dma_ctl_lo {
-+ struct {
-+ u32 int_en:1; /*enable or disable interrupts*/
-+ /*should be 0*/
-+ u32 dst_tr_width:3; /*destination transfer width*/
-+ /*usually 32 bits = 010*/
-+ u32 src_tr_width:3; /*source transfer width*/
-+ /*usually 32 bits = 010*/
-+ u32 dinc:2; /*destination address inc/dec*/
-+ /*For mem:INC=00, Periphral NoINC=11*/
-+ u32 sinc:2; /*source address inc or dec, as above*/
-+ u32 dst_msize:3; /*destination burst transaction length*/
-+ /*always = 16 ie 011*/
-+ u32 src_msize:3; /*source burst transaction length*/
-+ /*always = 16 ie 011*/
-+ u32 reser1:3;
-+ u32 tt_fc:3; /*transfer type and flow controller*/
-+ /*M-M = 000
-+ P-M = 010
-+ M-P = 001*/
-+ u32 dms:2; /*destination master select = 0*/
-+ u32 sms:2; /*source master select = 0*/
-+ u32 llp_dst_en:1; /*enable/disable destination LLP = 0*/
-+ u32 llp_src_en:1; /*enable/disable source LLP = 0*/
-+ u32 reser2:3;
-+ } ctlx;
-+ u32 ctl_lo;
-+};
-+
-+union lnw_dma_ctl_hi {
-+ struct {
-+ u32 block_ts:12; /*block transfer size*/
-+ /*configured by DMAC*/
-+ u32 reser:20;
-+ } ctlx;
-+ u32 ctl_hi;
-+
-+};
-+
-+/*DMA channel configuration registers*/
-+union lnw_dma_cfg_lo {
-+ struct {
-+ u32 reser1:5;
-+ u32 ch_prior:3; /*channel priority = 0*/
-+ u32 ch_susp:1; /*channel suspend = 0*/
-+ u32 fifo_empty:1; /*FIFO empty or not R bit = 0*/
-+ u32 hs_sel_dst:1; /*select HW/SW destn handshaking*/
-+ /*HW = 0, SW = 1*/
-+ u32 hs_sel_src:1; /*select HW/SW src handshaking*/
-+ u32 reser2:6;
-+ u32 dst_hs_pol:1; /*dest HS interface polarity*/
-+ u32 src_hs_pol:1; /*src HS interface polarity*/
-+ u32 max_abrst:10; /*max AMBA burst len = 0 (no sw limit*/
-+ u32 reload_src:1; /*auto reload src addr =1 if src is P*/
-+ u32 reload_dst:1; /*AR destn addr =1 if dstn is P*/
-+ } cfgx;
-+ u32 cfg_lo;
-+};
-+
-+union lnw_dma_cfg_hi {
-+ struct {
-+ u32 fcmode:1; /*flow control mode = 1*/
-+ u32 fifo_mode:1; /*FIFO mode select = 1*/
-+ u32 protctl:3; /*protection control = 0*/
-+ u32 rsvd:2;
-+ u32 src_per:4; /*src hw HS interface*/
-+ u32 dst_per:4; /*dstn hw HS interface*/
-+ u32 reser2:17;
-+ } cfgx;
-+ u32 cfg_hi;
-+};
-+
-+#endif /*__LNW_DMA_H__*/
-Index: linux-2.6.33/include/linux/intel_mid.h
-===================================================================
---- /dev/null
-+++ linux-2.6.33/include/linux/intel_mid.h
-@@ -0,0 +1,144 @@
-+/*
-+ * intel_mid.h - Netlink multicast interface definition for OSPM.
-+ *
-+ * Copyright (C) 2009 Intel Corp
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * 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; version 2 of the License.
-+ *
-+ * 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, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ * Authors: Sujith Thomas
-+ * Rajeev D Muralidhar
-+ * Vishwesh M Rudramuni
-+ * Nithish Mahalingam
-+ * Contact information:
-+ * Sujith Thomas <sujith.thomas@intel.com>
-+ * Rajeev D Muralidhar <rajeev.d.muralidhar@intel.com>
-+ * Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
-+ * Nithish Mahalingam <nithish.mahalingam@intel.com>
-+ *
-+ */
-+
-+#ifndef INTEL_MID_H
-+#define INTEL_MID_H
-+
-+#define PMU1_MAX_DEVS 2
-+#define PMU2_MAX_DEVS 12
-+#define PERIPH_MAX_DEVS 3
-+#define MAX_DEVICES (PMU1_MAX_DEVS + PMU2_MAX_DEVS + PERIPH_MAX_DEVS)
-+#define WAKE_CAPABLE 0x80000000
-+
-+struct pci_dev_info {
-+ u16 vendor_id;
-+ u16 device_id;
-+ u16 log_subsysid;
-+ u16 phy_susbsysid;
-+ u32 capability;
-+ struct pci_dev *dev_driver;
-+ char *dev_name;
-+};
-+
-+struct mid_ospm {
-+ u32 *pmu1_base;
-+ u32 *pmu1_pm_base;
-+ void __iomem *pmu2_base;
-+ u32 *pm_table_base;
-+ u32 pmu1_sub_systems;
-+ u32 pmu2_sub_systems;
-+ u32 pmu_wake_cfg;
-+ u32 pmu_wake_ss_states;
-+ u32 perepheral_sub_systems;
-+ int pmu2_states;
-+ int platform_sx_state;
-+ int s0ix_retry_enb;
-+ int fast_retry_exit;
-+ u32 pmode;
-+};
-+
-+extern struct pci_dev_info platform_pci_devices[MAX_DEVICES];
-+extern unsigned long g_intel_mid_wakeup_address;
-+
-+enum pmu_ss_state {
-+ SS_STATE_D0I0 = 0,
-+ SS_STATE_D0I1 = 1,
-+ SS_STATE_D0I2 = 2,
-+ SS_STATE_D0I3 = 3
-+};
-+
-+enum eospm_events {
-+ OSPM_EVENT_SUBSYS_INACTIVITY,
-+ OSPM_EVENT_SUBSYS_WAKE,
-+ OSPM_EVENT_SUBSYS_START_PLAY,
-+ OSPM_EVENT_SUBSYS_STOP_PLAY,
-+ OSPM_EVENT_CMD_SUCCESS,
-+ OSPM_EVENT_CMD_ERROR,
-+ OSPM_EVENT_CMD_NO_C6_ERROR,
-+ OSPM_EVENT_AUDIO_BUF_EMPTY,
-+ OSPM_EVENT_AUDIO_BUF_FULL,
-+ OSPM_EVENT_THERMAL_AUX0,
-+ OSPM_EVENT_THERMAL_AUX1,
-+ OSPM_EVENT_THERMAL_CRITICAL,
-+ OSPM_EVENT_THERMAL_DEV_FAULT,
-+ __OSPM_EVENT_COUNT,
-+};
-+
-+#define AUDIO_SUBSYTEM_ID 25
-+#define MID_S0I1_STATE 1
-+#define MID_S0I3_STATE 3
-+/* Thermal device Id */
-+#define TEMP_DEV_ID1 40
-+#define TEMP_DEV_ID2 41
-+#define TEMP_DEV_ID3 42
-+
-+/* First 32 (0-31) originators are subsystems
-+ Next 8 (0-7) are cmd IDs */
-+#define OSPM_CMDID_OFFSET 32
-+#define OSPM_MAX_CMD_ID 8
-+
-+struct ospm_genl_event {
-+ u32 orig;
-+ enum eospm_events event;
-+};
-+
-+/* attributes of ospm_genl_family */
-+enum {
-+ OSPM_GENL_ATTR_UNSPEC,
-+ OSPM_GENL_ATTR_EVENT, /* OSPM event info needed by user space */
-+ __OSPM_GENL_ATTR_MAX,
-+};
-+#define OSPM_GENL_ATTR_MAX (__OSPM_GENL_ATTR_MAX - 1)
-+
-+/* commands supported by the ospm_genl_family */
-+
-+enum {
-+ OSPM_GENL_CMD_UNSPEC,
-+ OSPM_GENL_CMD_EVENT, /* kernel->user notifications for OSPM events */
-+ __OSPM_GENL_CMD_MAX,
-+};
-+#define OSPM_GENL_CMD_MAX (__OSPM_GENL_CMD_MAX - 1)
-+
-+#define OSPM_GENL_FAMILY_NAME "ospm_event"
-+#define OSPM_GENL_VERSION 0x01
-+#define OSPM_GENL_MCAST_GROUP_NAME "ospm_mc_group"
-+
-+int ospm_generate_netlink_event(u32 orig, enum eospm_events event);
-+int ospm_event_genetlink_init(void);
-+void ospm_event_genetlink_exit(void);
-+
-+extern void intel_mid_reserve_bootmem(void);
-+extern unsigned long g_intel_mid_wakeup_address;
-+extern void find_pci_info(u32 device_id, u32 vendor_id, u32 *index);
-+extern int s0ix_non_bsp_init(void);
-+
-+#endif