diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/powermac/cpufreq_32.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/low_i2c.c | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 61 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/msi.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/reconfig.c | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 9 |
8 files changed, 84 insertions, 18 deletions
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 65c585b8b00d..08d94e4cedd3 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -44,14 +44,6 @@ */ #undef DEBUG_FREQ -/* - * There is a problem with the core cpufreq code on SMP kernels, - * it won't recalculate the Bogomips properly - */ -#ifdef CONFIG_SMP -#warning "WARNING, CPUFREQ not recommended on SMP kernels" -#endif - extern void low_choose_7447a_dfs(int dfs); extern void low_choose_750fx_pll(int pll); extern void low_sleep_handler(void); diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 21226b74c9b2..414ca9849f23 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -540,8 +540,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) /* Make sure IRQ is disabled */ kw_write_reg(reg_ier, 0); - /* Request chip interrupt */ - if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host)) + /* Request chip interrupt. We set IRQF_TIMER because we don't + * want that interrupt disabled between the 2 passes of driver + * suspend or we'll have issues running the pfuncs + */ + if (request_irq(host->irq, kw_i2c_irq, IRQF_TIMER, "keywest i2c", host)) host->irq = NO_IRQ; printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 04cdd32624d4..e81403b245b5 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -1286,3 +1286,64 @@ static void fixup_k2_sata(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata); +/* + * On U4 (aka CPC945) the PCIe root complex "P2P" bridge resource ranges aren't + * configured by the firmware. The bridge itself seems to ignore them but it + * causes problems with Linux which then re-assigns devices below the bridge, + * thus changing addresses of those devices from what was in the device-tree, + * which sucks when those are video cards using offb + * + * We could just mark it transparent but I prefer fixing up the resources to + * properly show what's going on here, as I have some doubts about having them + * badly configured potentially being an issue for DMA. + * + * We leave PIO alone, it seems to be fine + * + * Oh and there's another funny bug. The OF properties advertize the region + * 0xf1000000..0xf1ffffff as being forwarded as memory space. But that's + * actually not true, this region is the memory mapped config space. So we + * also need to filter it out or we'll map things in the wrong place. + */ +static void fixup_u4_pcie(struct pci_dev* dev) +{ + struct pci_controller *host = pci_bus_to_host(dev->bus); + struct resource *region = NULL; + u32 reg; + int i; + + /* Only do that on PowerMac */ + if (!machine_is(powermac)) + return; + + /* Find the largest MMIO region */ + for (i = 0; i < 3; i++) { + struct resource *r = &host->mem_resources[i]; + if (!(r->flags & IORESOURCE_MEM)) + continue; + /* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they + * are reserved by HW for other things + */ + if (r->start >= 0xf0000000 && r->start < 0xf3000000) + continue; + if (!region || (r->end - r->start) > + (region->end - region->start)) + region = r; + } + /* Nothing found, bail */ + if (region == 0) + return; + + /* Print things out */ + printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region); + + /* Fixup bridge config space. We know it's a Mac, resource aren't + * offset so let's just blast them as-is. We also know that they + * fit in 32 bits + */ + reg = ((region->start >> 16) & 0xfff0) | (region->end & 0xfff00000); + pci_write_config_dword(dev, PCI_MEMORY_BASE, reg); + pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0); + pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0); + pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie); diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 6d4da7b46b41..937a38e73178 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -408,7 +408,7 @@ static void __init smp_psurge_setup_cpu(int cpu_nr) /* reset the entry point so if we get another intr we won't * try to startup again */ out_be32(psurge_start, 0x100); - if (setup_irq(30, &psurge_irqaction)) + if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction)) printk(KERN_ERR "Couldn't get primary IPI interrupt"); } diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index bf2e1ac41308..1164c3430f2c 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -432,8 +432,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) /* Read config space back so we can restore after reset */ read_msi_msg(virq, &msg); entry->msg = msg; - - unmask_msi_irq(virq); } return 0; diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index b6f1b137d427..2e2bbe120b90 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -20,6 +20,7 @@ #include <asm/machdep.h> #include <asm/uaccess.h> #include <asm/pSeries_reconfig.h> +#include <asm/mmu.h> @@ -439,9 +440,15 @@ static int do_update_property(char *buf, size_t bufsize) if (!newprop) return -ENOMEM; + if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) + slb_set_size(*(int *)value); + oldprop = of_find_property(np, name,NULL); - if (!oldprop) + if (!oldprop) { + if (strlen(name)) + return prom_add_property(np, newprop); return -ENODEV; + } rc = prom_update_property(np, newprop, oldprop); if (rc) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8d75ea21296f..ca5f2e10972c 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -223,10 +223,6 @@ static void pseries_lpar_enable_pmcs(void) set = 1UL << 63; reset = 0; plpar_hcall_norets(H_PERFMON, set, reset); - - /* instruct hypervisor to maintain PMCs */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) - get_lppaca()->pmcregs_in_use = 1; } static void __init pseries_discover_pic(void) diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 419f8a637ffe..b9bf0eedccf2 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/radix-tree.h> #include <linux/cpu.h> +#include <linux/msi.h> #include <linux/of.h> #include <asm/firmware.h> @@ -219,6 +220,14 @@ static void xics_unmask_irq(unsigned int virq) static unsigned int xics_startup(unsigned int virq) { + /* + * The generic MSI code returns with the interrupt disabled on the + * card, using the MSI mask bits. Firmware doesn't appear to unmask + * at that level, so we do it here by hand. + */ + if (irq_to_desc(virq)->msi_desc) + unmask_msi_irq(virq); + /* unmask it */ xics_unmask_irq(virq); return 0; |