Commit 10a2f11d authored by Arnaud de Turckheim's avatar Arnaud de Turckheim Committed by Bartosz Golaszewski

gpio: pcie-idio-24: Enable PEX8311 interrupts

This enables the PEX8311 internal PCI wire interrupt and the PEX8311
local interrupt input so the local interrupts are forwarded to the PCI.

Fixes: 58556204 ("gpio: Add GPIO support for the ACCES PCIe-IDIO-24 family")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarArnaud de Turckheim <quarium@gmail.com>
Reviewed-by: default avatarWilliam Breathitt Gray <vilhelm.gray@gmail.com>
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
parent 23a7fdc0
...@@ -28,6 +28,47 @@ ...@@ -28,6 +28,47 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/types.h> #include <linux/types.h>
/*
* PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status
*
* Bit: Description
* 0: Enable Interrupt Sources (Bit 0)
* 1: Enable Interrupt Sources (Bit 1)
* 2: Generate Internal PCI Bus Internal SERR# Interrupt
* 3: Mailbox Interrupt Enable
* 4: Power Management Interrupt Enable
* 5: Power Management Interrupt
* 6: Slave Read Local Data Parity Check Error Enable
* 7: Slave Read Local Data Parity Check Error Status
* 8: Internal PCI Wire Interrupt Enable
* 9: PCI Express Doorbell Interrupt Enable
* 10: PCI Abort Interrupt Enable
* 11: Local Interrupt Input Enable
* 12: Retry Abort Enable
* 13: PCI Express Doorbell Interrupt Active
* 14: PCI Abort Interrupt Active
* 15: Local Interrupt Input Active
* 16: Local Interrupt Output Enable
* 17: Local Doorbell Interrupt Enable
* 18: DMA Channel 0 Interrupt Enable
* 19: DMA Channel 1 Interrupt Enable
* 20: Local Doorbell Interrupt Active
* 21: DMA Channel 0 Interrupt Active
* 22: DMA Channel 1 Interrupt Active
* 23: Built-In Self-Test (BIST) Interrupt Active
* 24: Direct Master was the Bus Master during a Master or Target Abort
* 25: DMA Channel 0 was the Bus Master during a Master or Target Abort
* 26: DMA Channel 1 was the Bus Master during a Master or Target Abort
* 27: Target Abort after internal 256 consecutive Master Retrys
* 28: PCI Bus wrote data to LCS_MBOX0
* 29: PCI Bus wrote data to LCS_MBOX1
* 30: PCI Bus wrote data to LCS_MBOX2
* 31: PCI Bus wrote data to LCS_MBOX3
*/
#define PLX_PEX8311_PCI_LCS_INTCSR 0x68
#define INTCSR_INTERNAL_PCI_WIRE BIT(8)
#define INTCSR_LOCAL_INPUT BIT(11)
/** /**
* struct idio_24_gpio_reg - GPIO device registers structure * struct idio_24_gpio_reg - GPIO device registers structure
* @out0_7: Read: FET Outputs 0-7 * @out0_7: Read: FET Outputs 0-7
...@@ -92,6 +133,7 @@ struct idio_24_gpio_reg { ...@@ -92,6 +133,7 @@ struct idio_24_gpio_reg {
struct idio_24_gpio { struct idio_24_gpio {
struct gpio_chip chip; struct gpio_chip chip;
raw_spinlock_t lock; raw_spinlock_t lock;
__u8 __iomem *plx;
struct idio_24_gpio_reg __iomem *reg; struct idio_24_gpio_reg __iomem *reg;
unsigned long irq_mask; unsigned long irq_mask;
}; };
...@@ -455,6 +497,7 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -455,6 +497,7 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct device *const dev = &pdev->dev; struct device *const dev = &pdev->dev;
struct idio_24_gpio *idio24gpio; struct idio_24_gpio *idio24gpio;
int err; int err;
const size_t pci_plx_bar_index = 1;
const size_t pci_bar_index = 2; const size_t pci_bar_index = 2;
const char *const name = pci_name(pdev); const char *const name = pci_name(pdev);
struct gpio_irq_chip *girq; struct gpio_irq_chip *girq;
...@@ -469,12 +512,13 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -469,12 +512,13 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return err; return err;
} }
err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name); err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
if (err) { if (err) {
dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err); dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
return err; return err;
} }
idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index]; idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
idio24gpio->chip.label = name; idio24gpio->chip.label = name;
...@@ -504,6 +548,12 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -504,6 +548,12 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Software board reset */ /* Software board reset */
iowrite8(0, &idio24gpio->reg->soft_reset); iowrite8(0, &idio24gpio->reg->soft_reset);
/*
* enable PLX PEX8311 internal PCI wire interrupt and local interrupt
* input
*/
iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio); err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
if (err) { if (err) {
......
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