0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "ssb_private.h"
0012
0013 #include <linux/ssb/ssb.h>
0014 #include <linux/pci.h>
0015 #include <linux/export.h>
0016 #include <linux/delay.h>
0017 #include <linux/ssb/ssb_embedded.h>
0018
0019 static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
0020 static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
0021 static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
0022 static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
0023 u8 address, u16 data);
0024
0025 static inline
0026 u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
0027 {
0028 return ssb_read32(pc->dev, offset);
0029 }
0030
0031 static inline
0032 void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value)
0033 {
0034 ssb_write32(pc->dev, offset, value);
0035 }
0036
0037 static inline
0038 u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset)
0039 {
0040 return ssb_read16(pc->dev, offset);
0041 }
0042
0043 static inline
0044 void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value)
0045 {
0046 ssb_write16(pc->dev, offset, value);
0047 }
0048
0049
0050
0051
0052
0053 #ifdef CONFIG_SSB_PCICORE_HOSTMODE
0054
0055 #include <asm/paccess.h>
0056
0057
0058
0059
0060 #define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
0061
0062
0063 #define SSB_PCI_SLOT_MAX 16
0064
0065
0066 static DEFINE_SPINLOCK(cfgspace_lock);
0067
0068 static struct ssb_pcicore *extpci_core;
0069
0070
0071 static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
0072 unsigned int bus, unsigned int dev,
0073 unsigned int func, unsigned int off)
0074 {
0075 u32 addr = 0;
0076 u32 tmp;
0077
0078
0079 if (pc->cardbusmode && (dev > 1))
0080 goto out;
0081
0082 if (bus == 0) {
0083
0084 if (unlikely(dev >= SSB_PCI_SLOT_MAX))
0085 goto out;
0086
0087 tmp = SSB_PCICORE_SBTOPCI_CFG0;
0088 tmp |= ((1 << (dev + 16)) & SSB_PCICORE_SBTOPCI1_MASK);
0089 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, tmp);
0090
0091 addr = SSB_PCI_CFG;
0092 addr |= ((1 << (dev + 16)) & ~SSB_PCICORE_SBTOPCI1_MASK);
0093 addr |= (func << 8);
0094 addr |= (off & ~3);
0095 } else {
0096
0097 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
0098 SSB_PCICORE_SBTOPCI_CFG1);
0099
0100 addr = SSB_PCI_CFG;
0101 addr |= (bus << 16);
0102 addr |= (dev << 11);
0103 addr |= (func << 8);
0104 addr |= (off & ~3);
0105 }
0106 out:
0107 return addr;
0108 }
0109
0110 static int ssb_extpci_read_config(struct ssb_pcicore *pc,
0111 unsigned int bus, unsigned int dev,
0112 unsigned int func, unsigned int off,
0113 void *buf, int len)
0114 {
0115 int err = -EINVAL;
0116 u32 addr, val;
0117 void __iomem *mmio;
0118
0119 WARN_ON(!pc->hostmode);
0120 if (unlikely(len != 1 && len != 2 && len != 4))
0121 goto out;
0122 addr = get_cfgspace_addr(pc, bus, dev, func, off);
0123 if (unlikely(!addr))
0124 goto out;
0125 err = -ENOMEM;
0126 mmio = ioremap(addr, len);
0127 if (!mmio)
0128 goto out;
0129
0130 if (mips_busprobe32(val, mmio)) {
0131 val = 0xffffffff;
0132 goto unmap;
0133 }
0134
0135 val = readl(mmio);
0136 val >>= (8 * (off & 3));
0137
0138 switch (len) {
0139 case 1:
0140 *((u8 *)buf) = (u8)val;
0141 break;
0142 case 2:
0143 *((u16 *)buf) = (u16)val;
0144 break;
0145 case 4:
0146 *((u32 *)buf) = (u32)val;
0147 break;
0148 }
0149 err = 0;
0150 unmap:
0151 iounmap(mmio);
0152 out:
0153 return err;
0154 }
0155
0156 static int ssb_extpci_write_config(struct ssb_pcicore *pc,
0157 unsigned int bus, unsigned int dev,
0158 unsigned int func, unsigned int off,
0159 const void *buf, int len)
0160 {
0161 int err = -EINVAL;
0162 u32 addr, val = 0;
0163 void __iomem *mmio;
0164
0165 WARN_ON(!pc->hostmode);
0166 if (unlikely(len != 1 && len != 2 && len != 4))
0167 goto out;
0168 addr = get_cfgspace_addr(pc, bus, dev, func, off);
0169 if (unlikely(!addr))
0170 goto out;
0171 err = -ENOMEM;
0172 mmio = ioremap(addr, len);
0173 if (!mmio)
0174 goto out;
0175
0176 if (mips_busprobe32(val, mmio)) {
0177 val = 0xffffffff;
0178 goto unmap;
0179 }
0180
0181 switch (len) {
0182 case 1:
0183 val = readl(mmio);
0184 val &= ~(0xFF << (8 * (off & 3)));
0185 val |= *((const u8 *)buf) << (8 * (off & 3));
0186 break;
0187 case 2:
0188 val = readl(mmio);
0189 val &= ~(0xFFFF << (8 * (off & 3)));
0190 val |= *((const u16 *)buf) << (8 * (off & 3));
0191 break;
0192 case 4:
0193 val = *((const u32 *)buf);
0194 break;
0195 }
0196 writel(val, mmio);
0197
0198 err = 0;
0199 unmap:
0200 iounmap(mmio);
0201 out:
0202 return err;
0203 }
0204
0205 static int ssb_pcicore_read_config(struct pci_bus *bus, unsigned int devfn,
0206 int reg, int size, u32 *val)
0207 {
0208 unsigned long flags;
0209 int err;
0210
0211 spin_lock_irqsave(&cfgspace_lock, flags);
0212 err = ssb_extpci_read_config(extpci_core, bus->number, PCI_SLOT(devfn),
0213 PCI_FUNC(devfn), reg, val, size);
0214 spin_unlock_irqrestore(&cfgspace_lock, flags);
0215
0216 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
0217 }
0218
0219 static int ssb_pcicore_write_config(struct pci_bus *bus, unsigned int devfn,
0220 int reg, int size, u32 val)
0221 {
0222 unsigned long flags;
0223 int err;
0224
0225 spin_lock_irqsave(&cfgspace_lock, flags);
0226 err = ssb_extpci_write_config(extpci_core, bus->number, PCI_SLOT(devfn),
0227 PCI_FUNC(devfn), reg, &val, size);
0228 spin_unlock_irqrestore(&cfgspace_lock, flags);
0229
0230 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
0231 }
0232
0233 static struct pci_ops ssb_pcicore_pciops = {
0234 .read = ssb_pcicore_read_config,
0235 .write = ssb_pcicore_write_config,
0236 };
0237
0238 static struct resource ssb_pcicore_mem_resource = {
0239 .name = "SSB PCIcore external memory",
0240 .start = SSB_PCI_DMA,
0241 .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1,
0242 .flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED,
0243 };
0244
0245 static struct resource ssb_pcicore_io_resource = {
0246 .name = "SSB PCIcore external I/O",
0247 .start = 0x100,
0248 .end = 0x7FF,
0249 .flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED,
0250 };
0251
0252 static struct pci_controller ssb_pcicore_controller = {
0253 .pci_ops = &ssb_pcicore_pciops,
0254 .io_resource = &ssb_pcicore_io_resource,
0255 .mem_resource = &ssb_pcicore_mem_resource,
0256 };
0257
0258
0259
0260
0261 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
0262 {
0263 if (d->bus->ops != &ssb_pcicore_pciops) {
0264
0265 return -ENODEV;
0266 }
0267
0268 dev_info(&d->dev, "PCI: Fixing up device %s\n", pci_name(d));
0269
0270
0271 d->irq = ssb_mips_irq(extpci_core->dev) + 2;
0272 pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
0273
0274 return 0;
0275 }
0276
0277
0278 static void ssb_pcicore_fixup_pcibridge(struct pci_dev *dev)
0279 {
0280 u8 lat;
0281
0282 if (dev->bus->ops != &ssb_pcicore_pciops) {
0283
0284 return;
0285 }
0286 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
0287 return;
0288
0289 dev_info(&dev->dev, "PCI: Fixing up bridge %s\n", pci_name(dev));
0290
0291
0292 pci_set_master(dev);
0293 if (pcibios_enable_device(dev, ~0) < 0) {
0294 dev_err(&dev->dev, "PCI: SSB bridge enable failed\n");
0295 return;
0296 }
0297
0298
0299 pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
0300
0301
0302 lat = 168;
0303 dev_info(&dev->dev,
0304 "PCI: Fixing latency timer of device %s to %u\n",
0305 pci_name(dev), lat);
0306 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
0307 }
0308 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge);
0309
0310
0311 int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
0312 {
0313 if (dev->bus->ops != &ssb_pcicore_pciops) {
0314
0315 return -ENODEV;
0316 }
0317 return ssb_mips_irq(extpci_core->dev) + 2;
0318 }
0319
0320 static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
0321 {
0322 u32 val;
0323
0324 if (WARN_ON(extpci_core))
0325 return;
0326 extpci_core = pc;
0327
0328 dev_dbg(pc->dev->dev, "PCIcore in host mode found\n");
0329
0330 val = SSB_PCICORE_CTL_RST_OE;
0331 val |= SSB_PCICORE_CTL_CLK_OE;
0332 pcicore_write32(pc, SSB_PCICORE_CTL, val);
0333 val |= SSB_PCICORE_CTL_CLK;
0334 pcicore_write32(pc, SSB_PCICORE_CTL, val);
0335 udelay(150);
0336 val |= SSB_PCICORE_CTL_RST;
0337 pcicore_write32(pc, SSB_PCICORE_CTL, val);
0338 val = SSB_PCICORE_ARBCTL_INTERN;
0339 pcicore_write32(pc, SSB_PCICORE_ARBCTL, val);
0340 udelay(1);
0341
0342 if (pc->dev->bus->has_cardbus_slot) {
0343 dev_dbg(pc->dev->dev, "CardBus slot detected\n");
0344 pc->cardbusmode = 1;
0345
0346 ssb_gpio_out(pc->dev->bus, 1, 1);
0347 ssb_gpio_outen(pc->dev->bus, 1, 1);
0348 pcicore_write16(pc, SSB_PCICORE_SPROM(0),
0349 pcicore_read16(pc, SSB_PCICORE_SPROM(0))
0350 | 0x0400);
0351 }
0352
0353
0354 pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
0355 SSB_PCICORE_SBTOPCI_IO);
0356
0357 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
0358 SSB_PCICORE_SBTOPCI_CFG0);
0359
0360 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2,
0361 SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA);
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 usleep_range(1000, 2000);
0372
0373
0374 val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
0375 ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2);
0376
0377 val = 0;
0378 ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2);
0379
0380
0381 pcicore_write32(pc, SSB_PCICORE_IMASK,
0382 SSB_PCICORE_IMASK_INTA);
0383
0384
0385
0386
0387
0388 ssb_pcicore_controller.io_map_base = (unsigned long)ioremap(SSB_PCI_MEM, 0x04000000);
0389 set_io_port_base(ssb_pcicore_controller.io_map_base);
0390
0391
0392
0393 mdelay(10);
0394 register_pci_controller(&ssb_pcicore_controller);
0395 }
0396
0397 static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
0398 {
0399 struct ssb_bus *bus = pc->dev->bus;
0400 u16 chipid_top;
0401 u32 tmp;
0402
0403 chipid_top = (bus->chip_id & 0xFF00);
0404 if (chipid_top != 0x4700 &&
0405 chipid_top != 0x5300)
0406 return 0;
0407
0408 if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
0409 return 0;
0410
0411
0412
0413
0414 if (bus->chip_id == 0x4712) {
0415 if (bus->chip_package == SSB_CHIPPACK_BCM4712S)
0416 return 0;
0417 if (bus->chip_package == SSB_CHIPPACK_BCM4712M)
0418 return 0;
0419 }
0420 if (bus->chip_id == 0x5350)
0421 return 0;
0422
0423 return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
0424 }
0425 #endif
0426
0427
0428
0429
0430
0431 static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
0432 {
0433 u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
0434 if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
0435 tmp &= ~0xF000;
0436 tmp |= (pc->dev->core_index << 12);
0437 pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
0438 }
0439 }
0440
0441 static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
0442 {
0443 return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
0444 }
0445
0446 static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
0447 {
0448 const u8 serdes_pll_device = 0x1D;
0449 const u8 serdes_rx_device = 0x1F;
0450 u16 tmp;
0451
0452 ssb_pcie_mdio_write(pc, serdes_rx_device, 1 ,
0453 ssb_pcicore_polarity_workaround(pc));
0454 tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 );
0455 if (tmp & 0x4000)
0456 ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
0457 }
0458
0459 static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
0460 {
0461 struct ssb_device *pdev = pc->dev;
0462 struct ssb_bus *bus = pdev->bus;
0463 u32 tmp;
0464
0465 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
0466 tmp |= SSB_PCICORE_SBTOPCI_PREF;
0467 tmp |= SSB_PCICORE_SBTOPCI_BURST;
0468 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
0469
0470 if (pdev->id.revision < 5) {
0471 tmp = ssb_read32(pdev, SSB_IMCFGLO);
0472 tmp &= ~SSB_IMCFGLO_SERTO;
0473 tmp |= 2;
0474 tmp &= ~SSB_IMCFGLO_REQTO;
0475 tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
0476 ssb_write32(pdev, SSB_IMCFGLO, tmp);
0477 ssb_commit_settings(bus);
0478 } else if (pdev->id.revision >= 11) {
0479 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
0480 tmp |= SSB_PCICORE_SBTOPCI_MRM;
0481 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
0482 }
0483 }
0484
0485 static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
0486 {
0487 u32 tmp;
0488 u8 rev = pc->dev->id.revision;
0489
0490 if (rev == 0 || rev == 1) {
0491
0492 tmp = ssb_pcie_read(pc, 0x4);
0493 tmp |= 0x8;
0494 ssb_pcie_write(pc, 0x4, tmp);
0495 }
0496 if (rev == 1) {
0497
0498 tmp = ssb_pcie_read(pc, 0x100);
0499 tmp |= 0x40;
0500 ssb_pcie_write(pc, 0x100, tmp);
0501 }
0502
0503 if (rev == 0) {
0504 const u8 serdes_rx_device = 0x1F;
0505
0506 ssb_pcie_mdio_write(pc, serdes_rx_device,
0507 2 , 0x8128);
0508 ssb_pcie_mdio_write(pc, serdes_rx_device,
0509 6 , 0x0100);
0510 ssb_pcie_mdio_write(pc, serdes_rx_device,
0511 7 , 0x1466);
0512 } else if (rev == 3 || rev == 4 || rev == 5) {
0513
0514 ssb_pcicore_serdes_workaround(pc);
0515
0516 } else if (rev == 7) {
0517
0518 }
0519
0520 if (rev >= 6) {
0521
0522 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
0523 if (!(tmp & 0x8000))
0524 pcicore_write16(pc, SSB_PCICORE_SPROM(5),
0525 tmp | 0x8000);
0526 }
0527 }
0528
0529
0530
0531
0532
0533 static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
0534 {
0535 struct ssb_device *pdev = pc->dev;
0536 struct ssb_bus *bus = pdev->bus;
0537
0538 if (bus->bustype == SSB_BUSTYPE_PCI)
0539 ssb_pcicore_fix_sprom_core_index(pc);
0540
0541
0542 ssb_write32(pdev, SSB_INTVEC, 0);
0543
0544
0545 if (pc->dev->id.coreid == SSB_DEV_PCIE) {
0546 ssb_pcicore_serdes_workaround(pc);
0547
0548
0549 }
0550 }
0551
0552 void ssb_pcicore_init(struct ssb_pcicore *pc)
0553 {
0554 struct ssb_device *dev = pc->dev;
0555
0556 if (!dev)
0557 return;
0558 if (!ssb_device_is_enabled(dev))
0559 ssb_device_enable(dev, 0);
0560
0561 #ifdef CONFIG_SSB_PCICORE_HOSTMODE
0562 pc->hostmode = pcicore_is_in_hostmode(pc);
0563 if (pc->hostmode)
0564 ssb_pcicore_init_hostmode(pc);
0565 #endif
0566 if (!pc->hostmode)
0567 ssb_pcicore_init_clientmode(pc);
0568 }
0569
0570 static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
0571 {
0572 pcicore_write32(pc, 0x130, address);
0573 return pcicore_read32(pc, 0x134);
0574 }
0575
0576 static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
0577 {
0578 pcicore_write32(pc, 0x130, address);
0579 pcicore_write32(pc, 0x134, data);
0580 }
0581
0582 static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
0583 {
0584 const u16 mdio_control = 0x128;
0585 const u16 mdio_data = 0x12C;
0586 u32 v;
0587 int i;
0588
0589 v = (1 << 30);
0590 v |= (1 << 28);
0591 v |= (1 << 17);
0592 v |= (0x1F << 18);
0593 v |= (phy << 4);
0594 pcicore_write32(pc, mdio_data, v);
0595
0596 udelay(10);
0597 for (i = 0; i < 200; i++) {
0598 v = pcicore_read32(pc, mdio_control);
0599 if (v & 0x100 )
0600 break;
0601 msleep(1);
0602 }
0603 }
0604
0605 static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
0606 {
0607 const u16 mdio_control = 0x128;
0608 const u16 mdio_data = 0x12C;
0609 int max_retries = 10;
0610 u16 ret = 0;
0611 u32 v;
0612 int i;
0613
0614 v = 0x80;
0615 v |= 0x2;
0616 pcicore_write32(pc, mdio_control, v);
0617
0618 if (pc->dev->id.revision >= 10) {
0619 max_retries = 200;
0620 ssb_pcie_mdio_set_phy(pc, device);
0621 }
0622
0623 v = (1 << 30);
0624 v |= (1 << 29);
0625 v |= (1 << 17);
0626 if (pc->dev->id.revision < 10)
0627 v |= (u32)device << 22;
0628 v |= (u32)address << 18;
0629 pcicore_write32(pc, mdio_data, v);
0630
0631 udelay(10);
0632 for (i = 0; i < max_retries; i++) {
0633 v = pcicore_read32(pc, mdio_control);
0634 if (v & 0x100 ) {
0635 udelay(10);
0636 ret = pcicore_read32(pc, mdio_data);
0637 break;
0638 }
0639 msleep(1);
0640 }
0641 pcicore_write32(pc, mdio_control, 0);
0642 return ret;
0643 }
0644
0645 static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
0646 u8 address, u16 data)
0647 {
0648 const u16 mdio_control = 0x128;
0649 const u16 mdio_data = 0x12C;
0650 int max_retries = 10;
0651 u32 v;
0652 int i;
0653
0654 v = 0x80;
0655 v |= 0x2;
0656 pcicore_write32(pc, mdio_control, v);
0657
0658 if (pc->dev->id.revision >= 10) {
0659 max_retries = 200;
0660 ssb_pcie_mdio_set_phy(pc, device);
0661 }
0662
0663 v = (1 << 30);
0664 v |= (1 << 28);
0665 v |= (1 << 17);
0666 if (pc->dev->id.revision < 10)
0667 v |= (u32)device << 22;
0668 v |= (u32)address << 18;
0669 v |= data;
0670 pcicore_write32(pc, mdio_data, v);
0671
0672 udelay(10);
0673 for (i = 0; i < max_retries; i++) {
0674 v = pcicore_read32(pc, mdio_control);
0675 if (v & 0x100 )
0676 break;
0677 msleep(1);
0678 }
0679 pcicore_write32(pc, mdio_control, 0);
0680 }
0681
0682 int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
0683 struct ssb_device *dev)
0684 {
0685 struct ssb_device *pdev = pc->dev;
0686 struct ssb_bus *bus;
0687 int err = 0;
0688 u32 tmp;
0689
0690 if (dev->bus->bustype != SSB_BUSTYPE_PCI) {
0691
0692
0693
0694
0695 goto out;
0696 }
0697
0698 if (!pdev)
0699 goto out;
0700 bus = pdev->bus;
0701
0702 might_sleep_if(pdev->id.coreid != SSB_DEV_PCI);
0703
0704
0705 if ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE)) {
0706 u32 coremask;
0707
0708
0709 coremask = (1 << dev->core_index);
0710
0711 WARN_ON(bus->bustype != SSB_BUSTYPE_PCI);
0712 err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
0713 if (err)
0714 goto out;
0715 tmp |= coremask << 8;
0716 err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp);
0717 if (err)
0718 goto out;
0719 } else {
0720 u32 intvec;
0721
0722 intvec = ssb_read32(pdev, SSB_INTVEC);
0723 tmp = ssb_read32(dev, SSB_TPSFLAG);
0724 tmp &= SSB_TPSFLAG_BPFLAG;
0725 intvec |= (1 << tmp);
0726 ssb_write32(pdev, SSB_INTVEC, intvec);
0727 }
0728
0729
0730 if (pc->setup_done)
0731 goto out;
0732 if (pdev->id.coreid == SSB_DEV_PCI) {
0733 ssb_pcicore_pci_setup_workarounds(pc);
0734 } else {
0735 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
0736 ssb_pcicore_pcie_setup_workarounds(pc);
0737 }
0738 pc->setup_done = 1;
0739 out:
0740 return err;
0741 }
0742 EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable);