summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-09-20 18:56:13 +0900
committerPaul Mundt <lethal@linux-sh.org>2010-09-20 18:56:13 +0900
commit39a90865f07f05343c450e91a56578bb8f69c5e8 (patch)
tree1d7b5d8f092af89c65ab5d4fc81cca62765e7917
parentc524ebf5a6b78d25219d64a05b3876cde719b5ff (diff)
downloadlinux-39a90865f07f05343c450e91a56578bb8f69c5e8.tar.gz
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>
-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 0b81999fb88b..b6234203e0ac 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -9,6 +9,7 @@
  */
 #include <linux/pci.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 #include <asm/addrspace.h>
 #include "pci-sh4.h"
 
@@ -18,8 +19,6 @@
 #define CONFIG_CMD(bus, devfn, where) \
 	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
 
-static DEFINE_SPINLOCK(sh4_pci_lock);
-
 /*
  * Functions for accessing PCI configuration space with type 1 accesses
  */
@@ -34,10 +33,10 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
 	 * PCIPDR may only be accessed as 32 bit words,
 	 * so we must do byte alignment by hand
 	 */
-	spin_lock_irqsave(&sh4_pci_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
 	data = pci_read_reg(chan, SH4_PCIPDR);
-	spin_unlock_irqrestore(&sh4_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
 	switch (size) {
 	case 1:
@@ -69,10 +68,10 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
 	int shift;
 	u32 data;
 
-	spin_lock_irqsave(&sh4_pci_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
 	data = pci_read_reg(chan, SH4_PCIPDR);
-	spin_unlock_irqrestore(&sh4_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
 	switch (size) {
 	case 1:
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 01cb70fbd803..128421009e3f 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -19,8 +19,6 @@ enum {
 	PCI_ACCESS_WRITE,
 };
 
-static DEFINE_SPINLOCK(sh7786_pcie_lock);
-
 static int sh7786_pcie_config_access(unsigned char access_type,
 		struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
 {
@@ -103,7 +101,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
 	else if ((size == 4) && (where & 3))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	spin_lock_irqsave(&sh7786_pcie_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
 					devfn, where, &data);
 	if (ret != PCIBIOS_SUCCESSFUL) {
@@ -123,7 +121,7 @@ static int sh7786_pcie_read(struct pci_bus *bus, unsigned int devfn,
 		devfn, where, size, (unsigned long)*val);
 
 out:
-	spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	return ret;
 }
 
@@ -139,7 +137,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
 	else if ((size == 4) && (where & 3))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	spin_lock_irqsave(&sh7786_pcie_lock, flags);
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
 	ret = sh7786_pcie_config_access(PCI_ACCESS_READ, bus,
 					devfn, where, &data);
 	if (ret != PCIBIOS_SUCCESSFUL)
@@ -163,7 +161,7 @@ static int sh7786_pcie_write(struct pci_bus *bus, unsigned int devfn,
 	ret = sh7786_pcie_config_access(PCI_ACCESS_WRITE, bus,
 					devfn, where, &data);
 out:
-	spin_unlock_irqrestore(&sh7786_pcie_lock, flags);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 	return ret;
 }
 
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index e4c988d46ad5..af4191bbb179 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 
 unsigned long PCIBIOS_MIN_IO = 0x0000;
 unsigned long PCIBIOS_MIN_MEM = 0;
@@ -56,6 +57,11 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
 	}
 }
 
+/*
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
+ */
+DEFINE_RAW_SPINLOCK(pci_config_lock);
 static DEFINE_MUTEX(pci_scan_mutex);
 
 int __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 8bd952fcf3ba..f0efe97f1750 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -37,6 +37,8 @@ struct pci_channel {
 };
 
 /* arch/sh/drivers/pci/pci.c */
+extern raw_spinlock_t pci_config_lock;
+
 extern int register_pci_controller(struct pci_channel *hose);
 extern void pcibios_report_status(unsigned int status_mask, int warn);