aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-08-20 02:59:40 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-08-20 02:59:40 -0400
commit7656e2486cb1ab7cdee65652ee695bdff894ea73 (patch)
tree85d2e580c12fcde487584a5c6d462c05485d9274 /arch/sh/drivers/pci
parent97e0214044d9f279a3d6286c9f859696ef0b7ebe (diff)
sh: Support type 1 accesses for SH7786 PCI.
This enables support for type 1 config space accesses on the SH7786 PCI controller. At the same time, add in some extra sanity checks for controller asserted errors. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci')
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 48f594b9582b..57134a38686a 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic SH7786 PCI-Express operations. 2 * Generic SH7786 PCI-Express operations.
3 * 3 *
4 * Copyright (C) 2009 Paul Mundt 4 * Copyright (C) 2009 - 2010 Paul Mundt
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License v2. See the file "COPYING" in the main directory of this archive 7 * License v2. See the file "COPYING" in the main directory of this archive
@@ -35,22 +35,34 @@ static int sh7786_pcie_config_access(unsigned char access_type,
35 if (devfn) 35 if (devfn)
36 return PCIBIOS_DEVICE_NOT_FOUND; 36 return PCIBIOS_DEVICE_NOT_FOUND;
37 37
38 /* Clear errors */
39 pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR);
40
38 /* Set the PIO address */ 41 /* Set the PIO address */
39 pci_write_reg(chan, (bus->number << 24) | (dev << 19) | 42 pci_write_reg(chan, (bus->number << 24) | (dev << 19) |
40 (func << 16) | (where & ~3), SH4A_PCIEPAR); 43 (func << 16) | (where & ~3), SH4A_PCIEPAR);
41 44
42 /* Enable the configuration access */ 45 /* Enable the configuration access */
43 pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR); 46 if (bus->number) {
47 /* Type 1 */
48 pci_write_reg(chan, (1 << 31) | (1 << 8), SH4A_PCIEPCTLR);
49 } else {
50 /* Type 0 */
51 pci_write_reg(chan, (1 << 31), SH4A_PCIEPCTLR);
52 }
53
54 /* Check for errors */
55 if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10)
56 return PCIBIOS_DEVICE_NOT_FOUND;
57 /* Check for master and target aborts */
58 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
59 return PCIBIOS_DEVICE_NOT_FOUND;
44 60
45 if (access_type == PCI_ACCESS_READ) 61 if (access_type == PCI_ACCESS_READ)
46 *data = pci_read_reg(chan, SH4A_PCIEPDR); 62 *data = pci_read_reg(chan, SH4A_PCIEPDR);
47 else 63 else
48 pci_write_reg(chan, *data, SH4A_PCIEPDR); 64 pci_write_reg(chan, *data, SH4A_PCIEPDR);
49 65
50 /* Check for master and target aborts */
51 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
52 return PCIBIOS_DEVICE_NOT_FOUND;
53
54 return PCIBIOS_SUCCESSFUL; 66 return PCIBIOS_SUCCESSFUL;
55} 67}
56 68
@@ -69,8 +81,10 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
69 spin_lock_irqsave(&sh7786_pcie_lock, flags); 81 spin_lock_irqsave(&sh7786_pcie_lock, flags);
70 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, 82 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
71 devfn, where, &data); 83 devfn, where, &data);
72 if (ret != PCIBIOS_SUCCESSFUL) 84 if (ret != PCIBIOS_SUCCESSFUL) {
85 *val = 0xffffffff;
73 goto out; 86 goto out;
87 }
74 88
75 if (size == 1) 89 if (size == 1)
76 *val = (data >> ((where & 3) << 3)) & 0xff; 90 *val = (data >> ((where & 3) << 3)) & 0xff;