From: Paul Mundt Date: Mon, 20 Sep 2010 09:56:13 +0000 (+0900) Subject: sh: pci: Use a generic raw spinlock for PCI config access locking. X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=39a90865f07f05343c450e91a56578bb8f69c5e8;p=linux-beck.git 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 --- 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 #include +#include #include #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 #include #include +#include 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);