diff options
Diffstat (limited to 'drivers/dma/pch_dma.c')
| -rw-r--r-- | drivers/dma/pch_dma.c | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 823f58179f9..9f9ca9fe5ce 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -21,10 +21,13 @@ #include <linux/dma-mapping.h> #include <linux/init.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/pch_dma.h> +#include "dmaengine.h" + #define DRV_NAME "pch-dma" #define DMA_CTL0_DISABLE 0x0 @@ -105,7 +108,6 @@ struct pch_dma_chan { spinlock_t lock; - dma_cookie_t completed_cookie; struct list_head active_list; struct list_head queue; struct list_head free_list; @@ -416,20 +418,6 @@ static void pdc_advance_work(struct pch_dma_chan *pd_chan) } } -static dma_cookie_t pdc_assign_cookie(struct pch_dma_chan *pd_chan, - struct pch_dma_desc *desc) -{ - dma_cookie_t cookie = pd_chan->chan.cookie; - - if (++cookie < 0) - cookie = 1; - - pd_chan->chan.cookie = cookie; - desc->txd.cookie = cookie; - - return cookie; -} - static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd) { struct pch_dma_desc *desc = to_pd_desc(txd); @@ -437,7 +425,7 @@ static dma_cookie_t pd_tx_submit(struct dma_async_tx_descriptor *txd) dma_cookie_t cookie; spin_lock(&pd_chan->lock); - cookie = pdc_assign_cookie(pd_chan, desc); + cookie = dma_cookie_assign(txd); if (list_empty(&pd_chan->active_list)) { list_add_tail(&desc->desc_node, &pd_chan->active_list); @@ -489,7 +477,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) dev_dbg(chan2dev(&pd_chan->chan), "scanned %d descriptors\n", i); if (!ret) { - ret = pdc_alloc_desc(&pd_chan->chan, GFP_NOIO); + ret = pdc_alloc_desc(&pd_chan->chan, GFP_ATOMIC); if (ret) { spin_lock(&pd_chan->lock); pd_chan->descs_allocated++; @@ -544,7 +532,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) spin_lock_irq(&pd_chan->lock); list_splice(&tmp_list, &pd_chan->free_list); pd_chan->descs_allocated = i; - pd_chan->completed_cookie = chan->cookie = 1; + dma_cookie_init(chan); spin_unlock_irq(&pd_chan->lock); pdc_enable_irq(chan, 1); @@ -577,21 +565,7 @@ static void pd_free_chan_resources(struct dma_chan *chan) static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *txstate) { - struct pch_dma_chan *pd_chan = to_pd_chan(chan); - dma_cookie_t last_used; - dma_cookie_t last_completed; - int ret; - - spin_lock_irq(&pd_chan->lock); - last_completed = pd_chan->completed_cookie; - last_used = chan->cookie; - spin_unlock_irq(&pd_chan->lock); - - ret = dma_async_is_complete(cookie, last_completed, last_used); - - dma_set_tx_state(txstate, last_completed, last_used, 0); - - return ret; + return dma_cookie_status(chan, cookie, txstate); } static void pd_issue_pending(struct dma_chan *chan) @@ -607,7 +581,8 @@ static void pd_issue_pending(struct dma_chan *chan) static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction direction, unsigned long flags) + enum dma_transfer_direction direction, unsigned long flags, + void *context) { struct pch_dma_chan *pd_chan = to_pd_chan(chan); struct pch_dma_slave *pd_slave = chan->private; @@ -640,7 +615,7 @@ static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, goto err_desc_get; desc->regs.dev_addr = reg; - desc->regs.mem_addr = sg_phys(sg); + desc->regs.mem_addr = sg_dma_address(sg); desc->regs.size = sg_dma_len(sg); desc->regs.next = DMA_DESC_FOLLOW_WITHOUT_IRQ; @@ -862,7 +837,7 @@ static int pch_dma_resume(struct pci_dev *pdev) } #endif -static int __devinit pch_dma_probe(struct pci_dev *pdev, +static int pch_dma_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct pch_dma *pd; @@ -886,6 +861,7 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { dev_err(&pdev->dev, "Cannot find proper base address\n"); + err = -ENODEV; goto err_disable_pdev; } @@ -932,7 +908,7 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, struct pch_dma_chan *pd_chan = &pd->channels[i]; pd_chan->chan.device = &pd->dma; - pd_chan->chan.cookie = 1; + dma_cookie_init(&pd_chan->chan); pd_chan->membase = ®s->desc[i]; @@ -980,7 +956,7 @@ err_free_mem: return err; } -static void __devexit pch_dma_remove(struct pci_dev *pdev) +static void pch_dma_remove(struct pci_dev *pdev) { struct pch_dma *pd = pci_get_drvdata(pdev); struct pch_dma_chan *pd_chan; @@ -989,16 +965,16 @@ static void __devexit pch_dma_remove(struct pci_dev *pdev) if (pd) { dma_async_device_unregister(&pd->dma); + free_irq(pdev->irq, pd); + list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { pd_chan = to_pd_chan(chan); - tasklet_disable(&pd_chan->tasklet); tasklet_kill(&pd_chan->tasklet); } pci_pool_destroy(pd->pool); - free_irq(pdev->irq, pd); pci_iounmap(pdev, pd->membase); pci_release_regions(pdev); pci_disable_device(pdev); @@ -1021,7 +997,7 @@ static void __devexit pch_dma_remove(struct pci_dev *pdev) #define PCI_DEVICE_ID_ML7831_DMA1_8CH 0x8810 #define PCI_DEVICE_ID_ML7831_DMA2_4CH 0x8815 -DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = { +const struct pci_device_id pch_dma_id_table[] = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */ @@ -1041,27 +1017,17 @@ static struct pci_driver pch_dma_driver = { .name = DRV_NAME, .id_table = pch_dma_id_table, .probe = pch_dma_probe, - .remove = __devexit_p(pch_dma_remove), + .remove = pch_dma_remove, #ifdef CONFIG_PM .suspend = pch_dma_suspend, .resume = pch_dma_resume, #endif }; -static int __init pch_dma_init(void) -{ - return pci_register_driver(&pch_dma_driver); -} - -static void __exit pch_dma_exit(void) -{ - pci_unregister_driver(&pch_dma_driver); -} - -module_init(pch_dma_init); -module_exit(pch_dma_exit); +module_pci_driver(pch_dma_driver); MODULE_DESCRIPTION("Intel EG20T PCH / LAPIS Semicon ML7213/ML7223/ML7831 IOH " "DMA controller driver"); MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>"); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(pci, pch_dma_id_table); |
