Commit 2cbb743f authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

pcie_wb: turn on/off non-MSI interrupts as required

Usually our cards are used in MSI mode. On older motherboards, they
can fall back to classic interrupt generation. However, then the
interrupt enable register in the card must be turned on.
parent b86076fa
...@@ -46,6 +46,11 @@ static void compat_pci_clear_master(struct pci_dev *dev) ...@@ -46,6 +46,11 @@ static void compat_pci_clear_master(struct pci_dev *dev)
#define pci_clear_master compat_pci_clear_master #define pci_clear_master compat_pci_clear_master
#endif #endif
static void pcie_int_enable(struct pcie_wb_dev *dev, int on)
{
int enable = on && !dev->msi;
iowrite32((enable?0x20000000UL:0) + 0x10000000UL, dev->pci_res[0].addr + CONTROL_REGISTER_HIGH);
}
static void wb_cycle(struct wishbone* wb, int on) static void wb_cycle(struct wishbone* wb, int on)
{ {
...@@ -230,6 +235,8 @@ static int wb_request(struct wishbone *wb, struct wishbone_request *req) ...@@ -230,6 +235,8 @@ static int wb_request(struct wishbone *wb, struct wishbone_request *req)
if (out) iowrite32(1, control + MASTER_CTL_HIGH); /* dequeue operation */ if (out) iowrite32(1, control + MASTER_CTL_HIGH); /* dequeue operation */
pcie_int_enable(dev, 1);
return out; return out;
} }
...@@ -261,7 +268,8 @@ static irqreturn_t irq_handler(int irq, void *dev_id) ...@@ -261,7 +268,8 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
struct pcie_wb_dev *dev = dev_id; struct pcie_wb_dev *dev = dev_id;
if (unlikely(debug)) printk(KERN_ALERT "posting MSI\n"); if (unlikely(debug)) printk(KERN_ALERT "posting MSI\n");
pcie_int_enable(dev, 0);
wishbone_slave_ready(&dev->wb); wishbone_slave_ready(&dev->wb);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -364,12 +372,15 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -364,12 +372,15 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* disable legacy interrupts when using MSI */ /* disable legacy interrupts when using MSI */
pci_intx(pdev, 0); pci_intx(pdev, 0);
} }
if (request_irq(pdev->irq, irq_handler, 0, "pcie_wb", dev) < 0) { if (request_irq(pdev->irq, irq_handler, 0, "pcie_wb", dev) < 0) {
printk(KERN_ALERT PCIE_WB ": could not register interrupt handler\n"); printk(KERN_ALERT PCIE_WB ": could not register interrupt handler\n");
goto fail_msi; goto fail_msi;
} }
/* Enable classic interrupts */
pcie_int_enable(dev, 1);
if (wishbone_register(&dev->wb) < 0) { if (wishbone_register(&dev->wb) < 0) {
printk(KERN_ALERT PCIE_WB ": could not register wishbone bus\n"); printk(KERN_ALERT PCIE_WB ": could not register wishbone bus\n");
goto fail_irq; goto fail_irq;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment