aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2014-02-17 21:11:01 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-02-18 15:19:50 -0500
commit80a595d941a2ce2953e6c77d822d8a4c3d8fa5a0 (patch)
treed5e0ca035ad52edd0807b3585d3e651a9237b295 /drivers/pci/host
parented65b78881c713b41051310780f94bde3c010db9 (diff)
PCI: rcar: Add error interrupt handling
Add option to enable interrupts to report any errors from the AHB-PCI bridge to help find any issues with the bridge when in use. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/pci/host')
-rw-r--r--drivers/pci/host/pci-rcar-gen2.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index 201e4a450340..11e444e79f45 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -39,9 +39,26 @@
39 39
40#define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20) 40#define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
41#define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24) 41#define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
42#define RCAR_PCI_INT_SIGTABORT (1 << 0)
43#define RCAR_PCI_INT_SIGRETABORT (1 << 1)
44#define RCAR_PCI_INT_REMABORT (1 << 2)
45#define RCAR_PCI_INT_PERR (1 << 3)
46#define RCAR_PCI_INT_SIGSERR (1 << 4)
47#define RCAR_PCI_INT_RESERR (1 << 5)
48#define RCAR_PCI_INT_WIN1ERR (1 << 12)
49#define RCAR_PCI_INT_WIN2ERR (1 << 13)
42#define RCAR_PCI_INT_A (1 << 16) 50#define RCAR_PCI_INT_A (1 << 16)
43#define RCAR_PCI_INT_B (1 << 17) 51#define RCAR_PCI_INT_B (1 << 17)
44#define RCAR_PCI_INT_PME (1 << 19) 52#define RCAR_PCI_INT_PME (1 << 19)
53#define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT | \
54 RCAR_PCI_INT_SIGRETABORT | \
55 RCAR_PCI_INT_SIGRETABORT | \
56 RCAR_PCI_INT_REMABORT | \
57 RCAR_PCI_INT_PERR | \
58 RCAR_PCI_INT_SIGSERR | \
59 RCAR_PCI_INT_RESERR | \
60 RCAR_PCI_INT_WIN1ERR | \
61 RCAR_PCI_INT_WIN2ERR)
45 62
46#define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30) 63#define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
47#define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0) 64#define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0)
@@ -164,6 +181,46 @@ static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
164 return priv->irq; 181 return priv->irq;
165} 182}
166 183
184#ifdef CONFIG_PCI_DEBUG
185/* if debug enabled, then attach an error handler irq to the bridge */
186
187static irqreturn_t rcar_pci_err_irq(int irq, void *pw)
188{
189 struct rcar_pci_priv *priv = pw;
190 u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG);
191
192 if (status & RCAR_PCI_INT_ALLERRORS) {
193 dev_err(priv->dev, "error irq: status %08x\n", status);
194
195 /* clear the error(s) */
196 iowrite32(status & RCAR_PCI_INT_ALLERRORS,
197 priv->reg + RCAR_PCI_INT_STATUS_REG);
198 return IRQ_HANDLED;
199 }
200
201 return IRQ_NONE;
202}
203
204static void rcar_pci_setup_errirq(struct rcar_pci_priv *priv)
205{
206 int ret;
207 u32 val;
208
209 ret = devm_request_irq(priv->dev, priv->irq, rcar_pci_err_irq,
210 IRQF_SHARED, "error irq", priv);
211 if (ret) {
212 dev_err(priv->dev, "cannot claim IRQ for error handling\n");
213 return;
214 }
215
216 val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG);
217 val |= RCAR_PCI_INT_ALLERRORS;
218 iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG);
219}
220#else
221static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { }
222#endif
223
167/* PCI host controller setup */ 224/* PCI host controller setup */
168static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) 225static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
169{ 226{
@@ -224,6 +281,9 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
224 iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, 281 iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
225 reg + RCAR_PCI_INT_ENABLE_REG); 282 reg + RCAR_PCI_INT_ENABLE_REG);
226 283
284 if (priv->irq > 0)
285 rcar_pci_setup_errirq(priv);
286
227 /* Add PCI resources */ 287 /* Add PCI resources */
228 pci_add_resource(&sys->resources, &priv->io_res); 288 pci_add_resource(&sys->resources, &priv->io_res);
229 pci_add_resource(&sys->resources, &priv->mem_res); 289 pci_add_resource(&sys->resources, &priv->mem_res);