Commit 39a90865 authored by Paul Mundt's avatar Paul Mundt
Browse files

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: default avatarPaul Mundt <lethal@linux-sh.org>
parent c524ebf5
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -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:
+4 −6
Original line number Diff line number Diff line
@@ -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;
}

+6 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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);