1cd248341SJan Glauber /* 2cd248341SJan Glauber * Copyright IBM Corp. 2012 3cd248341SJan Glauber * 4cd248341SJan Glauber * Author(s): 5cd248341SJan Glauber * Jan Glauber <jang@linux.vnet.ibm.com> 6cd248341SJan Glauber * 7cd248341SJan Glauber * The System z PCI code is a rewrite from a prototype by 8cd248341SJan Glauber * the following people (Kudoz!): 9cd248341SJan Glauber * Alexander Schmidt <alexschm@de.ibm.com> 10cd248341SJan Glauber * Christoph Raisch <raisch@de.ibm.com> 11cd248341SJan Glauber * Hannes Hering <hering2@de.ibm.com> 12cd248341SJan Glauber * Hoang-Nam Nguyen <hnguyen@de.ibm.com> 13cd248341SJan Glauber * Jan-Bernd Themann <themann@de.ibm.com> 14cd248341SJan Glauber * Stefan Roscher <stefan.roscher@de.ibm.com> 15cd248341SJan Glauber * Thomas Klein <tklein@de.ibm.com> 16cd248341SJan Glauber */ 17cd248341SJan Glauber 18cd248341SJan Glauber #define COMPONENT "zPCI" 19cd248341SJan Glauber #define pr_fmt(fmt) COMPONENT ": " fmt 20cd248341SJan Glauber 21cd248341SJan Glauber #include <linux/kernel.h> 22cd248341SJan Glauber #include <linux/slab.h> 23cd248341SJan Glauber #include <linux/err.h> 24cd248341SJan Glauber #include <linux/export.h> 25cd248341SJan Glauber #include <linux/delay.h> 26cd248341SJan Glauber #include <linux/seq_file.h> 27cd248341SJan Glauber #include <linux/pci.h> 28cd248341SJan Glauber #include <linux/msi.h> 29cd248341SJan Glauber 30cd248341SJan Glauber #include <asm/facility.h> 31cd248341SJan Glauber #include <asm/pci_insn.h> 32*a755a45dSJan Glauber #include <asm/pci_clp.h> 33cd248341SJan Glauber 34cd248341SJan Glauber #define DEBUG /* enable pr_debug */ 35cd248341SJan Glauber 36cd248341SJan Glauber #define ZPCI_NR_DMA_SPACES 1 37cd248341SJan Glauber #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS 38cd248341SJan Glauber 39cd248341SJan Glauber /* list of all detected zpci devices */ 40cd248341SJan Glauber LIST_HEAD(zpci_list); 41cd248341SJan Glauber DEFINE_MUTEX(zpci_list_lock); 42cd248341SJan Glauber 43cd248341SJan Glauber static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); 44cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_domain_lock); 45cd248341SJan Glauber 46cd248341SJan Glauber /* I/O Map */ 47cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_iomap_lock); 48cd248341SJan Glauber static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 49cd248341SJan Glauber struct zpci_iomap_entry *zpci_iomap_start; 50cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_iomap_start); 51cd248341SJan Glauber 52cd248341SJan Glauber struct zpci_dev *get_zdev(struct pci_dev *pdev) 53cd248341SJan Glauber { 54cd248341SJan Glauber return (struct zpci_dev *) pdev->sysdata; 55cd248341SJan Glauber } 56cd248341SJan Glauber 57cd248341SJan Glauber struct zpci_dev *get_zdev_by_fid(u32 fid) 58cd248341SJan Glauber { 59cd248341SJan Glauber struct zpci_dev *tmp, *zdev = NULL; 60cd248341SJan Glauber 61cd248341SJan Glauber mutex_lock(&zpci_list_lock); 62cd248341SJan Glauber list_for_each_entry(tmp, &zpci_list, entry) { 63cd248341SJan Glauber if (tmp->fid == fid) { 64cd248341SJan Glauber zdev = tmp; 65cd248341SJan Glauber break; 66cd248341SJan Glauber } 67cd248341SJan Glauber } 68cd248341SJan Glauber mutex_unlock(&zpci_list_lock); 69cd248341SJan Glauber return zdev; 70cd248341SJan Glauber } 71cd248341SJan Glauber 72cd248341SJan Glauber bool zpci_fid_present(u32 fid) 73cd248341SJan Glauber { 74cd248341SJan Glauber return (get_zdev_by_fid(fid) != NULL) ? true : false; 75cd248341SJan Glauber } 76cd248341SJan Glauber 77cd248341SJan Glauber static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) 78cd248341SJan Glauber { 79cd248341SJan Glauber return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; 80cd248341SJan Glauber } 81cd248341SJan Glauber 82cd248341SJan Glauber int pci_domain_nr(struct pci_bus *bus) 83cd248341SJan Glauber { 84cd248341SJan Glauber return ((struct zpci_dev *) bus->sysdata)->domain; 85cd248341SJan Glauber } 86cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_domain_nr); 87cd248341SJan Glauber 88cd248341SJan Glauber int pci_proc_domain(struct pci_bus *bus) 89cd248341SJan Glauber { 90cd248341SJan Glauber return pci_domain_nr(bus); 91cd248341SJan Glauber } 92cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_proc_domain); 93cd248341SJan Glauber 94cd248341SJan Glauber /* Store PCI function information block */ 95cd248341SJan Glauber static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) 96cd248341SJan Glauber { 97cd248341SJan Glauber struct zpci_fib *fib; 98cd248341SJan Glauber u8 status, cc; 99cd248341SJan Glauber 100cd248341SJan Glauber fib = (void *) get_zeroed_page(GFP_KERNEL); 101cd248341SJan Glauber if (!fib) 102cd248341SJan Glauber return -ENOMEM; 103cd248341SJan Glauber 104cd248341SJan Glauber do { 105cd248341SJan Glauber cc = __stpcifc(zdev->fh, 0, fib, &status); 106cd248341SJan Glauber if (cc == 2) { 107cd248341SJan Glauber msleep(ZPCI_INSN_BUSY_DELAY); 108cd248341SJan Glauber memset(fib, 0, PAGE_SIZE); 109cd248341SJan Glauber } 110cd248341SJan Glauber } while (cc == 2); 111cd248341SJan Glauber 112cd248341SJan Glauber if (cc) 113cd248341SJan Glauber pr_err_once("%s: cc: %u status: %u\n", 114cd248341SJan Glauber __func__, cc, status); 115cd248341SJan Glauber 116cd248341SJan Glauber /* Return PCI function controls */ 117cd248341SJan Glauber *fc = fib->fc; 118cd248341SJan Glauber 119cd248341SJan Glauber free_page((unsigned long) fib); 120cd248341SJan Glauber return (cc) ? -EIO : 0; 121cd248341SJan Glauber } 122cd248341SJan Glauber 123cd248341SJan Glauber #define ZPCI_PCIAS_CFGSPC 15 124cd248341SJan Glauber 125cd248341SJan Glauber static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 126cd248341SJan Glauber { 127cd248341SJan Glauber u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 128cd248341SJan Glauber u64 data; 129cd248341SJan Glauber int rc; 130cd248341SJan Glauber 131cd248341SJan Glauber rc = pcilg_instr(&data, req, offset); 132cd248341SJan Glauber data = data << ((8 - len) * 8); 133cd248341SJan Glauber data = le64_to_cpu(data); 134cd248341SJan Glauber if (!rc) 135cd248341SJan Glauber *val = (u32) data; 136cd248341SJan Glauber else 137cd248341SJan Glauber *val = 0xffffffff; 138cd248341SJan Glauber return rc; 139cd248341SJan Glauber } 140cd248341SJan Glauber 141cd248341SJan Glauber static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) 142cd248341SJan Glauber { 143cd248341SJan Glauber u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 144cd248341SJan Glauber u64 data = val; 145cd248341SJan Glauber int rc; 146cd248341SJan Glauber 147cd248341SJan Glauber data = cpu_to_le64(data); 148cd248341SJan Glauber data = data >> ((8 - len) * 8); 149cd248341SJan Glauber rc = pcistg_instr(data, req, offset); 150cd248341SJan Glauber return rc; 151cd248341SJan Glauber } 152cd248341SJan Glauber 153cd248341SJan Glauber void __devinit pcibios_fixup_bus(struct pci_bus *bus) 154cd248341SJan Glauber { 155cd248341SJan Glauber } 156cd248341SJan Glauber 157cd248341SJan Glauber resource_size_t pcibios_align_resource(void *data, const struct resource *res, 158cd248341SJan Glauber resource_size_t size, 159cd248341SJan Glauber resource_size_t align) 160cd248341SJan Glauber { 161cd248341SJan Glauber return 0; 162cd248341SJan Glauber } 163cd248341SJan Glauber 164cd248341SJan Glauber /* Create a virtual mapping cookie for a PCI BAR */ 165cd248341SJan Glauber void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max) 166cd248341SJan Glauber { 167cd248341SJan Glauber struct zpci_dev *zdev = get_zdev(pdev); 168cd248341SJan Glauber u64 addr; 169cd248341SJan Glauber int idx; 170cd248341SJan Glauber 171cd248341SJan Glauber if ((bar & 7) != bar) 172cd248341SJan Glauber return NULL; 173cd248341SJan Glauber 174cd248341SJan Glauber idx = zdev->bars[bar].map_idx; 175cd248341SJan Glauber spin_lock(&zpci_iomap_lock); 176cd248341SJan Glauber zpci_iomap_start[idx].fh = zdev->fh; 177cd248341SJan Glauber zpci_iomap_start[idx].bar = bar; 178cd248341SJan Glauber spin_unlock(&zpci_iomap_lock); 179cd248341SJan Glauber 180cd248341SJan Glauber addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); 181cd248341SJan Glauber return (void __iomem *) addr; 182cd248341SJan Glauber } 183cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iomap); 184cd248341SJan Glauber 185cd248341SJan Glauber void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) 186cd248341SJan Glauber { 187cd248341SJan Glauber unsigned int idx; 188cd248341SJan Glauber 189cd248341SJan Glauber idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; 190cd248341SJan Glauber spin_lock(&zpci_iomap_lock); 191cd248341SJan Glauber zpci_iomap_start[idx].fh = 0; 192cd248341SJan Glauber zpci_iomap_start[idx].bar = 0; 193cd248341SJan Glauber spin_unlock(&zpci_iomap_lock); 194cd248341SJan Glauber } 195cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iounmap); 196cd248341SJan Glauber 197cd248341SJan Glauber static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, 198cd248341SJan Glauber int size, u32 *val) 199cd248341SJan Glauber { 200cd248341SJan Glauber struct zpci_dev *zdev = get_zdev_by_bus(bus); 201cd248341SJan Glauber 202cd248341SJan Glauber if (!zdev || devfn != ZPCI_DEVFN) 203cd248341SJan Glauber return 0; 204cd248341SJan Glauber return zpci_cfg_load(zdev, where, val, size); 205cd248341SJan Glauber } 206cd248341SJan Glauber 207cd248341SJan Glauber static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, 208cd248341SJan Glauber int size, u32 val) 209cd248341SJan Glauber { 210cd248341SJan Glauber struct zpci_dev *zdev = get_zdev_by_bus(bus); 211cd248341SJan Glauber 212cd248341SJan Glauber if (!zdev || devfn != ZPCI_DEVFN) 213cd248341SJan Glauber return 0; 214cd248341SJan Glauber return zpci_cfg_store(zdev, where, val, size); 215cd248341SJan Glauber } 216cd248341SJan Glauber 217cd248341SJan Glauber static struct pci_ops pci_root_ops = { 218cd248341SJan Glauber .read = pci_read, 219cd248341SJan Glauber .write = pci_write, 220cd248341SJan Glauber }; 221cd248341SJan Glauber 222cd248341SJan Glauber static void zpci_map_resources(struct zpci_dev *zdev) 223cd248341SJan Glauber { 224cd248341SJan Glauber struct pci_dev *pdev = zdev->pdev; 225cd248341SJan Glauber resource_size_t len; 226cd248341SJan Glauber int i; 227cd248341SJan Glauber 228cd248341SJan Glauber for (i = 0; i < PCI_BAR_COUNT; i++) { 229cd248341SJan Glauber len = pci_resource_len(pdev, i); 230cd248341SJan Glauber if (!len) 231cd248341SJan Glauber continue; 232cd248341SJan Glauber pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); 233cd248341SJan Glauber pdev->resource[i].end = pdev->resource[i].start + len - 1; 234cd248341SJan Glauber pr_debug("BAR%i: -> start: %Lx end: %Lx\n", 235cd248341SJan Glauber i, pdev->resource[i].start, pdev->resource[i].end); 236cd248341SJan Glauber } 237cd248341SJan Glauber }; 238cd248341SJan Glauber 239cd248341SJan Glauber static void zpci_unmap_resources(struct pci_dev *pdev) 240cd248341SJan Glauber { 241cd248341SJan Glauber resource_size_t len; 242cd248341SJan Glauber int i; 243cd248341SJan Glauber 244cd248341SJan Glauber for (i = 0; i < PCI_BAR_COUNT; i++) { 245cd248341SJan Glauber len = pci_resource_len(pdev, i); 246cd248341SJan Glauber if (!len) 247cd248341SJan Glauber continue; 248cd248341SJan Glauber pci_iounmap(pdev, (void *) pdev->resource[i].start); 249cd248341SJan Glauber } 250cd248341SJan Glauber }; 251cd248341SJan Glauber 252cd248341SJan Glauber struct zpci_dev *zpci_alloc_device(void) 253cd248341SJan Glauber { 254cd248341SJan Glauber struct zpci_dev *zdev; 255cd248341SJan Glauber 256cd248341SJan Glauber /* Alloc memory for our private pci device data */ 257cd248341SJan Glauber zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); 258cd248341SJan Glauber if (!zdev) 259cd248341SJan Glauber return ERR_PTR(-ENOMEM); 260cd248341SJan Glauber return zdev; 261cd248341SJan Glauber } 262cd248341SJan Glauber 263cd248341SJan Glauber void zpci_free_device(struct zpci_dev *zdev) 264cd248341SJan Glauber { 265cd248341SJan Glauber kfree(zdev); 266cd248341SJan Glauber } 267cd248341SJan Glauber 268cd248341SJan Glauber /* Called on removal of pci_dev, leaves zpci and bus device */ 269cd248341SJan Glauber static void zpci_remove_device(struct pci_dev *pdev) 270cd248341SJan Glauber { 271cd248341SJan Glauber struct zpci_dev *zdev = get_zdev(pdev); 272cd248341SJan Glauber 273cd248341SJan Glauber dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); 274cd248341SJan Glauber zdev->state = ZPCI_FN_STATE_CONFIGURED; 275cd248341SJan Glauber zpci_unmap_resources(pdev); 276cd248341SJan Glauber list_del(&zdev->entry); /* can be called from init */ 277cd248341SJan Glauber zdev->pdev = NULL; 278cd248341SJan Glauber } 279cd248341SJan Glauber 280cd248341SJan Glauber static void zpci_scan_devices(void) 281cd248341SJan Glauber { 282cd248341SJan Glauber struct zpci_dev *zdev; 283cd248341SJan Glauber 284cd248341SJan Glauber mutex_lock(&zpci_list_lock); 285cd248341SJan Glauber list_for_each_entry(zdev, &zpci_list, entry) 286cd248341SJan Glauber if (zdev->state == ZPCI_FN_STATE_CONFIGURED) 287cd248341SJan Glauber zpci_scan_device(zdev); 288cd248341SJan Glauber mutex_unlock(&zpci_list_lock); 289cd248341SJan Glauber } 290cd248341SJan Glauber 291cd248341SJan Glauber /* 292cd248341SJan Glauber * Too late for any s390 specific setup, since interrupts must be set up 293cd248341SJan Glauber * already which requires DMA setup too and the pci scan will access the 294cd248341SJan Glauber * config space, which only works if the function handle is enabled. 295cd248341SJan Glauber */ 296cd248341SJan Glauber int pcibios_enable_device(struct pci_dev *pdev, int mask) 297cd248341SJan Glauber { 298cd248341SJan Glauber struct resource *res; 299cd248341SJan Glauber u16 cmd; 300cd248341SJan Glauber int i; 301cd248341SJan Glauber 302cd248341SJan Glauber pci_read_config_word(pdev, PCI_COMMAND, &cmd); 303cd248341SJan Glauber 304cd248341SJan Glauber for (i = 0; i < PCI_BAR_COUNT; i++) { 305cd248341SJan Glauber res = &pdev->resource[i]; 306cd248341SJan Glauber 307cd248341SJan Glauber if (res->flags & IORESOURCE_IO) 308cd248341SJan Glauber return -EINVAL; 309cd248341SJan Glauber 310cd248341SJan Glauber if (res->flags & IORESOURCE_MEM) 311cd248341SJan Glauber cmd |= PCI_COMMAND_MEMORY; 312cd248341SJan Glauber } 313cd248341SJan Glauber pci_write_config_word(pdev, PCI_COMMAND, cmd); 314cd248341SJan Glauber return 0; 315cd248341SJan Glauber } 316cd248341SJan Glauber 317cd248341SJan Glauber void pcibios_disable_device(struct pci_dev *pdev) 318cd248341SJan Glauber { 319cd248341SJan Glauber zpci_remove_device(pdev); 320cd248341SJan Glauber pdev->sysdata = NULL; 321cd248341SJan Glauber } 322cd248341SJan Glauber 323cd248341SJan Glauber static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 324cd248341SJan Glauber unsigned long flags, int domain) 325cd248341SJan Glauber { 326cd248341SJan Glauber struct resource *r; 327cd248341SJan Glauber char *name; 328cd248341SJan Glauber int rc; 329cd248341SJan Glauber 330cd248341SJan Glauber r = kzalloc(sizeof(*r), GFP_KERNEL); 331cd248341SJan Glauber if (!r) 332cd248341SJan Glauber return ERR_PTR(-ENOMEM); 333cd248341SJan Glauber r->start = start; 334cd248341SJan Glauber r->end = r->start + size - 1; 335cd248341SJan Glauber r->flags = flags; 336cd248341SJan Glauber r->parent = &iomem_resource; 337cd248341SJan Glauber name = kmalloc(18, GFP_KERNEL); 338cd248341SJan Glauber if (!name) { 339cd248341SJan Glauber kfree(r); 340cd248341SJan Glauber return ERR_PTR(-ENOMEM); 341cd248341SJan Glauber } 342cd248341SJan Glauber sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR); 343cd248341SJan Glauber r->name = name; 344cd248341SJan Glauber 345cd248341SJan Glauber rc = request_resource(&iomem_resource, r); 346cd248341SJan Glauber if (rc) 347cd248341SJan Glauber pr_debug("request resource %pR failed\n", r); 348cd248341SJan Glauber return r; 349cd248341SJan Glauber } 350cd248341SJan Glauber 351cd248341SJan Glauber static int zpci_alloc_iomap(struct zpci_dev *zdev) 352cd248341SJan Glauber { 353cd248341SJan Glauber int entry; 354cd248341SJan Glauber 355cd248341SJan Glauber spin_lock(&zpci_iomap_lock); 356cd248341SJan Glauber entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 357cd248341SJan Glauber if (entry == ZPCI_IOMAP_MAX_ENTRIES) { 358cd248341SJan Glauber spin_unlock(&zpci_iomap_lock); 359cd248341SJan Glauber return -ENOSPC; 360cd248341SJan Glauber } 361cd248341SJan Glauber set_bit(entry, zpci_iomap); 362cd248341SJan Glauber spin_unlock(&zpci_iomap_lock); 363cd248341SJan Glauber return entry; 364cd248341SJan Glauber } 365cd248341SJan Glauber 366cd248341SJan Glauber static void zpci_free_iomap(struct zpci_dev *zdev, int entry) 367cd248341SJan Glauber { 368cd248341SJan Glauber spin_lock(&zpci_iomap_lock); 369cd248341SJan Glauber memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); 370cd248341SJan Glauber clear_bit(entry, zpci_iomap); 371cd248341SJan Glauber spin_unlock(&zpci_iomap_lock); 372cd248341SJan Glauber } 373cd248341SJan Glauber 374cd248341SJan Glauber static int zpci_create_device_bus(struct zpci_dev *zdev) 375cd248341SJan Glauber { 376cd248341SJan Glauber struct resource *res; 377cd248341SJan Glauber LIST_HEAD(resources); 378cd248341SJan Glauber int i; 379cd248341SJan Glauber 380cd248341SJan Glauber /* allocate mapping entry for each used bar */ 381cd248341SJan Glauber for (i = 0; i < PCI_BAR_COUNT; i++) { 382cd248341SJan Glauber unsigned long addr, size, flags; 383cd248341SJan Glauber int entry; 384cd248341SJan Glauber 385cd248341SJan Glauber if (!zdev->bars[i].size) 386cd248341SJan Glauber continue; 387cd248341SJan Glauber entry = zpci_alloc_iomap(zdev); 388cd248341SJan Glauber if (entry < 0) 389cd248341SJan Glauber return entry; 390cd248341SJan Glauber zdev->bars[i].map_idx = entry; 391cd248341SJan Glauber 392cd248341SJan Glauber /* only MMIO is supported */ 393cd248341SJan Glauber flags = IORESOURCE_MEM; 394cd248341SJan Glauber if (zdev->bars[i].val & 8) 395cd248341SJan Glauber flags |= IORESOURCE_PREFETCH; 396cd248341SJan Glauber if (zdev->bars[i].val & 4) 397cd248341SJan Glauber flags |= IORESOURCE_MEM_64; 398cd248341SJan Glauber 399cd248341SJan Glauber addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); 400cd248341SJan Glauber 401cd248341SJan Glauber size = 1UL << zdev->bars[i].size; 402cd248341SJan Glauber 403cd248341SJan Glauber res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain); 404cd248341SJan Glauber if (IS_ERR(res)) { 405cd248341SJan Glauber zpci_free_iomap(zdev, entry); 406cd248341SJan Glauber return PTR_ERR(res); 407cd248341SJan Glauber } 408cd248341SJan Glauber pci_add_resource(&resources, res); 409cd248341SJan Glauber } 410cd248341SJan Glauber 411cd248341SJan Glauber zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, 412cd248341SJan Glauber zdev, &resources); 413cd248341SJan Glauber if (!zdev->bus) 414cd248341SJan Glauber return -EIO; 415cd248341SJan Glauber 416cd248341SJan Glauber zdev->bus->max_bus_speed = zdev->max_bus_speed; 417cd248341SJan Glauber return 0; 418cd248341SJan Glauber } 419cd248341SJan Glauber 420cd248341SJan Glauber static int zpci_alloc_domain(struct zpci_dev *zdev) 421cd248341SJan Glauber { 422cd248341SJan Glauber spin_lock(&zpci_domain_lock); 423cd248341SJan Glauber zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); 424cd248341SJan Glauber if (zdev->domain == ZPCI_NR_DEVICES) { 425cd248341SJan Glauber spin_unlock(&zpci_domain_lock); 426cd248341SJan Glauber return -ENOSPC; 427cd248341SJan Glauber } 428cd248341SJan Glauber set_bit(zdev->domain, zpci_domain); 429cd248341SJan Glauber spin_unlock(&zpci_domain_lock); 430cd248341SJan Glauber return 0; 431cd248341SJan Glauber } 432cd248341SJan Glauber 433cd248341SJan Glauber static void zpci_free_domain(struct zpci_dev *zdev) 434cd248341SJan Glauber { 435cd248341SJan Glauber spin_lock(&zpci_domain_lock); 436cd248341SJan Glauber clear_bit(zdev->domain, zpci_domain); 437cd248341SJan Glauber spin_unlock(&zpci_domain_lock); 438cd248341SJan Glauber } 439cd248341SJan Glauber 440*a755a45dSJan Glauber int zpci_enable_device(struct zpci_dev *zdev) 441*a755a45dSJan Glauber { 442*a755a45dSJan Glauber int rc; 443*a755a45dSJan Glauber 444*a755a45dSJan Glauber rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES); 445*a755a45dSJan Glauber if (rc) 446*a755a45dSJan Glauber goto out; 447*a755a45dSJan Glauber pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid); 448*a755a45dSJan Glauber return 0; 449*a755a45dSJan Glauber out: 450*a755a45dSJan Glauber return rc; 451*a755a45dSJan Glauber } 452*a755a45dSJan Glauber EXPORT_SYMBOL_GPL(zpci_enable_device); 453*a755a45dSJan Glauber 454cd248341SJan Glauber int zpci_create_device(struct zpci_dev *zdev) 455cd248341SJan Glauber { 456cd248341SJan Glauber int rc; 457cd248341SJan Glauber 458cd248341SJan Glauber rc = zpci_alloc_domain(zdev); 459cd248341SJan Glauber if (rc) 460cd248341SJan Glauber goto out; 461cd248341SJan Glauber 462cd248341SJan Glauber rc = zpci_create_device_bus(zdev); 463cd248341SJan Glauber if (rc) 464cd248341SJan Glauber goto out_bus; 465cd248341SJan Glauber 466cd248341SJan Glauber mutex_lock(&zpci_list_lock); 467cd248341SJan Glauber list_add_tail(&zdev->entry, &zpci_list); 468cd248341SJan Glauber mutex_unlock(&zpci_list_lock); 469cd248341SJan Glauber 470cd248341SJan Glauber if (zdev->state == ZPCI_FN_STATE_STANDBY) 471cd248341SJan Glauber return 0; 472cd248341SJan Glauber 473*a755a45dSJan Glauber rc = zpci_enable_device(zdev); 474*a755a45dSJan Glauber if (rc) 475*a755a45dSJan Glauber goto out_start; 476cd248341SJan Glauber return 0; 477cd248341SJan Glauber 478*a755a45dSJan Glauber out_start: 479*a755a45dSJan Glauber mutex_lock(&zpci_list_lock); 480*a755a45dSJan Glauber list_del(&zdev->entry); 481*a755a45dSJan Glauber mutex_unlock(&zpci_list_lock); 482cd248341SJan Glauber out_bus: 483cd248341SJan Glauber zpci_free_domain(zdev); 484cd248341SJan Glauber out: 485cd248341SJan Glauber return rc; 486cd248341SJan Glauber } 487cd248341SJan Glauber 488cd248341SJan Glauber void zpci_stop_device(struct zpci_dev *zdev) 489cd248341SJan Glauber { 490cd248341SJan Glauber /* 491cd248341SJan Glauber * Note: SCLP disables fh via set-pci-fn so don't 492cd248341SJan Glauber * do that here. 493cd248341SJan Glauber */ 494cd248341SJan Glauber } 495cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_stop_device); 496cd248341SJan Glauber 497cd248341SJan Glauber int zpci_scan_device(struct zpci_dev *zdev) 498cd248341SJan Glauber { 499cd248341SJan Glauber zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN); 500cd248341SJan Glauber if (!zdev->pdev) { 501cd248341SJan Glauber pr_err("pci_scan_single_device failed for fid: 0x%x\n", 502cd248341SJan Glauber zdev->fid); 503cd248341SJan Glauber goto out; 504cd248341SJan Glauber } 505cd248341SJan Glauber 506cd248341SJan Glauber zpci_map_resources(zdev); 507cd248341SJan Glauber pci_bus_add_devices(zdev->bus); 508cd248341SJan Glauber 509cd248341SJan Glauber /* now that pdev was added to the bus mark it as used */ 510cd248341SJan Glauber zdev->state = ZPCI_FN_STATE_ONLINE; 511cd248341SJan Glauber return 0; 512cd248341SJan Glauber 513cd248341SJan Glauber out: 514*a755a45dSJan Glauber clp_disable_fh(zdev); 515cd248341SJan Glauber return -EIO; 516cd248341SJan Glauber } 517cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_scan_device); 518cd248341SJan Glauber 519cd248341SJan Glauber static inline int barsize(u8 size) 520cd248341SJan Glauber { 521cd248341SJan Glauber return (size) ? (1 << size) >> 10 : 0; 522cd248341SJan Glauber } 523cd248341SJan Glauber 524cd248341SJan Glauber static int zpci_mem_init(void) 525cd248341SJan Glauber { 526cd248341SJan Glauber /* TODO: use realloc */ 527cd248341SJan Glauber zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 528cd248341SJan Glauber GFP_KERNEL); 529cd248341SJan Glauber if (!zpci_iomap_start) 530cd248341SJan Glauber goto error_zdev; 531cd248341SJan Glauber return 0; 532cd248341SJan Glauber 533cd248341SJan Glauber error_zdev: 534cd248341SJan Glauber return -ENOMEM; 535cd248341SJan Glauber } 536cd248341SJan Glauber 537cd248341SJan Glauber static void zpci_mem_exit(void) 538cd248341SJan Glauber { 539cd248341SJan Glauber kfree(zpci_iomap_start); 540cd248341SJan Glauber } 541cd248341SJan Glauber 542cd248341SJan Glauber unsigned int pci_probe = 1; 543cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_probe); 544cd248341SJan Glauber 545cd248341SJan Glauber char * __init pcibios_setup(char *str) 546cd248341SJan Glauber { 547cd248341SJan Glauber if (!strcmp(str, "off")) { 548cd248341SJan Glauber pci_probe = 0; 549cd248341SJan Glauber return NULL; 550cd248341SJan Glauber } 551cd248341SJan Glauber return str; 552cd248341SJan Glauber } 553cd248341SJan Glauber 554cd248341SJan Glauber static int __init pci_base_init(void) 555cd248341SJan Glauber { 556cd248341SJan Glauber int rc; 557cd248341SJan Glauber 558cd248341SJan Glauber if (!pci_probe) 559cd248341SJan Glauber return 0; 560cd248341SJan Glauber 561cd248341SJan Glauber if (!test_facility(2) || !test_facility(69) 562cd248341SJan Glauber || !test_facility(71) || !test_facility(72)) 563cd248341SJan Glauber return 0; 564cd248341SJan Glauber 565cd248341SJan Glauber pr_info("Probing PCI hardware: PCI:%d SID:%d AEN:%d\n", 566cd248341SJan Glauber test_facility(69), test_facility(70), 567cd248341SJan Glauber test_facility(71)); 568cd248341SJan Glauber 569cd248341SJan Glauber rc = zpci_mem_init(); 570cd248341SJan Glauber if (rc) 571cd248341SJan Glauber goto out_mem; 572cd248341SJan Glauber 573*a755a45dSJan Glauber rc = clp_find_pci_devices(); 574*a755a45dSJan Glauber if (rc) 575*a755a45dSJan Glauber goto out_find; 576*a755a45dSJan Glauber 577cd248341SJan Glauber zpci_scan_devices(); 578cd248341SJan Glauber return 0; 579cd248341SJan Glauber 580*a755a45dSJan Glauber out_find: 581cd248341SJan Glauber zpci_mem_exit(); 582cd248341SJan Glauber out_mem: 583cd248341SJan Glauber return rc; 584cd248341SJan Glauber } 585cd248341SJan Glauber subsys_initcall(pci_base_init); 586