diff options
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ehv_pic.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_msi.c | 4 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 125 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.h | 13 | ||||
-rw-r--r-- | arch/powerpc/sysdev/indirect_pci.c | 10 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 20 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mv64x60_dev.c | 16 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 15 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/rtc_cmos_setup.c | 5 | ||||
-rw-r--r-- | arch/powerpc/sysdev/udbg_memcons.c | 105 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/icp-native.c | 10 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/ics-opal.c | 2 |
15 files changed, 265 insertions, 67 deletions
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a84fecf63c4d..ab4cb5476472 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -19,6 +19,7 @@ config PPC_MSI_BITMAP default y if MPIC default y if FSL_PCI default y if PPC4xx_MSI + default y if POWERNV_MSI source "arch/powerpc/sysdev/xics/Kconfig" diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index b0a518e97599..99464a7bdb3b 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -64,6 +64,8 @@ endif obj-$(CONFIG_PPC_SCOM) += scom.o +obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o + subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PPC_XICS) += xics/ diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 6e0e1005227f..9cd0e60716fe 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -81,7 +81,7 @@ int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest, ev_int_set_config(src, config, prio, cpuid); spin_unlock_irqrestore(&ehv_pic_lock, flags); - return 0; + return IRQ_SET_MASK_OK; } static unsigned int ehv_pic_type_to_vecpri(unsigned int type) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 178c99427b1c..ab02db3d02d8 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -333,6 +333,8 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) return 0; } +static struct lock_class_key fsl_msi_irq_class; + static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, int offset, int irq_index) { @@ -351,7 +353,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, dev_err(&dev->dev, "No memory for MSI cascade data\n"); return -ENOMEM; } - + irq_set_lockdep_class(virt_msir, &fsl_msi_irq_class); msi->msi_virqs[irq_index] = virt_msir; cascade_data->index = offset; cascade_data->msi_data = msi; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 682084dba19b..028ac1f71b51 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -54,16 +54,63 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev) return; } -static int __init fsl_pcie_check_link(struct pci_controller *hose) +static int fsl_indirect_read_config(struct pci_bus *, unsigned int, + int, int, u32 *); + +static int fsl_pcie_check_link(struct pci_controller *hose) { - u32 val; + u32 val = 0; + + if (hose->indirect_type & PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) { + if (hose->ops->read == fsl_indirect_read_config) { + struct pci_bus bus; + bus.number = 0; + bus.sysdata = hose; + bus.ops = hose->ops; + indirect_read_config(&bus, 0, PCIE_LTSSM, 4, &val); + } else + early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); + if (val < PCIE_LTSSM_L0) + return 1; + } else { + struct ccsr_pci __iomem *pci = hose->private_data; + /* for PCIe IP rev 3.0 or greater use CSR0 for link state */ + val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK) + >> PEX_CSR0_LTSSM_SHIFT; + if (val != PEX_CSR0_LTSSM_L0) + return 1; + } - early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); - if (val < PCIE_LTSSM_L0) - return 1; return 0; } +static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + + if (fsl_pcie_check_link(hose)) + hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; + else + hose->indirect_type &= ~PPC_INDIRECT_TYPE_NO_PCIE_LINK; + + return indirect_read_config(bus, devfn, offset, len, val); +} + +static struct pci_ops fsl_indirect_pci_ops = +{ + .read = fsl_indirect_read_config, + .write = indirect_write_config, +}; + +static void __init fsl_setup_indirect_pci(struct pci_controller* hose, + resource_size_t cfg_addr, + resource_size_t cfg_data, u32 flags) +{ + setup_indirect_pci(hose, cfg_addr, cfg_data, flags); + hose->ops = &fsl_indirect_pci_ops; +} + #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) #define MAX_PHYS_ADDR_BITS 40 @@ -106,7 +153,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, flags |= 0x10000000; /* enable relaxed ordering */ for (i = 0; size > 0; i++) { - unsigned int bits = min(__ilog2(size), + unsigned int bits = min(ilog2(size), __ffs(pci_addr | phys_addr)); if (index + i >= 5) @@ -126,13 +173,12 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, } /* atmu setup for fsl pci/pcie controller */ -static void setup_pci_atmu(struct pci_controller *hose, - struct resource *rsrc) +static void setup_pci_atmu(struct pci_controller *hose) { - struct ccsr_pci __iomem *pci; + struct ccsr_pci __iomem *pci = hose->private_data; int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4; u64 mem, sz, paddr_hi = 0; - u64 paddr_lo = ULLONG_MAX; + u64 offset = 0, paddr_lo = ULLONG_MAX; u32 pcicsrbar = 0, pcicsrbar_sz; u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; @@ -140,15 +186,6 @@ static void setup_pci_atmu(struct pci_controller *hose, const u64 *reg; int len; - pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", - (u64)rsrc->start, (u64)resource_size(rsrc)); - - pci = ioremap(rsrc->start, resource_size(rsrc)); - if (!pci) { - dev_err(hose->parent, "Unable to map ATMU registers\n"); - return; - } - if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { win_idx = 2; @@ -171,8 +208,9 @@ static void setup_pci_atmu(struct pci_controller *hose, paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start); paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end); - n = setup_one_atmu(pci, j, &hose->mem_resources[i], - hose->pci_mem_offset); + /* We assume all memory resources have the same offset */ + offset = hose->mem_offset[i]; + n = setup_one_atmu(pci, j, &hose->mem_resources[i], offset); if (n < 0 || j >= 5) { pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i); @@ -196,23 +234,23 @@ static void setup_pci_atmu(struct pci_controller *hose, out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12)); /* Enable, IO R/W */ out_be32(&pci->pow[j].powar, 0x80088000 - | (__ilog2(hose->io_resource.end + | (ilog2(hose->io_resource.end - hose->io_resource.start + 1) - 1)); } } /* convert to pci address space */ - paddr_hi -= hose->pci_mem_offset; - paddr_lo -= hose->pci_mem_offset; + paddr_hi -= offset; + paddr_lo -= offset; if (paddr_hi == paddr_lo) { pr_err("%s: No outbound window space\n", name); - goto out; + return; } if (paddr_lo == 0) { pr_err("%s: No space for inbound window\n", name); - goto out; + return; } /* setup PCSRBAR/PEXCSRBAR */ @@ -261,7 +299,7 @@ static void setup_pci_atmu(struct pci_controller *hose, } sz = min(mem, paddr_lo); - mem_log = __ilog2_u64(sz); + mem_log = ilog2(sz); /* PCIe can overmap inbound & outbound since RX & TX are separated */ if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { @@ -290,7 +328,7 @@ static void setup_pci_atmu(struct pci_controller *hose, * SWIOTLB and access the full range of memory */ if (sz != mem) { - mem_log = __ilog2_u64(mem); + mem_log = ilog2(mem); /* Size window up if we dont fit in exact power-of-2 */ if ((1ull << mem_log) != mem) @@ -327,7 +365,7 @@ static void setup_pci_atmu(struct pci_controller *hose, sz -= 1ull << mem_log; if (sz) { - mem_log = __ilog2_u64(sz); + mem_log = ilog2(sz); piwar |= (mem_log - 1); out_be32(&pci->piw[win_idx].pitar, paddr >> 12); @@ -358,9 +396,6 @@ static void setup_pci_atmu(struct pci_controller *hose, pr_info("%s: DMA window size is 0x%llx\n", name, (u64)hose->dma_window_size); } - -out: - iounmap(pci); } static void __init setup_pci_cmd(struct pci_controller *hose) @@ -429,6 +464,7 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) const int *bus_range; u8 hdr_type, progif; struct device_node *dev; + struct ccsr_pci __iomem *pci; dev = pdev->dev.of_node; @@ -461,8 +497,18 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) hose->first_busno = bus_range ? bus_range[0] : 0x0; hose->last_busno = bus_range ? bus_range[1] : 0xff; - setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, - PPC_INDIRECT_TYPE_BIG_ENDIAN); + pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", + (u64)rsrc.start, (u64)resource_size(&rsrc)); + + pci = hose->private_data = ioremap(rsrc.start, resource_size(&rsrc)); + if (!hose->private_data) + goto no_bridge; + + fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, + PPC_INDIRECT_TYPE_BIG_ENDIAN); + + if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) + hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { /* For PCIE read HEADER_TYPE to identify controler mode */ @@ -500,11 +546,12 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) pci_process_bridge_OF_ranges(hose, dev, is_primary); /* Setup PEX window registers */ - setup_pci_atmu(hose, &rsrc); + setup_pci_atmu(hose); return 0; no_bridge: + iounmap(hose->private_data); /* unmap cfg_data & cfg_addr separately if not on same page */ if (((unsigned long)hose->cfg_data & PAGE_MASK) != ((unsigned long)hose->cfg_addr & PAGE_MASK)) @@ -681,6 +728,7 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose, WARN_ON(hose->dn->data); hose->dn->data = pcie; hose->ops = &mpc83xx_pcie_ops; + hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); @@ -766,8 +814,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) if (ret) goto err0; } else { - setup_indirect_pci(hose, rsrc_cfg.start, - rsrc_cfg.start + 4, 0); + fsl_setup_indirect_pci(hose, rsrc_cfg.start, + rsrc_cfg.start + 4, 0); } printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " @@ -836,6 +884,7 @@ static const struct of_device_id pci_ids[] = { { .compatible = "fsl,qoriq-pcie-v2.2", }, { .compatible = "fsl,qoriq-pcie-v2.3", }, { .compatible = "fsl,qoriq-pcie-v2.4", }, + { .compatible = "fsl,qoriq-pcie-v3.0", }, /* * The following entries are for compatibility with older device @@ -927,7 +976,7 @@ static int fsl_pci_resume(struct device *dev) return -ENODEV; } - setup_pci_atmu(hose, &pci_rsrc); + setup_pci_atmu(hose); return 0; } diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index c495c00c8740..72b5625330e2 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -14,9 +14,12 @@ #ifndef __POWERPC_FSL_PCI_H #define __POWERPC_FSL_PCI_H +struct platform_device; + #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ #define PCIE_LTSSM_L0 0x16 /* L0 state */ #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ +#define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */ #define PIWAR_EN 0x80000000 /* Enable */ #define PIWAR_PF 0x20000000 /* prefetch */ #define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */ @@ -89,6 +92,16 @@ struct ccsr_pci { __be32 pex_err_cap_r1; /* 0x.e2c - PCIE error capture register 0 */ __be32 pex_err_cap_r2; /* 0x.e30 - PCIE error capture register 0 */ __be32 pex_err_cap_r3; /* 0x.e34 - PCIE error capture register 0 */ + u8 res_e38[200]; + __be32 pdb_stat; /* 0x.f00 - PCIE Debug Status */ + u8 res_f04[16]; + __be32 pex_csr0; /* 0x.f14 - PEX Control/Status register 0*/ +#define PEX_CSR0_LTSSM_MASK 0xFC +#define PEX_CSR0_LTSSM_SHIFT 2 +#define PEX_CSR0_LTSSM_L0 0x11 + __be32 pex_csr1; /* 0x.f18 - PEX Control/Status register 1*/ + u8 res_f1c[228]; + }; extern int fsl_add_bridge(struct platform_device *pdev, int is_primary); diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index 82fdad885d20..c6c8b526a4f6 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c @@ -20,9 +20,8 @@ #include <asm/pci-bridge.h> #include <asm/machdep.h> -static int -indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 *val) +int indirect_read_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 *val) { struct pci_controller *hose = pci_bus_to_host(bus); volatile void __iomem *cfg_data; @@ -78,9 +77,8 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, return PCIBIOS_SUCCESSFUL; } -static int -indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 val) +int indirect_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) { struct pci_controller *hose = pci_bus_to_host(bus); volatile void __iomem *cfg_data; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d30e6a676c89..3cc2f9159ab1 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -54,7 +54,7 @@ static DEFINE_RAW_SPINLOCK(mpic_lock); #ifdef CONFIG_PPC32 /* XXX for now */ #ifdef CONFIG_IRQ_ALL_CPUS -#define distribute_irqs (!(mpic->flags & MPIC_SINGLE_DEST_CPU)) +#define distribute_irqs (1) #else #define distribute_irqs (0) #endif @@ -836,7 +836,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, mpic_physmask(mask)); } - return 0; + return IRQ_SET_MASK_OK; } static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) @@ -1001,8 +1001,12 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, if (hw == mpic->spurious_vec) return -EINVAL; - if (mpic->protected && test_bit(hw, mpic->protected)) - return -EINVAL; + if (mpic->protected && test_bit(hw, mpic->protected)) { + pr_warning("mpic: Mapping of source 0x%x failed, " + "source protected by firmware !\n",\ + (unsigned int)hw); + return -EPERM; + } #ifdef CONFIG_SMP else if (hw >= mpic->ipi_vecs[0]) { @@ -1029,8 +1033,12 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, if (mpic_map_error_int(mpic, virq, hw)) return 0; - if (hw >= mpic->num_sources) + if (hw >= mpic->num_sources) { + pr_warning("mpic: Mapping of source 0x%x failed, " + "source out of range !\n",\ + (unsigned int)hw); return -EINVAL; + } mpic_msi_reserve_hwirq(mpic, hw); @@ -1695,7 +1703,7 @@ void mpic_setup_this_cpu(void) * it differently, then we should make sure we also change the default * values of irq_desc[].affinity in irq.c. */ - if (distribute_irqs) { + if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) { for (i = 0; i < mpic->num_sources ; i++) mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 0f6af41ebb44..4a25c26f0bf4 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -214,15 +214,27 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev( struct device_node *np, int id) { struct platform_device *pdev; - struct resource r[1]; + struct resource r[2]; int err; err = of_address_to_resource(np, 0, &r[0]); if (err) return ERR_PTR(err); + /* register an orion mdio bus driver */ + r[1].start = r[0].start + 0x4; + r[1].end = r[0].start + 0x84 - 1; + r[1].flags = IORESOURCE_MEM; + + if (id == 0) { + pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1); + if (!pdev) + return pdev; + } + pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, - r, 1); + &r[0], 1); + return pdev; } diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 56e8b3c3c890..64603a10b863 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -257,6 +257,7 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, /* Setup outbound memory windows */ for (i = j = 0; i < 3; i++) { struct resource *res = &hose->mem_resources[i]; + resource_size_t offset = hose->mem_offset[i]; /* we only care about memory windows */ if (!(res->flags & IORESOURCE_MEM)) @@ -270,7 +271,7 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, /* Configure the resource */ if (ppc4xx_setup_one_pci_PMM(hose, reg, res->start, - res->start - hose->pci_mem_offset, + res->start - offset, resource_size(res), res->flags, j) == 0) { @@ -279,7 +280,7 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, /* If the resource PCI address is 0 then we have our * ISA memory hole */ - if (res->start == hose->pci_mem_offset) + if (res->start == offset) found_isa_hole = 1; } } @@ -457,6 +458,7 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, /* Setup outbound memory windows */ for (i = j = 0; i < 3; i++) { struct resource *res = &hose->mem_resources[i]; + resource_size_t offset = hose->mem_offset[i]; /* we only care about memory windows */ if (!(res->flags & IORESOURCE_MEM)) @@ -470,7 +472,7 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, /* Configure the resource */ if (ppc4xx_setup_one_pcix_POM(hose, reg, res->start, - res->start - hose->pci_mem_offset, + res->start - offset, resource_size(res), res->flags, j) == 0) { @@ -479,7 +481,7 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, /* If the resource PCI address is 0 then we have our * ISA memory hole */ - if (res->start == hose->pci_mem_offset) + if (res->start == offset) found_isa_hole = 1; } } @@ -1792,6 +1794,7 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, /* Setup outbound memory windows */ for (i = j = 0; i < 3; i++) { struct resource *res = &hose->mem_resources[i]; + resource_size_t offset = hose->mem_offset[i]; /* we only care about memory windows */ if (!(res->flags & IORESOURCE_MEM)) @@ -1805,7 +1808,7 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, /* Configure the resource */ if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, res->start, - res->start - hose->pci_mem_offset, + res->start - offset, resource_size(res), res->flags, j) == 0) { @@ -1814,7 +1817,7 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, /* If the resource PCI address is 0 then we have our * ISA memory hole */ - if (res->start == hose->pci_mem_offset) + if (res->start == offset) found_isa_hole = 1; } } diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 41ac3dfac98e..3c251993bacd 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig @@ -22,6 +22,6 @@ config UCC config QE_USB bool - default y if USB_GADGET_FSL_QE + default y if USB_FSL_QE help QE USB Controller support diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c index 9afba924e94f..af79e1ea74b6 100644 --- a/arch/powerpc/sysdev/rtc_cmos_setup.c +++ b/arch/powerpc/sysdev/rtc_cmos_setup.c @@ -62,10 +62,7 @@ static int __init add_rtc(void) pd = platform_device_register_simple("rtc_cmos", -1, &res[0], num_res); - if (IS_ERR(pd)) - return PTR_ERR(pd); - - return 0; + return PTR_RET(pd); } fs_initcall(add_rtc); diff --git a/arch/powerpc/sysdev/udbg_memcons.c b/arch/powerpc/sysdev/udbg_memcons.c new file mode 100644 index 000000000000..ce5a7b489e4b --- /dev/null +++ b/arch/powerpc/sysdev/udbg_memcons.c @@ -0,0 +1,105 @@ +/* + * A udbg backend which logs messages and reads input from in memory + * buffers. + * + * The console output can be read from memcons_output which is a + * circular buffer whose next write position is stored in memcons.output_pos. + * + * Input may be passed by writing into the memcons_input buffer when it is + * empty. The input buffer is empty when both input_pos == input_start and + * *input_start == '\0'. + * + * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp + * Copyright (C) 2013 Alistair Popple, 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. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/barrier.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/udbg.h> + +struct memcons { + char *output_start; + char *output_pos; + char *output_end; + char *input_start; + char *input_pos; + char *input_end; +}; + +static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE]; +static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE]; + +struct memcons memcons = { + .output_start = memcons_output, + .output_pos = memcons_output, + .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE], + .input_start = memcons_input, + .input_pos = memcons_input, + .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE], +}; + +void memcons_putc(char c) +{ + char *new_output_pos; + + *memcons.output_pos = c; + wmb(); + new_output_pos = memcons.output_pos + 1; + if (new_output_pos >= memcons.output_end) + new_output_pos = memcons.output_start; + + memcons.output_pos = new_output_pos; +} + +int memcons_getc_poll(void) +{ + char c; + char *new_input_pos; + + if (*memcons.input_pos) { + c = *memcons.input_pos; + + new_input_pos = memcons.input_pos + 1; + if (new_input_pos >= memcons.input_end) + new_input_pos = memcons.input_start; + else if (*new_input_pos == '\0') + new_input_pos = memcons.input_start; + + *memcons.input_pos = '\0'; + wmb(); + memcons.input_pos = new_input_pos; + return c; + } + + return -1; +} + +int memcons_getc(void) +{ + int c; + + while (1) { + c = memcons_getc_poll(); + if (c == -1) + cpu_relax(); + else + break; + } + + return c; +} + +void udbg_init_memcons(void) +{ + udbg_putc = memcons_putc; + udbg_getc = memcons_getc; + udbg_getc_poll = memcons_getc_poll; +} diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 48861d3fcd07..7cd728b3b5e4 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c @@ -51,6 +51,12 @@ static struct icp_ipl __iomem *icp_native_regs[NR_CPUS]; static inline unsigned int icp_native_get_xirr(void) { int cpu = smp_processor_id(); + unsigned int xirr; + + /* Handled an interrupt latched by KVM */ + xirr = kvmppc_get_xics_latch(); + if (xirr) + return xirr; return in_be32(&icp_native_regs[cpu]->xirr.word); } @@ -81,7 +87,7 @@ static void icp_native_set_cpu_priority(unsigned char cppr) iosync(); } -static void icp_native_eoi(struct irq_data *d) +void icp_native_eoi(struct irq_data *d) { unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); @@ -138,6 +144,7 @@ static unsigned int icp_native_get_irq(void) static void icp_native_cause_ipi(int cpu, unsigned long data) { + kvmppc_set_host_ipi(cpu, 1); icp_native_set_qirr(cpu, IPI_PRIORITY); } @@ -151,6 +158,7 @@ static irqreturn_t icp_native_ipi_action(int irq, void *dev_id) { int cpu = smp_processor_id(); + kvmppc_set_host_ipi(cpu, 0); icp_native_set_qirr(cpu, 0xff); return smp_ipi_demux(); diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index f7e8609df0d5..39d72212655e 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -148,7 +148,7 @@ static int ics_opal_set_affinity(struct irq_data *d, __func__, d->irq, hw_irq, server, rc); return -1; } - return 0; + return IRQ_SET_MASK_OK; } static struct irq_chip ics_opal_irq_chip = { |