diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-08-20 02:59:40 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-08-20 02:59:40 -0400 |
commit | 7656e2486cb1ab7cdee65652ee695bdff894ea73 (patch) | |
tree | 85d2e580c12fcde487584a5c6d462c05485d9274 /arch/sh/drivers/pci | |
parent | 97e0214044d9f279a3d6286c9f859696ef0b7ebe (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.c | 28 |
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; |