Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cd59dea authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/config' into next

* pci/config:
  PCI: xilinx: Convert to use generic config accessors
  PCI: xgene: Convert to use generic config accessors
  PCI: tegra: Convert to use generic config accessors
  PCI: rcar: Convert to use generic config accessors
  PCI: generic: Convert to use generic config accessors
  powerpc/powermac: Convert PCI to use generic config accessors
  powerpc/fsl_pci: Convert PCI to use generic config accessors
  ARM: ks8695: Convert PCI to use generic config accessors
  ARM: sa1100: Convert PCI to use generic config accessors
  ARM: integrator: Convert PCI to use generic config accessors
  ARM: cns3xxx: Convert PCI to use generic config accessors
  PCI: Add generic config accessors
  powerpc/PCI: Add struct pci_ops member names to initialization
  mn10300/PCI: Add struct pci_ops member names to initialization
  MIPS: PCI: Add struct pci_ops member names to initialization
  frv/PCI: Add struct pci_ops member names to initialization
parents 341f3a2b 029e2151
Loading
Loading
Loading
Loading
+10 −42
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
	return sysdata_to_cnspci(bus->sysdata);
}

static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
					 unsigned int devfn, int where)
{
	struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
@@ -88,55 +88,22 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
				   int where, int size, u32 *val)
{
	u32 v;
	void __iomem *base;
	int ret;
	u32 mask = (0x1ull << (size * 8)) - 1;
	int shift = (where % 4) * 8;

	base = cns3xxx_pci_cfg_base(bus, devfn, where);
	if (!base) {
		*val = 0xffffffff;
		return PCIBIOS_SUCCESSFUL;
	}

	v = __raw_readl(base);
	ret = pci_generic_config_read32(bus, devfn, where, size, val);

	if (bus->number == 0 && devfn == 0 &&
			(where & 0xffc) == PCI_CLASS_REVISION) {
	if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
	    (where & 0xffc) == PCI_CLASS_REVISION)
		/*
		 * RC's class is 0xb, but Linux PCI driver needs 0x604
		 * for a PCIe bridge. So we must fixup the class code
		 * to 0x604 here.
		 */
		v &= 0xff;
		v |= 0x604 << 16;
	}

	*val = (v >> shift) & mask;

	return PCIBIOS_SUCCESSFUL;
}

static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
				    int where, int size, u32 val)
{
	u32 v;
	void __iomem *base;
	u32 mask = (0x1ull << (size * 8)) - 1;
	int shift = (where % 4) * 8;

	base = cns3xxx_pci_cfg_base(bus, devfn, where);
	if (!base)
		return PCIBIOS_SUCCESSFUL;

	v = __raw_readl(base);

	v &= ~(mask << shift);
	v |= (val & mask) << shift;

	__raw_writel(v, base);
		*val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask;

	return PCIBIOS_SUCCESSFUL;
	return ret;
}

static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
@@ -155,8 +122,9 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
}

static struct pci_ops cns3xxx_pcie_ops = {
	.map_bus = cns3xxx_pci_map_bus,
	.read = cns3xxx_pci_read_config,
	.write = cns3xxx_pci_write_config,
	.write = pci_generic_config_write,
};

static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+5 −57
Original line number Diff line number Diff line
@@ -356,7 +356,6 @@ static u64 pre_mem_pci_sz;
 *	 7:2	register number
 *
 */
static DEFINE_RAW_SPINLOCK(v3_lock);

#undef V3_LB_BASE_PREFETCH
#define V3_LB_BASE_PREFETCH 0
@@ -457,67 +456,21 @@ static void v3_close_config_window(void)
static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
			  int size, u32 *val)
{
	void __iomem *addr;
	unsigned long flags;
	u32 v;

	raw_spin_lock_irqsave(&v3_lock, flags);
	addr = v3_open_config_window(bus, devfn, where);

	switch (size) {
	case 1:
		v = __raw_readb(addr);
		break;

	case 2:
		v = __raw_readw(addr);
		break;

	default:
		v = __raw_readl(addr);
		break;
	}

	int ret = pci_generic_config_read(bus, devfn, where, size, val);
	v3_close_config_window();
	raw_spin_unlock_irqrestore(&v3_lock, flags);

	*val = v;
	return PCIBIOS_SUCCESSFUL;
	return ret;
}

static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
			   int size, u32 val)
{
	void __iomem *addr;
	unsigned long flags;

	raw_spin_lock_irqsave(&v3_lock, flags);
	addr = v3_open_config_window(bus, devfn, where);

	switch (size) {
	case 1:
		__raw_writeb((u8)val, addr);
		__raw_readb(addr);
		break;

	case 2:
		__raw_writew((u16)val, addr);
		__raw_readw(addr);
		break;

	case 4:
		__raw_writel(val, addr);
		__raw_readl(addr);
		break;
	}

	int ret = pci_generic_config_write(bus, devfn, where, size, val);
	v3_close_config_window();
	raw_spin_unlock_irqrestore(&v3_lock, flags);

	return PCIBIOS_SUCCESSFUL;
	return ret;
}

static struct pci_ops pci_v3_ops = {
	.map_bus = v3_open_config_window,
	.read	= v3_read_config,
	.write	= v3_write_config,
};
@@ -658,7 +611,6 @@ static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
 */
static void __init pci_v3_preinit(void)
{
	unsigned long flags;
	unsigned int temp;
	phys_addr_t io_address = pci_pio_to_address(io_mem.start);

@@ -672,8 +624,6 @@ static void __init pci_v3_preinit(void)
	hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
	hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");

	raw_spin_lock_irqsave(&v3_lock, flags);

	/*
	 * Unlock V3 registers, but only if they were previously locked.
	 */
@@ -736,8 +686,6 @@ static void __init pci_v3_preinit(void)
	v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
	v3_writeb(V3_LB_IMASK, 0x28);
	__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);

	raw_spin_unlock_irqrestore(&v3_lock, flags);
}

static void __init pci_v3_postinit(void)
+6 −71
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@


static int pci_dbg;
static int pci_cfg_dbg;


static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
{
@@ -59,75 +57,11 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi
	}
}


/*
 * The KS8695 datasheet prohibits anything other than 32bit accesses
 * to the IO registers, so all our configuration must be done with
 * 32bit operations, and the correct bit masking and shifting.
 */

static int ks8695_pci_readconfig(struct pci_bus *bus,
			unsigned int devfn, int where, int size, u32 *value)
static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
					int where)
{
	ks8695_pci_setupconfig(bus->number, devfn, where);

	*value = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);

	switch (size) {
		case 4:
			break;
		case 2:
			*value = *value >> ((where & 2) * 8);
			*value &= 0xffff;
			break;
		case 1:
			*value = *value >> ((where & 3) * 8);
			*value &= 0xff;
			break;
	}

	if (pci_cfg_dbg) {
		printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
			bus->number, devfn, where, size, *value,
			__raw_readl(KS8695_PCI_VA +  KS8695_PBCD));
	}

	return PCIBIOS_SUCCESSFUL;
}

static int ks8695_pci_writeconfig(struct pci_bus *bus,
			unsigned int devfn, int where, int size, u32 value)
{
	unsigned long tmp;

	if (pci_cfg_dbg) {
		printk("write: %d,%08x,%02x,%d: %08x\n",
			bus->number, devfn, where, size, value);
	}

	ks8695_pci_setupconfig(bus->number, devfn, where);

	switch (size) {
		case 4:
			__raw_writel(value, KS8695_PCI_VA +  KS8695_PBCD);
			break;
		case 2:
			tmp = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);
			tmp &= ~(0xffff << ((where & 2) * 8));
			tmp |= value << ((where & 2) * 8);

			__raw_writel(tmp, KS8695_PCI_VA +  KS8695_PBCD);
			break;
		case 1:
			tmp = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);
			tmp &= ~(0xff << ((where & 3) * 8));
			tmp |= value << ((where & 3) * 8);

			__raw_writel(tmp, KS8695_PCI_VA +  KS8695_PBCD);
			break;
	}

	return PCIBIOS_SUCCESSFUL;
	return KS8695_PCI_VA +  KS8695_PBCD;
}

static void ks8695_local_writeconfig(int where, u32 value)
@@ -137,8 +71,9 @@ static void ks8695_local_writeconfig(int where, u32 value)
}

static struct pci_ops ks8695_pci_ops = {
	.read	= ks8695_pci_readconfig,
	.write	= ks8695_pci_writeconfig,
	.map_bus = ks8695_pci_map_bus,
	.read	= pci_generic_config_read32,
	.write	= pci_generic_config_write32,
};

static struct resource pci_mem = {
+8 −86
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/spinlock.h>

#include <asm/mach/pci.h>
#include <asm/mach-types.h>
@@ -30,97 +29,20 @@
#include <mach/nanoengine.h>
#include <mach/hardware.h>

static DEFINE_SPINLOCK(nano_lock);

static int nanoengine_get_pci_address(struct pci_bus *bus,
	unsigned int devfn, int where, void __iomem **address)
static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
					    unsigned int devfn, int where)
{
	int ret = PCIBIOS_DEVICE_NOT_FOUND;
	unsigned int busnr = bus->number;
	if (bus->number != 0 || (devfn >> 3) != 0)
		return NULL;

	*address = (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
	return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
		((bus->number << 16) | (devfn << 8) | (where & ~3));

	ret = (busnr > 255 || devfn > 255 || where > 255) ?
		PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;

	return ret;
}

static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
	int size, u32 *val)
{
	int ret;
	void __iomem *address;
	unsigned long flags;
	u32 v;

	/* nanoEngine PCI bridge does not return -1 for a non-existing
	 * device. We must fake the answer. We know that the only valid
	 * device is device zero at bus 0, which is the network chip. */
	if (bus->number != 0 || (devfn >> 3) != 0) {
		v = -1;
		nanoengine_get_pci_address(bus, devfn, where, &address);
		goto exit_function;
	}

	spin_lock_irqsave(&nano_lock, flags);

	ret = nanoengine_get_pci_address(bus, devfn, where, &address);
	if (ret != PCIBIOS_SUCCESSFUL)
		return ret;
	v = __raw_readl(address);

	spin_unlock_irqrestore(&nano_lock, flags);

	v >>= ((where & 3) * 8);
	v &= (unsigned long)(-1) >> ((4 - size) * 8);

exit_function:
	*val = v;
	return PCIBIOS_SUCCESSFUL;
}

static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
	int size, u32 val)
{
	int ret;
	void __iomem *address;
	unsigned long flags;
	unsigned shift;
	u32 v;

	shift = (where & 3) * 8;

	spin_lock_irqsave(&nano_lock, flags);

	ret = nanoengine_get_pci_address(bus, devfn, where, &address);
	if (ret != PCIBIOS_SUCCESSFUL)
		return ret;
	v = __raw_readl(address);
	switch (size) {
	case 1:
		v &= ~(0xFF << shift);
		v |= val << shift;
		break;
	case 2:
		v &= ~(0xFFFF << shift);
		v |= val << shift;
		break;
	case 4:
		v = val;
		break;
	}
	__raw_writel(v, address);

	spin_unlock_irqrestore(&nano_lock, flags);

	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops pci_nano_ops = {
	.read	= nanoengine_read_config,
	.write	= nanoengine_write_config,
	.map_bus = nanoengine_pci_map_bus,
	.read	= pci_generic_config_read32,
	.write	= pci_generic_config_write32,
};

static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
+2 −2
Original line number Diff line number Diff line
@@ -168,8 +168,8 @@ static int pci_frv_write_config(struct pci_bus *bus, unsigned int devfn, int whe
}

static struct pci_ops pci_direct_frv = {
	pci_frv_read_config,
	pci_frv_write_config,
	.read = pci_frv_read_config,
	.write = pci_frv_write_config,
};

/*
Loading