aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-09-20 05:56:13 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-09-20 05:56:13 -0400
commit39a90865f07f05343c450e91a56578bb8f69c5e8 (patch)
tree1d7b5d8f092af89c65ab5d4fc81cca62765e7917 /arch/sh
parentc524ebf5a6b78d25219d64a05b3876cde719b5ff (diff)
sh: pci: Use a generic raw spinlock for PCI config access locking.
This copies the pci_config_lock idea from x86 over, allowing us to kill off a couple of existing private locks. At the same time, these need to be converted to raw spinlocks for -rt kernels, so we make that change at the same time. This should make it easier for future parts to get the locking right instead of inevitable ending up with lock type mismatches. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c11
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c10
-rw-r--r--arch/sh/drivers/pci/pci.c6
-rw-r--r--arch/sh/include/asm/pci.h2
4 files changed, 17 insertions, 12 deletions
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 0b81999fb88..b6234203e0a 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/spinlock.h>
12#include <asm/addrspace.h> 13#include <asm/addrspace.h>
13#include "pci-sh4.h" 14#include "pci-sh4.h"
14 15
@@ -18,8 +19,6 @@
18#define CONFIG_CMD(bus, devfn, where) \ 19#define CONFIG_CMD(bus, devfn, where) \
19 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) 20 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
20 21
21static DEFINE_SPINLOCK(sh4_pci_lock);
22
23/* 22/*
24 * Functions for accessing PCI configuration space with type 1 accesses 23 * Functions for accessing PCI configuration space with type 1 accesses
25 */ 24 */
@@ -34,10 +33,10 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
34 * PCIPDR may only be accessed as 32 bit words, 33 * PCIPDR may only be accessed as 32 bit words,
35 * so we must do byte alignment by hand 34 * so we must do byte alignment by hand
36 */ 35 */
37 spin_lock_irqsave(&sh4_pci_lock, flags); 36 raw_spin_lock_irqsave(&pci_config_lock, flags);
38 pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); 37 pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
39 data = pci_read_reg(chan, SH4_PCIPDR); 38 data = pci_read_reg(chan, SH4_PCIPDR);
40 spin_unlock_irqrestore(&sh4_pci_lock, flags); 39 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
41 40
42 switch (size) { 41 switch (size) {
43 case 1: 42 case 1:
@@ -69,10 +68,10 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
69 int shift; 68 int shift;
70 u32 data; 69 u32 data;
71 70
72 spin_lock_irqsave(&sh4_pci_lock, flags); 71 raw_spin_lock_irqsave(&pci_config_lock, flags);
73 pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); 72 pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
74 data = pci_read_reg(chan, SH4_PCIPDR); 73 data = pci_read_reg(chan, SH4_PCIPDR);
75 spin_unlock_irqrestore(&sh4_pci_lock, flags); 74 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
76 75
77 switch (size) { 76 switch (size) {
78 case 1: 77 case 1:
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 01cb70fbd80..128421009e3 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -19,8 +19,6 @@ enum {
19 PCI_ACCESS_WRITE, 19 PCI_ACCESS_WRITE,
20}; 20};
21 21
22static DEFINE_SPINLOCK(sh7786_pcie_lock);
23
24static int sh7786_pcie_config_access(unsigned char access_type, 22static int sh7786_pcie_config_access(unsigned char access_type,
25 struct pci_bus *bus, unsigned int devfn, int where, u32 *data) 23 struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
26{ 24{
@@ -103,7 +101,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
103 else if ((size == 4) && (where & 3)) 101 else if ((size == 4) && (where & 3))
104 return PCIBIOS_BAD_REGISTER_NUMBER; 102 return PCIBIOS_BAD_REGISTER_NUMBER;
105 103
106 spin_lock_irqsave(&sh7786_pcie_lock, flags); 104 raw_spin_lock_irqsave(&pci_config_lock, flags);
107 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, 105 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
108 devfn, where, &data); 106 devfn, where, &data);
109 if (ret != PCIBIOS_SUCCESSFUL) { 107 if (ret != PCIBIOS_SUCCESSFUL) {
@@ -123,7 +121,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
123 devfn, where, size, (unsigned long)*val); 121 devfn, where, size, (unsigned long)*val);
124 122
125out: 123out:
126 spin_unlock_irqrestore(&sh7786_pcie_lock, flags); 124 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
127 return ret; 125 return ret;
128} 126}
129 127
@@ -139,7 +137,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
139 else if ((size == 4) && (where & 3)) 137 else if ((size == 4) && (where & 3))
140 return PCIBIOS_BAD_REGISTER_NUMBER; 138 return PCIBIOS_BAD_REGISTER_NUMBER;
141 139
142 spin_lock_irqsave(&sh7786_pcie_lock, flags); 140 raw_spin_lock_irqsave(&pci_config_lock, flags);
143 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus, 141 ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
144 devfn, where, &data); 142 devfn, where, &data);
145 if (ret != PCIBIOS_SUCCESSFUL) 143 if (ret != PCIBIOS_SUCCESSFUL)
@@ -163,7 +161,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
163 ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus, 161 ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus,
164 devfn, where, &data); 162 devfn, where, &data);
165out: 163out:
166 spin_unlock_irqrestore(&sh7786_pcie_lock, flags); 164 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
167 return ret; 165 return ret;
168} 166}
169 167
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index e4c988d46ad..af4191bbb17 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
19#include <linux/dma-debug.h> 19#include <linux/dma-debug.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/spinlock.h>
22 23
23unsigned long PCIBIOS_MIN_IO = 0x0000; 24unsigned long PCIBIOS_MIN_IO = 0x0000;
24unsigned long PCIBIOS_MIN_MEM = 0; 25unsigned long PCIBIOS_MIN_MEM = 0;
@@ -56,6 +57,11 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
56 } 57 }
57} 58}
58 59
60/*
61 * This interrupt-safe spinlock protects all accesses to PCI
62 * configuration space.
63 */
64DEFINE_RAW_SPINLOCK(pci_config_lock);
59static DEFINE_MUTEX(pci_scan_mutex); 65static DEFINE_MUTEX(pci_scan_mutex);
60 66
61int __devinit register_pci_controller(struct pci_channel *hose) 67int __devinit register_pci_controller(struct pci_channel *hose)
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 8bd952fcf3b..f0efe97f175 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -37,6 +37,8 @@ struct pci_channel {
37}; 37};
38 38
39/* arch/sh/drivers/pci/pci.c */ 39/* arch/sh/drivers/pci/pci.c */
40extern raw_spinlock_t pci_config_lock;
41
40extern int register_pci_controller(struct pci_channel *hose); 42extern int register_pci_controller(struct pci_channel *hose);
41extern void pcibios_report_status(unsigned int status_mask, int warn); 43extern void pcibios_report_status(unsigned int status_mask, int warn);
42 44