Message ID | 1395319870-3929-1-git-send-email-tim.gardner@canonical.com |
---|---|
State | New |
Headers | show |
On 03/20/2014 05:51 AM, tim.gardner@canonical.com wrote: > From: Dave Jiang <dave.jiang@intel.com> > > BugLink: http://bugs.launchpad.net/bugs/1291113 > > The Intel Atom S1200 family ioatdma changed the channel reset behavior. > It does a reset similar to PCI FLR by resetting all the MSIX > registers. We have to re-init msix interrupts because of this. This > workaround is only specific to this platform and is not expected to carry > over to the later generations. > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> > Acked-by: Dan Williams <djbw@fb.com> > Signed-off-by: Vinod Koul <vinod.koul@intel.com> > (back ported from commit 8a52b9ff1154a68b6a2a8da9a31a87e52f5f6418) > > Back port notes: I implemented enough of this patch to support > device->irq_mode storage, upon which da87ca4d4ca101f177fffd84f1f0a5e4c0343557 > (ioat: fix tasklet tear down) is dependent. > > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> > --- > drivers/dma/ioat/dma.c | 8 +++++++- > drivers/dma/ioat/dma.h | 10 ++++++++++ > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c > index 6595180..fe5152a 100644 > --- a/drivers/dma/ioat/dma.c > +++ b/drivers/dma/ioat/dma.c > @@ -890,7 +890,7 @@ MODULE_PARM_DESC(ioat_interrupt_style, > * ioat_dma_setup_interrupts - setup interrupt handler > * @device: ioat device > */ > -static int ioat_dma_setup_interrupts(struct ioatdma_device *device) > +int ioat_dma_setup_interrupts(struct ioatdma_device *device) > { > struct ioat_chan_common *chan; > struct pci_dev *pdev = device->pdev; > @@ -939,6 +939,7 @@ msix: > } > } > intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; > + device->irq_mode = IOAT_MSIX; > goto done; > > msix_single_vector: > @@ -954,6 +955,7 @@ msix_single_vector: > pci_disable_msix(pdev); > goto msi; > } > + device->irq_mode = IOAT_MSIX_SINGLE; > goto done; > > msi: > @@ -967,6 +969,7 @@ msi: > pci_disable_msi(pdev); > goto intx; > } > + device->irq_mode = IOAT_MSIX; > goto done; > > intx: > @@ -975,6 +978,7 @@ intx: > if (err) > goto err_no_irq; > > + device->irq_mode = IOAT_INTX; > done: > if (device->intr_quirk) > device->intr_quirk(device); > @@ -985,9 +989,11 @@ done: > err_no_irq: > /* Disable all interrupt generation */ > writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); > + device->irq_mode = IOAT_NOIRQ; > dev_err(dev, "no usable interrupts\n"); > return err; > } > +EXPORT_SYMBOL(ioat_dma_setup_interrupts); > > static void ioat_disable_interrupts(struct ioatdma_device *device) > { > diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h > index 8bebddd..148883e 100644 > --- a/drivers/dma/ioat/dma.h > +++ b/drivers/dma/ioat/dma.h > @@ -48,6 +48,14 @@ > */ > #define NULL_DESC_BUFFER_SIZE 1 > > +enum ioat_irq_mode { > + IOAT_NOIRQ = 0, > + IOAT_MSIX, > + IOAT_MSIX_SINGLE, > + IOAT_MSI, > + IOAT_INTX > +}; > + > /** > * struct ioatdma_device - internal representation of a IOAT device > * @pdev: PCI-Express device > @@ -77,6 +85,7 @@ struct ioatdma_device { > struct msix_entry msix_entries[4]; > struct ioat_chan_common *idx[4]; > struct dca_provider *dca; > + enum ioat_irq_mode irq_mode; > void (*intr_quirk)(struct ioatdma_device *device); > int (*enumerate_channels)(struct ioatdma_device *device); > int (*reset_hw)(struct ioat_chan_common *chan); > @@ -344,6 +353,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, > dma_addr_t *phys_complete); > void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); > void ioat_kobject_del(struct ioatdma_device *device); > +int ioat_dma_setup_interrupts(struct ioatdma_device *device); > extern const struct sysfs_ops ioat_sysfs_ops; > extern struct ioat_sysfs_entry ioat_version_attr; > extern struct ioat_sysfs_entry ioat_cap_attr; > Looks like a faithful backport of the upstream commit and you got positive testing results.
On 03/20/2014 05:51 AM, tim.gardner@canonical.com wrote: > From: Dave Jiang <dave.jiang@intel.com> > > BugLink: http://bugs.launchpad.net/bugs/1291113 > > The Intel Atom S1200 family ioatdma changed the channel reset behavior. > It does a reset similar to PCI FLR by resetting all the MSIX > registers. We have to re-init msix interrupts because of this. This > workaround is only specific to this platform and is not expected to carry > over to the later generations. > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> > Acked-by: Dan Williams <djbw@fb.com> > Signed-off-by: Vinod Koul <vinod.koul@intel.com> > (back ported from commit 8a52b9ff1154a68b6a2a8da9a31a87e52f5f6418) > > Back port notes: I implemented enough of this patch to support > device->irq_mode storage, upon which da87ca4d4ca101f177fffd84f1f0a5e4c0343557 > (ioat: fix tasklet tear down) is dependent. > > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> > --- > drivers/dma/ioat/dma.c | 8 +++++++- > drivers/dma/ioat/dma.h | 10 ++++++++++ > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c > index 6595180..fe5152a 100644 > --- a/drivers/dma/ioat/dma.c > +++ b/drivers/dma/ioat/dma.c > @@ -890,7 +890,7 @@ MODULE_PARM_DESC(ioat_interrupt_style, > * ioat_dma_setup_interrupts - setup interrupt handler > * @device: ioat device > */ > -static int ioat_dma_setup_interrupts(struct ioatdma_device *device) > +int ioat_dma_setup_interrupts(struct ioatdma_device *device) > { > struct ioat_chan_common *chan; > struct pci_dev *pdev = device->pdev; > @@ -939,6 +939,7 @@ msix: > } > } > intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; > + device->irq_mode = IOAT_MSIX; > goto done; > > msix_single_vector: > @@ -954,6 +955,7 @@ msix_single_vector: > pci_disable_msix(pdev); > goto msi; > } > + device->irq_mode = IOAT_MSIX_SINGLE; > goto done; > > msi: > @@ -967,6 +969,7 @@ msi: > pci_disable_msi(pdev); > goto intx; > } > + device->irq_mode = IOAT_MSIX; > goto done; > > intx: > @@ -975,6 +978,7 @@ intx: > if (err) > goto err_no_irq; > > + device->irq_mode = IOAT_INTX; > done: > if (device->intr_quirk) > device->intr_quirk(device); > @@ -985,9 +989,11 @@ done: > err_no_irq: > /* Disable all interrupt generation */ > writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); > + device->irq_mode = IOAT_NOIRQ; > dev_err(dev, "no usable interrupts\n"); > return err; > } > +EXPORT_SYMBOL(ioat_dma_setup_interrupts); > > static void ioat_disable_interrupts(struct ioatdma_device *device) > { > diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h > index 8bebddd..148883e 100644 > --- a/drivers/dma/ioat/dma.h > +++ b/drivers/dma/ioat/dma.h > @@ -48,6 +48,14 @@ > */ > #define NULL_DESC_BUFFER_SIZE 1 > > +enum ioat_irq_mode { > + IOAT_NOIRQ = 0, > + IOAT_MSIX, > + IOAT_MSIX_SINGLE, > + IOAT_MSI, > + IOAT_INTX > +}; > + > /** > * struct ioatdma_device - internal representation of a IOAT device > * @pdev: PCI-Express device > @@ -77,6 +85,7 @@ struct ioatdma_device { > struct msix_entry msix_entries[4]; > struct ioat_chan_common *idx[4]; > struct dca_provider *dca; > + enum ioat_irq_mode irq_mode; > void (*intr_quirk)(struct ioatdma_device *device); > int (*enumerate_channels)(struct ioatdma_device *device); > int (*reset_hw)(struct ioat_chan_common *chan); > @@ -344,6 +353,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, > dma_addr_t *phys_complete); > void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); > void ioat_kobject_del(struct ioatdma_device *device); > +int ioat_dma_setup_interrupts(struct ioatdma_device *device); > extern const struct sysfs_ops ioat_sysfs_ops; > extern struct ioat_sysfs_entry ioat_version_attr; > extern struct ioat_sysfs_entry ioat_cap_attr; >
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 6595180..fe5152a 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -890,7 +890,7 @@ MODULE_PARM_DESC(ioat_interrupt_style, * ioat_dma_setup_interrupts - setup interrupt handler * @device: ioat device */ -static int ioat_dma_setup_interrupts(struct ioatdma_device *device) +int ioat_dma_setup_interrupts(struct ioatdma_device *device) { struct ioat_chan_common *chan; struct pci_dev *pdev = device->pdev; @@ -939,6 +939,7 @@ msix: } } intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; + device->irq_mode = IOAT_MSIX; goto done; msix_single_vector: @@ -954,6 +955,7 @@ msix_single_vector: pci_disable_msix(pdev); goto msi; } + device->irq_mode = IOAT_MSIX_SINGLE; goto done; msi: @@ -967,6 +969,7 @@ msi: pci_disable_msi(pdev); goto intx; } + device->irq_mode = IOAT_MSIX; goto done; intx: @@ -975,6 +978,7 @@ intx: if (err) goto err_no_irq; + device->irq_mode = IOAT_INTX; done: if (device->intr_quirk) device->intr_quirk(device); @@ -985,9 +989,11 @@ done: err_no_irq: /* Disable all interrupt generation */ writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); + device->irq_mode = IOAT_NOIRQ; dev_err(dev, "no usable interrupts\n"); return err; } +EXPORT_SYMBOL(ioat_dma_setup_interrupts); static void ioat_disable_interrupts(struct ioatdma_device *device) { diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 8bebddd..148883e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -48,6 +48,14 @@ */ #define NULL_DESC_BUFFER_SIZE 1 +enum ioat_irq_mode { + IOAT_NOIRQ = 0, + IOAT_MSIX, + IOAT_MSIX_SINGLE, + IOAT_MSI, + IOAT_INTX +}; + /** * struct ioatdma_device - internal representation of a IOAT device * @pdev: PCI-Express device @@ -77,6 +85,7 @@ struct ioatdma_device { struct msix_entry msix_entries[4]; struct ioat_chan_common *idx[4]; struct dca_provider *dca; + enum ioat_irq_mode irq_mode; void (*intr_quirk)(struct ioatdma_device *device); int (*enumerate_channels)(struct ioatdma_device *device); int (*reset_hw)(struct ioat_chan_common *chan); @@ -344,6 +353,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, dma_addr_t *phys_complete); void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); void ioat_kobject_del(struct ioatdma_device *device); +int ioat_dma_setup_interrupts(struct ioatdma_device *device); extern const struct sysfs_ops ioat_sysfs_ops; extern struct ioat_sysfs_entry ioat_version_attr; extern struct ioat_sysfs_entry ioat_cap_attr;