forked from luck/tmp_suning_uos_patched
dmaengine fixes for 4.8-rc5
The fixes this time are all in drivers: o possible NULL dereference in img-mdc o correct device identity for free_irq in at_xdmac o missing of_node_put() in fsl probe o fix debug log and hotchain corner case for pxa-dma o fix checking hardware bits in isr in usb dmac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXyVvqAAoJEHwUBw8lI4NHiCEQAKVLFj94XEveZo/h/ypub9EO g0c/fsOQKwrHgLmAAAUB/NGIUaEmBFWmEmBf+DnaHN8Y3OXzmBbRAdx2fbewL5yY iBzkyxvixQsiS9lXMqFTOnggavjunsYfSK0kBDkx1nyqY8b4otgJ95YIVT+1wRie THl81etBcFaOM0h2RrDUx8/K1Ve9LK4UF2KVEuHGWkgEw2Su3/tgL1xQARmiXvPr rNlzQS5lw1t1nSZjfgQ+Ds2TL4EVcis+uHHumZX6GTFdoRh8qJMnlDTWgN0fDYLb pbNG7MgLpiRTDGPRVgwRwGd+DjcgIXjt5NgJPrwd791X8tIz4UZ7t6et+DYH9lhe rr9pa11P0w0l49suyWMoPzST3o+M0XRIAcwqxJURzaCv2bN6lquA0jlVkPy/kHQ4 rOLN8FMkVVzhlL0rRf+c1t4c6RdP2Ew6AQ3haEMXVCsvKKvecb/7uV5OAYXSRnNA VPvH0ONFnQrGBrDabI6hCJMCyVsYuTt/mv03Y/ZssKBTj9Cly4sptrigVnTDYTDh KddzCPQ1RdVVJIA282DiKxP3sC+tILuz3gqpSNVBLI6FFOeZD0AU/hT8HNfw6CKQ U3nr8D1txRl8GS7X7Ixi+esj81GpaEENP8UtLhCI2q0PKfpgx5vwlGS0R6otpK5A 0/zP6hOGIw37TJvCtrkG =0onD -----END PGP SIGNATURE----- Merge tag 'dmaengine-fix-4.8-rc5' of git://git.infradead.org/users/vkoul/slave-dma Pull dmaengine fixes from Vinod Koul: "The fixes this time are all in drivers: - possible NULL dereference in img-mdc - correct device identity for free_irq in at_xdmac - missing of_node_put() in fsl probe - fix debug log and hotchain corner case for pxa-dma - fix checking hardware bits in isr in usb dmac" * tag 'dmaengine-fix-4.8-rc5' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: img-mdc: fix a possible NULL dereference dmaengine: at_xdmac: fix to pass correct device identity to free_irq() dmaengine: fsl_raid: add missing of_node_put() in fsl_re_probe() dmaengine: pxa_dma: fix debug message dmaengine: pxa_dma: fix hotchain corner case dmaengine: usb-dmac: check CHCR.DE bit in usb_dmac_isr_channel()
This commit is contained in:
commit
ac8103840b
@ -2067,7 +2067,7 @@ static int at_xdmac_probe(struct platform_device *pdev)
|
|||||||
err_clk_disable:
|
err_clk_disable:
|
||||||
clk_disable_unprepare(atxdmac->clk);
|
clk_disable_unprepare(atxdmac->clk);
|
||||||
err_free_irq:
|
err_free_irq:
|
||||||
free_irq(atxdmac->irq, atxdmac->dma.dev);
|
free_irq(atxdmac->irq, atxdmac);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2081,7 +2081,7 @@ static int at_xdmac_remove(struct platform_device *pdev)
|
|||||||
dma_async_device_unregister(&atxdmac->dma);
|
dma_async_device_unregister(&atxdmac->dma);
|
||||||
clk_disable_unprepare(atxdmac->clk);
|
clk_disable_unprepare(atxdmac->clk);
|
||||||
|
|
||||||
free_irq(atxdmac->irq, atxdmac->dma.dev);
|
free_irq(atxdmac->irq, atxdmac);
|
||||||
|
|
||||||
for (i = 0; i < atxdmac->dma.chancnt; i++) {
|
for (i = 0; i < atxdmac->dma.chancnt; i++) {
|
||||||
struct at_xdmac_chan *atchan = &atxdmac->chan[i];
|
struct at_xdmac_chan *atchan = &atxdmac->chan[i];
|
||||||
|
@ -836,6 +836,7 @@ static int fsl_re_probe(struct platform_device *ofdev)
|
|||||||
rc = of_property_read_u32(np, "reg", &off);
|
rc = of_property_read_u32(np, "reg", &off);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dev_err(dev, "Reg property not found in JQ node\n");
|
dev_err(dev, "Reg property not found in JQ node\n");
|
||||||
|
of_node_put(np);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
/* Find out the Job Rings present under each JQ */
|
/* Find out the Job Rings present under each JQ */
|
||||||
|
@ -861,7 +861,6 @@ static int mdc_dma_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct mdc_dma *mdma;
|
struct mdc_dma *mdma;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
const struct of_device_id *match;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u32 val;
|
u32 val;
|
||||||
int ret;
|
int ret;
|
||||||
@ -871,8 +870,7 @@ static int mdc_dma_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
platform_set_drvdata(pdev, mdma);
|
platform_set_drvdata(pdev, mdma);
|
||||||
|
|
||||||
match = of_match_device(mdc_dma_of_match, &pdev->dev);
|
mdma->soc = of_device_get_match_data(&pdev->dev);
|
||||||
mdma->soc = match->data;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
mdma->regs = devm_ioremap_resource(&pdev->dev, res);
|
mdma->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
@ -638,7 +638,7 @@ static bool pxad_try_hotchain(struct virt_dma_chan *vc,
|
|||||||
vd_last_issued = list_entry(vc->desc_issued.prev,
|
vd_last_issued = list_entry(vc->desc_issued.prev,
|
||||||
struct virt_dma_desc, node);
|
struct virt_dma_desc, node);
|
||||||
pxad_desc_chain(vd_last_issued, vd);
|
pxad_desc_chain(vd_last_issued, vd);
|
||||||
if (is_chan_running(chan) || is_desc_completed(vd_last_issued))
|
if (is_chan_running(chan) || is_desc_completed(vd))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,6 +671,7 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id)
|
|||||||
struct virt_dma_desc *vd, *tmp;
|
struct virt_dma_desc *vd, *tmp;
|
||||||
unsigned int dcsr;
|
unsigned int dcsr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
bool vd_completed;
|
||||||
dma_cookie_t last_started = 0;
|
dma_cookie_t last_started = 0;
|
||||||
|
|
||||||
BUG_ON(!chan);
|
BUG_ON(!chan);
|
||||||
@ -681,15 +682,17 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id)
|
|||||||
|
|
||||||
spin_lock_irqsave(&chan->vc.lock, flags);
|
spin_lock_irqsave(&chan->vc.lock, flags);
|
||||||
list_for_each_entry_safe(vd, tmp, &chan->vc.desc_issued, node) {
|
list_for_each_entry_safe(vd, tmp, &chan->vc.desc_issued, node) {
|
||||||
|
vd_completed = is_desc_completed(vd);
|
||||||
dev_dbg(&chan->vc.chan.dev->device,
|
dev_dbg(&chan->vc.chan.dev->device,
|
||||||
"%s(): checking txd %p[%x]: completed=%d\n",
|
"%s(): checking txd %p[%x]: completed=%d dcsr=0x%x\n",
|
||||||
__func__, vd, vd->tx.cookie, is_desc_completed(vd));
|
__func__, vd, vd->tx.cookie, vd_completed,
|
||||||
|
dcsr);
|
||||||
last_started = vd->tx.cookie;
|
last_started = vd->tx.cookie;
|
||||||
if (to_pxad_sw_desc(vd)->cyclic) {
|
if (to_pxad_sw_desc(vd)->cyclic) {
|
||||||
vchan_cyclic_callback(vd);
|
vchan_cyclic_callback(vd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (is_desc_completed(vd)) {
|
if (vd_completed) {
|
||||||
list_del(&vd->node);
|
list_del(&vd->node);
|
||||||
vchan_cookie_complete(vd);
|
vchan_cookie_complete(vd);
|
||||||
} else {
|
} else {
|
||||||
|
@ -600,27 +600,30 @@ static irqreturn_t usb_dmac_isr_channel(int irq, void *dev)
|
|||||||
{
|
{
|
||||||
struct usb_dmac_chan *chan = dev;
|
struct usb_dmac_chan *chan = dev;
|
||||||
irqreturn_t ret = IRQ_NONE;
|
irqreturn_t ret = IRQ_NONE;
|
||||||
u32 mask = USB_DMACHCR_TE;
|
u32 mask = 0;
|
||||||
u32 check_bits = USB_DMACHCR_TE | USB_DMACHCR_SP;
|
|
||||||
u32 chcr;
|
u32 chcr;
|
||||||
|
bool xfer_end = false;
|
||||||
|
|
||||||
spin_lock(&chan->vc.lock);
|
spin_lock(&chan->vc.lock);
|
||||||
|
|
||||||
chcr = usb_dmac_chan_read(chan, USB_DMACHCR);
|
chcr = usb_dmac_chan_read(chan, USB_DMACHCR);
|
||||||
if (chcr & check_bits)
|
if (chcr & (USB_DMACHCR_TE | USB_DMACHCR_SP)) {
|
||||||
mask |= USB_DMACHCR_DE | check_bits;
|
mask |= USB_DMACHCR_DE | USB_DMACHCR_TE | USB_DMACHCR_SP;
|
||||||
|
if (chcr & USB_DMACHCR_DE)
|
||||||
|
xfer_end = true;
|
||||||
|
ret |= IRQ_HANDLED;
|
||||||
|
}
|
||||||
if (chcr & USB_DMACHCR_NULL) {
|
if (chcr & USB_DMACHCR_NULL) {
|
||||||
/* An interruption of TE will happen after we set FTE */
|
/* An interruption of TE will happen after we set FTE */
|
||||||
mask |= USB_DMACHCR_NULL;
|
mask |= USB_DMACHCR_NULL;
|
||||||
chcr |= USB_DMACHCR_FTE;
|
chcr |= USB_DMACHCR_FTE;
|
||||||
ret |= IRQ_HANDLED;
|
ret |= IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask);
|
if (mask)
|
||||||
|
usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask);
|
||||||
|
|
||||||
if (chcr & check_bits) {
|
if (xfer_end)
|
||||||
usb_dmac_isr_transfer_end(chan);
|
usb_dmac_isr_transfer_end(chan);
|
||||||
ret |= IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&chan->vc.lock);
|
spin_unlock(&chan->vc.lock);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user