/*
* Support PCI/PCIe on PowerNV platforms
*
* Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#undef DEBUG
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/msi.h>
#include <asm/sections.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/opal.h>
#include <asm/iommu.h>
#include <asm/tce.h>
#include <asm/abs_addr.h>
#include "powernv.h"
#include "pci.h"
struct resource_wrap {
struct list_head link;
resource_size_t size;
resource_size_t align;
struct pci_dev *dev; /* Set if it's a device */
struct pci_bus *bus; /* Set if it's a bridge */
};
static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe,
struct va_format *vaf)
{
char pfix[32];
if (pe->pdev)
strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix));
else
sprintf(pfix, "%04x:%02x ",
pci_domain_nr(pe->pbus), pe->pbus->number);
return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf);
}
#define define_pe_printk_level(func, kern_level) \
static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \
{ \
struct va_format vaf; \
va_list args; \
int r; \
\
va_start(args, fmt); \
\
vaf.fmt = fmt; \
vaf.va = &args; \
\
r = __pe_printk(kern_level, pe, &vaf); \
va_end(args); \
\
return r; \
} \
define_pe_printk_level(pe_err, KERN_ERR);
define_pe_printk_level(pe_warn, KERN_WARNING);
define_pe_printk_level(pe_info, KERN_INFO);
/* Calculate resource usage & alignment requirement of a single
* device. This will also assign all resources within the device
* for a given type starting at 0 for the biggest one and then
* assigning in decreasing order of size.
*/
static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags,
resource_size_t *size,
resource_size_t *align)
{
resource_size_t start;
struct resource *r;
int i;