/*
 * Sonics Silicon Backplane
 * Broadcom PCI-core driver
 *
 * Copyright 2005, Broadcom Corporation
 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
 *
 * Licensed under the GNU/GPL. See COPYING for details.
 */

#include <linux/ssb/ssb.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ssb/ssb_embedded.h>

#include "ssb_private.h"

static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
				u8 address, u16 data);

static inline
u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
{
	return ssb_read32(pc->dev, offset);
}

static inline
void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value)
{
	ssb_write32(pc->dev, offset, value);
}

static inline
u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset)
{
	return ssb_read16(pc->dev, offset);
}

static inline
void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value)
{
	ssb_write16(pc->dev, offset, value);
}

/**************************************************
 * Code for hostmode operation.
 **************************************************/

#ifdef CONFIG_SSB_PCICORE_HOSTMODE

#include <asm/paccess.h>
/* Probe a 32bit value on the bus and catch bus exceptions.
 * Returns nonzero on a bus exception.
 * This is MIPS specific */
#define mips_busprobe32(val, addr)	get_dbe((val), ((u32 *)(addr)))

/* Assume one-hot slot wiring */
#define SSB_PCI_SLOT_MAX	16

/* Global lock is OK, as we won't have more than one extpci anyway. */
static DEFINE_SPINLOCK(cfgspace_lock);
/* Core to access the external PCI config space. Can only have one. */
static struct ssb_pcicore *extpci_core;


static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
			     unsigned int bus, unsigned int dev,
			     unsigned int func, unsigned int off)
{
	u32 addr = 0;
	u32 tmp;

	/* We do only have one cardbus device behind the bridge. */
	if (pc->cardbusmode && (dev >= 1))
		goto out;

	if (bus == 0) {
		/* Type 0 transaction */
		if (unlikely(dev >= SSB_PCI_SLOT_MAX))
			goto out;
		/* Slide the window */
		tmp = SSB_PCICORE_SBTOPCI_CFG0;
		tmp |= ((1 << (dev + 16)) & SSB_PCICORE_SBTOPCI1_MASK);
		pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, tmp);
		/* Calculate the address */
		addr = SSB_PCI_CFG;
		addr |= ((1 << (dev + 16)) & ~SSB_PCICORE_SBTOPCI1_MASK);
		addr |= (func << 8);
		addr |= (off & ~3);
	} else {
		/* Type 1 transaction */
		pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
				SSB_PCICORE_SBTOPCI_CFG1);
		/* Calculate the address */
		addr = SSB_PCI_CFG;
		addr |= (bus << 16);
		addr |= (dev << 11);
		addr |= (func << 8);
		addr |= (off & ~3);
	}
out:
	return addr;
}

static int ssb_extpci_read_config(struct ssb_pcicore *pc,
				  unsigned int bus, unsigned int dev,
				  unsigned int func, unsigned int off,
				  void *buf, int len)
{
	int err = -EINVAL;
	u32 addr, val;
	void __iomem *mmio;

	SSB_WARN_ON(!pc->hostmode);
	if (unlikely(len != 1 && len != 2 && len != 4))
		goto out;
	addr = get_cfgspace_addr(pc, bus, dev, func, off);
	if (unlikely(!addr))
		goto out;
	err = -ENOMEM;
	mmio = ioremap_nocache(addr, len);
	if (!mmio)
		goto out;

	if (mips_busprobe32(val, mmio)) {
		val = 0xffffffff;
		goto unmap;
	}

	val = readl(mmio);
	val >>= (8 * (off & 3));

	switch (len) {
	case 1:
		*((u8 *)buf) = (u8)val;
		break;
	case 2:
		*((u16 *)buf) = (u16)val;
		break;
	case 4:
		*((u32 *)buf) = (u32)val;
		break;
	}
	err = 0;
unmap:
	iounmap(mmio);
out:
	return err;
}

static int ssb_extpci_write_config(struct ssb_pcicore *pc,
				   unsigned int bus, unsigned int dev,
				   unsigned int func, unsigned int off,
				   const void *buf, int len)
{
	int err = -EINVAL;
	u32 addr, val = 0;
	void __iomem *mmio;

	SSB_WARN_ON(!pc->hostmode);
	if (unlikely(len != 1 && len != 2 && len != 4))
		goto out;
	addr = get_cfgspace_addr(pc, bus, dev, func, off);
	if (unlikely(!addr))
		goto out;
	err = -ENOMEM;
	mmio = ioremap_nocache(addr, len);
	if (!mmio)
		goto out;

	if (mips_busprobe32(val, mmio)) {
		val = 0xffffffff;
		goto unmap;
	}

	switch (len) {
	case 1:
		val = readl(mmio);
		val &= ~(0xFF << (8 * (off & 3)));
		val |= *((const u8 *)buf) << (8 * (off & 3));
		break;
	case 2:
		val = readl(mmio);
		val &= ~(0xFFFF << (8 * (off & 3)));
		val |= *((const u16 *)buf) << (8 * (off & 3));
		break;
	case 4:
		val = *((const u32 *)buf);
		break;
	}
	writel(val, mmio);

	err = 0;
unmap:
	iounmap(mmio);
out:
	return err;
}

static int ssb_pcicore_read_config(struct pci_bus *bus, unsigned int devfn,
				   int reg, int size, u32 *val)
{
	unsigned long flags;
	int err;

	spin_lock_irqsave(&cfgspace_lock, flags);
	err = ssb_extpci_read_config(extpci_core, bus->number, PCI_SLOT(devfn),
				     PCI_FUNC(devfn), reg, val, size);
	spin_unlock_irqrestore(&cfgspace_lock, flags);

	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}

static int ssb_pcicore_write_config(struct pci_bus *bus, unsigned int devfn,
				    int reg, int size, u32 val)
{
	unsigned long flags;
	int err;

	spin_lock_irqsave(&cfgspace_lock, flags);
	err = ssb_extpci_write_config(extpci_core, bus->number, PCI_SLOT(devfn),
				      PCI_FUNC(devfn), reg, &val, size);
	spin_unlock_irqrestore(&cfgspace_lock, flags);

	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}

static struct pci_ops ssb_pcicore_pciops = {
	.read	= ssb_pcicore_read_config,
	.write	= ssb_pcicore_write_config,
};

static struct resource ssb_pcicore_mem_resource = {
	.name	= "SSB PCIcore external memory",
	.start	= SSB_PCI_DMA,
	.end	= SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1,
	.flags	= IORESOURCE_MEM | IORESOURCE_PCI_FIXED,
};

static struct resource ssb_pcicore_io_resource = {
	.name	= "SSB PCIcore external I/O",
	.start	= 0x100,
	.end	= 0x7FF,
	.flags	= IORESOURCE_IO | IORESOURCE_PCI_FIXED,
};

static struct pci_controller ssb_pcicore_controller = {
	.pci_ops	= &ssb_pcicore_pciops,
	.io_resource	= &ssb_pcicore_io_resource,
	.mem_resource	= &ssb_pcicore_mem_resource,
};

/* This function is called when doing a pci_enable_device().
 * We must first check if the device is a device on the PCI-core bridge. */
int ssb_pcicore_plat_dev_init(struct pci_dev *d)
{
	if (d->bus->ops != &ssb_pcicore_pciops) {
		/* This is not a device on the PCI-core bridge. */
		return -ENODEV;
	}

	ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
		   pci_name(d));

	/* Fix up interrupt lines */
	d->irq = ssb_mips_irq(extpci_core->dev) + 2;
	pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);

	return 0;
}

/* Early PCI fixup for a device on the PCI-core bridge. */
static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev)
{
	u8 lat;

	if (dev->bus->ops != &ssb_pcicore_pciops) {
		/* This is not a device on the PCI-core bridge. */
		return;
	}
	if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
		return;

	ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev));

	/* Enable PCI bridge bus mastering and memory space */
	pci_set_master(dev);
	if (pcibios_enable_device(dev, ~0) < 0) {
		ssb_printk(KERN_ERR "PCI: SSB bridge enable failed\n");
		return;
	}

	/* Enable PCI bridge BAR1 prefetch and burst */
	pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);

	/* Make sure our latency is high enough to handle the devices behind us */
	lat = 168;
	ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n",
		   pci_name(dev), lat);
	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge);

/* PCI device IRQ mapping. */
int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	if (dev->bus->ops != &ssb_pcicore_pciops) {
		/* This is not a device on the PCI-core bridge. */
		return -ENODEV;
	}
	return ssb_mips_irq(extpci_core->dev) + 2;
}

static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
{
	u32 val;

	if (WARN_ON(extpci_core))
		return;
	extpci_core = pc;

	ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n");
	/* Reset devices on the external PCI bus */
	val = SSB_PCICORE_CTL_RST_OE;
	val |= SSB_PCICORE_CTL_CLK_OE;
	pcicore_write32(pc, SSB_PCICORE_CTL, val);
	val |= SSB_PCICORE_CTL_CLK; /* Clock on */
	pcicore_write32(pc, SSB_PCICORE_CTL, val);
	udelay(150); /* Assertion time demanded by the PCI standard */
	val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */
	pcicore_write32(pc, SSB_PCICORE_CTL, val);
	val = SSB_PCICORE_ARBCTL_INTERN;
	pcicore_write32(pc, SSB_PCICORE_ARBCTL, val);
	udelay(1); /* Assertion time demanded by the PCI standard */

	if (pc->dev->bus->has_cardbus_slot) {
		ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n");
		pc->cardbusmode = 1;
		/* GPIO 1 resets the bridge */
		ssb_gpio_out(pc->dev->bus, 1, 1);
		ssb_gpio_outen(pc->dev->bus, 1, 1);
		pcicore_write16(pc, SSB_PCICORE_SPROM(0),
				pcicore_read16(pc, SSB_PCICORE_SPROM(0))
				| 0x0400);
	}

	/* 64MB I/O window */
	pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
			SSB_PCICORE_SBTOPCI_IO);
	/* 64MB config space */
	pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
			SSB_PCICORE_SBTOPCI_CFG0);
	/* 1GB memory window */
	pcicore_write32(pc, SSB_PCICORE_SBTOPCI2,
			SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA);

	/* Enable PCI bridge BAR0 prefetch and burst */
	val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
	ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2);
	/* Clear error conditions */
	val = 0;
	ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2);

	/* Enable PCI interrupts */
	pcicore_write32(pc, SSB_PCICORE_IMASK,
			SSB_PCICORE_IMASK_INTA);

	/* Ok, ready to run, register it to the system.
	 * The following needs change, if we want to port hostmode
	 * to non-MIPS platform. */
	ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000);
	set_io_port_base(ssb_pcicore_controller.io_map_base);
	/* Give some time to the PCI controller to configure itself with the new
	 * values. Not waiting at this point causes crashes of the machine. */
	mdelay(10);
	register_pci_controller(&ssb_pcicore_controller);
}

static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc)
{
	struct ssb_bus *bus = pc->dev->bus;
	u16 chipid_top;
	u32 tmp;

	chipid_top = (bus->chip_id & 0xFF00);
	if (chipid_top != 0x4700 &&
	    chipid_top != 0x5300)
		return 0;

	if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
		return 0;

	/* The 200-pin BCM4712 package does not bond out PCI. Even when
	 * PCI is bonded out, some boards may leave the pins floating. */
	if (bus->chip_id == 0x4712) {
		if (bus->chip_package == SSB_CHIPPACK_BCM4712S)
			return 0;
		if (bus->chip_package == SSB_CHIPPACK_BCM4712M)
			return 0;
	}
	if (bus->chip_id == 0x5350)
		return 0;

	return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
}
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */

/**************************************************
 * Workarounds.
 **************************************************/

static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
{
	u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
	if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
		tmp &= ~0xF000;
		tmp |= (pc->dev->core_index << 12);
		pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
	}
}

static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
{
	return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
}

static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
{
	const u8 serdes_pll_device = 0x1D;
	const u8 serdes_rx_device = 0x1F;
	u16 tmp;

	ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
			    ssb_pcicore_polarity_workaround(pc));
	tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
	if (tmp & 0x4000)
		ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
}

static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
{
	struct ssb_device *pdev = pc->dev;
	struct ssb_bus *bus = pdev->bus;
	u32 tmp;

	tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
	tmp |= SSB_PCICORE_SBTOPCI_PREF;
	tmp |= SSB_PCICORE_SBTOPCI_BURST;
	pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);

	if (pdev->id.revision < 5) {
		tmp = ssb_read32(pdev, SSB_IMCFGLO);
		tmp &= ~SSB_IMCFGLO_SERTO;
		tmp |= 2;
		tmp &= ~SSB_IMCFGLO_REQTO;
		tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
		ssb_write32(pdev, SSB_IMCFGLO, tmp);
		ssb_commit_settings(bus);
	} else if (pdev->id.revision >= 11) {
		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
		tmp |= SSB_PCICORE_SBTOPCI_MRM;
		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
	}
}

static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
{
	u32 tmp;
	u8 rev = pc->dev->id.revision;

	if (rev == 0 || rev == 1) {
		/* TLP Workaround register. */
		tmp = ssb_pcie_read(pc, 0x4);
		tmp |= 0x8;
		ssb_pcie_write(pc, 0x4, tmp);
	}
	if (rev == 1) {
		/* DLLP Link Control register. */
		tmp = ssb_pcie_read(pc, 0x100);
		tmp |= 0x40;
		ssb_pcie_write(pc, 0x100, tmp);
	}

	if (rev == 0) {
		const u8 serdes_rx_device = 0x1F;

		ssb_pcie_mdio_write(pc, serdes_rx_device,
					2 /* Timer */, 0x8128);
		ssb_pcie_mdio_write(pc, serdes_rx_device,
					6 /* CDR */, 0x0100);
		ssb_pcie_mdio_write(pc, serdes_rx_device,
					7 /* CDR BW */, 0x1466);
	} else if (rev == 3 || rev == 4 || rev == 5) {
		/* TODO: DLLP Power Management Threshold */
		ssb_pcicore_serdes_workaround(pc);
		/* TODO: ASPM */
	} else if (rev == 7) {
		/* TODO: No PLL down */
	}

	if (rev >= 6) {
		/* Miscellaneous Configuration Fixup */
		tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
		if (!(tmp & 0x8000))
			pcicore_write16(pc, SSB_PCICORE_SPROM(5),
					tmp | 0x8000);
	}
}

/**************************************************
 * Generic and Clientmode operation code.
 **************************************************/

static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
{
	ssb_pcicore_fix_sprom_core_index(pc);

	/* Disable PCI interrupts. */
	ssb_write32(pc->dev, SSB_INTVEC, 0);

	/* Additional PCIe always once-executed workarounds */
	if (pc->dev->id.coreid == SSB_DEV_PCIE) {
		ssb_pcicore_serdes_workaround(pc);
		/* TODO: ASPM */
		/* TODO: Clock Request Update */
	}
}

void __devinit ssb_pcicore_init(struct ssb_pcicore *pc)
{
	struct ssb_device *dev = pc->dev;

	if (!dev)
		return;
	if (!ssb_device_is_enabled(dev))
		ssb_device_enable(dev, 0);

#ifdef CONFIG_SSB_PCICORE_HOSTMODE
	pc->hostmode = pcicore_is_in_hostmode(pc);
	if (pc->hostmode)
		ssb_pcicore_init_hostmode(pc);
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
	if (!pc->hostmode)
		ssb_pcicore_init_clientmode(pc);
}

static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
{
	pcicore_write32(pc, 0x130, address);
	return pcicore_read32(pc, 0x134);
}

static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
{
	pcicore_write32(pc, 0x130, address);
	pcicore_write32(pc, 0x134, data);
}

static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
{
	const u16 mdio_control = 0x128;
	const u16 mdio_data = 0x12C;
	u32 v;
	int i;

	v = (1 << 30); /* Start of Transaction */
	v |= (1 << 28); /* Write Transaction */
	v |= (1 << 17); /* Turnaround */
	v |= (0x1F << 18);
	v |= (phy << 4);
	pcicore_write32(pc, mdio_data, v);

	udelay(10);
	for (i = 0; i < 200; i++) {
		v = pcicore_read32(pc, mdio_control);
		if (v & 0x100 /* Trans complete */)
			break;
		msleep(1);
	}
}

static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
{
	const u16 mdio_control = 0x128;
	const u16 mdio_data = 0x12C;
	int max_retries = 10;
	u16 ret = 0;
	u32 v;
	int i;

	v = 0x80; /* Enable Preamble Sequence */
	v |= 0x2; /* MDIO Clock Divisor */
	pcicore_write32(pc, mdio_control, v);

	if (pc->dev->id.revision >= 10) {
		max_retries = 200;
		ssb_pcie_mdio_set_phy(pc, device);
	}

	v = (1 << 30); /* Start of Transaction */
	v |= (1 << 29); /* Read Transaction */
	v |= (1 << 17); /* Turnaround */
	if (pc->dev->id.revision < 10)
		v |= (u32)device << 22;
	v |= (u32)address << 18;
	pcicore_write32(pc, mdio_data, v);
	/* Wait for the device to complete the transaction */
	udelay(10);
	for (i = 0; i < max_retries; i++) {
		v = pcicore_read32(pc, mdio_control);
		if (v & 0x100 /* Trans complete */) {
			udelay(10);
			ret = pcicore_read32(pc, mdio_data);
			break;
		}
		msleep(1);
	}
	pcicore_write32(pc, mdio_control, 0);
	return ret;
}

static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
				u8 address, u16 data)
{
	const u16 mdio_control = 0x128;
	const u16 mdio_data = 0x12C;
	int max_retries = 10;
	u32 v;
	int i;

	v = 0x80; /* Enable Preamble Sequence */
	v |= 0x2; /* MDIO Clock Divisor */
	pcicore_write32(pc, mdio_control, v);

	if (pc->dev->id.revision >= 10) {
		max_retries = 200;
		ssb_pcie_mdio_set_phy(pc, device);
	}

	v = (1 << 30); /* Start of Transaction */
	v |= (1 << 28); /* Write Transaction */
	v |= (1 << 17); /* Turnaround */
	if (pc->dev->id.revision < 10)
		v |= (u32)device << 22;
	v |= (u32)address << 18;
	v |= data;
	pcicore_write32(pc, mdio_data, v);
	/* Wait for the device to complete the transaction */
	udelay(10);
	for (i = 0; i < max_retries; i++) {
		v = pcicore_read32(pc, mdio_control);
		if (v & 0x100 /* Trans complete */)
			break;
		msleep(1);
	}
	pcicore_write32(pc, mdio_control, 0);
}

int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
				   struct ssb_device *dev)
{
	struct ssb_device *pdev = pc->dev;
	struct ssb_bus *bus;
	int err = 0;
	u32 tmp;

	if (dev->bus->bustype != SSB_BUSTYPE_PCI) {
		/* This SSB device is not on a PCI host-bus. So the IRQs are
		 * not routed through the PCI core.
		 * So we must not enable routing through the PCI core. */
		goto out;
	}

	if (!pdev)
		goto out;
	bus = pdev->bus;

	might_sleep_if(pdev->id.coreid != SSB_DEV_PCI);

	/* Enable interrupts for this device. */
	if ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE)) {
		u32 coremask;

		/* Calculate the "coremask" for the device. */
		coremask = (1 << dev->core_index);

		SSB_WARN_ON(bus->bustype != SSB_BUSTYPE_PCI);
		err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
		if (err)
			goto out;
		tmp |= coremask << 8;
		err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp);
		if (err)
			goto out;
	} else {
		u32 intvec;

		intvec = ssb_read32(pdev, SSB_INTVEC);
		tmp = ssb_read32(dev, SSB_TPSFLAG);
		tmp &= SSB_TPSFLAG_BPFLAG;
		intvec |= (1 << tmp);
		ssb_write32(pdev, SSB_INTVEC, intvec);
	}

	/* Setup PCIcore operation. */
	if (pc->setup_done)
		goto out;
	if (pdev->id.coreid == SSB_DEV_PCI) {
		ssb_pcicore_pci_setup_workarounds(pc);
	} else {
		WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
		ssb_pcicore_pcie_setup_workarounds(pc);
	}
	pc->setup_done = 1;
out:
	return err;
}
EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable);
