diff options
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/chmc.c | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/isa.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/ldc.c | 15 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 24 |
8 files changed, 71 insertions, 20 deletions
diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c index 777d3457704..6d4f02e8a4c 100644 --- a/arch/sparc64/kernel/chmc.c +++ b/arch/sparc64/kernel/chmc.c @@ -1,7 +1,6 @@ -/* $Id: chmc.c,v 1.4 2002/01/08 16:00:14 davem Exp $ - * memctrlr.c: Driver for UltraSPARC-III memory controller. +/* memctrlr.c: Driver for UltraSPARC-III memory controller. * - * Copyright (C) 2001 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2007 David S. Miller (davem@davemloft.net) */ #include <linux/module.h> @@ -16,6 +15,7 @@ #include <linux/init.h> #include <asm/spitfire.h> #include <asm/chmctrl.h> +#include <asm/cpudata.h> #include <asm/oplib.h> #include <asm/prom.h> #include <asm/io.h> @@ -242,8 +242,11 @@ int chmc_getunumber(int syndrome_code, */ static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset) { - unsigned long ret; - int this_cpu = get_cpu(); + unsigned long ret, this_cpu; + + preempt_disable(); + + this_cpu = real_hard_smp_processor_id(); if (mp->portid == this_cpu) { __asm__ __volatile__("ldxa [%1] %2, %0" @@ -255,7 +258,8 @@ static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset) : "r" (mp->regs + offset), "i" (ASI_PHYS_BYPASS_EC_E)); } - put_cpu(); + + preempt_enable(); return ret; } diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index c9b0d7af64a..ea257e82836 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -2593,3 +2593,15 @@ sun4v_mmustat_info: retl nop .size sun4v_mmustat_info, .-sun4v_mmustat_info + + .globl sun4v_mmu_demap_all + .type sun4v_mmu_demap_all,#function +sun4v_mmu_demap_all: + clr %o0 + clr %o1 + mov HV_MMU_ALL, %o2 + mov HV_FAST_MMU_DEMAP_ALL, %o5 + ta HV_FAST_TRAP + retl + nop + .size sun4v_mmu_demap_all, .-sun4v_mmu_demap_all diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index 0f19dce1c90..b5f7b354084 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -155,6 +155,7 @@ void __init isa_init(void) isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); if (!isa_br) { printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); + pci_dev_put(pdev); return; } @@ -168,6 +169,7 @@ void __init isa_init(void) printk(KERN_DEBUG "isa: device registration error for %s!\n", dp->path_component_name); kfree(isa_br); + pci_dev_put(pdev); return; } diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c index 217478a9412..63969f61028 100644 --- a/arch/sparc64/kernel/ldc.c +++ b/arch/sparc64/kernel/ldc.c @@ -2338,6 +2338,7 @@ static int __init ldc_init(void) unsigned long major, minor; struct mdesc_handle *hp; const u64 *v; + int err; u64 mp; hp = mdesc_grab(); @@ -2345,29 +2346,33 @@ static int __init ldc_init(void) return -ENODEV; mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform"); + err = -ENODEV; if (mp == MDESC_NODE_NULL) - return -ENODEV; + goto out; v = mdesc_get_property(hp, mp, "domaining-enabled", NULL); if (!v) - return -ENODEV; + goto out; major = 1; minor = 0; if (sun4v_hvapi_register(HV_GRP_LDOM, major, &minor)) { printk(KERN_INFO PFX "Could not register LDOM hvapi.\n"); - return -ENODEV; + goto out; } printk(KERN_INFO "%s", version); if (!*v) { printk(KERN_INFO PFX "Domaining disabled.\n"); - return -ENODEV; + goto out; } ldom_domaining_enabled = 1; + err = 0; - return 0; +out: + mdesc_release(hp); + return err; } core_initcall(ldc_init); diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 63b3ebc0c3c..a61c38fe75e 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1275,4 +1275,20 @@ int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) return (device_mask & dma_addr_mask) == dma_addr_mask; } +void pci_resource_to_user(const struct pci_dev *pdev, int bar, + const struct resource *rp, resource_size_t *start, + resource_size_t *end) +{ + struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + unsigned long offset; + + if (rp->flags & IORESOURCE_IO) + offset = pbm->io_space.start; + else + offset = pbm->mem_space.start; + + *start = rp->start - offset; + *end = rp->end - offset; +} + #endif /* !(CONFIG_PCI) */ diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 9546ba9f5de..e752e75cce8 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -850,7 +850,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) /* How the Tomatillo IRQs are routed around is pure guesswork here. * * All the Tomatillo devices I see in prtconf dumps seem to have only - * a single PCI bus unit attached to it. It would seem they are seperate + * a single PCI bus unit attached to it. It would seem they are separate * devices because their PortID (ie. JBUS ID) values are all different * and thus the registers are mapped to totally different locations. * diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 8c4875bdb4a..e587a372f3f 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1022,6 +1022,10 @@ void __init sun4v_pci_init(struct device_node *dp, char *model_name) } prop = of_find_property(dp, "reg", NULL); + if (!prop) { + prom_printf("SUN4V_PCI: Could not find config registers\n"); + prom_halt(); + } regs = prop->value; devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 7cd8d94df0d..c39944927f1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -236,8 +236,9 @@ void smp_synchronize_tick_client(void) t[i].rt, t[i].master, t[i].diff, t[i].lat); #endif - printk(KERN_INFO "CPU %d: synchronized TICK with master CPU (last diff %ld cycles," - "maxerr %lu cycles)\n", smp_processor_id(), delta, rt); + printk(KERN_INFO "CPU %d: synchronized TICK with master CPU " + "(last diff %ld cycles, maxerr %lu cycles)\n", + smp_processor_id(), delta, rt); } static void smp_start_sync_tick_client(int cpu); @@ -475,7 +476,7 @@ static inline void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpuma */ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { - u64 pstate, ver; + u64 pstate, ver, busy_mask; int nack_busy_id, is_jbus, need_more; if (cpus_empty(mask)) @@ -507,14 +508,20 @@ retry: "i" (ASI_INTR_W)); nack_busy_id = 0; + busy_mask = 0; { int i; for_each_cpu_mask(i, mask) { u64 target = (i << 14) | 0x70; - if (!is_jbus) + if (is_jbus) { + busy_mask |= (0x1UL << (i * 2)); + } else { target |= (nack_busy_id << 24); + busy_mask |= (0x1UL << + (nack_busy_id * 2)); + } __asm__ __volatile__( "stxa %%g0, [%0] %1\n\t" "membar #Sync\n\t" @@ -530,15 +537,16 @@ retry: /* Now, poll for completion. */ { - u64 dispatch_stat; + u64 dispatch_stat, nack_mask; long stuck; stuck = 100000 * nack_busy_id; + nack_mask = busy_mask << 1; do { __asm__ __volatile__("ldxa [%%g0] %1, %0" : "=r" (dispatch_stat) : "i" (ASI_INTR_DISPATCH_STAT)); - if (dispatch_stat == 0UL) { + if (!(dispatch_stat & (busy_mask | nack_mask))) { __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); if (unlikely(need_more)) { @@ -555,12 +563,12 @@ retry: } if (!--stuck) break; - } while (dispatch_stat & 0x5555555555555555UL); + } while (dispatch_stat & busy_mask); __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); - if ((dispatch_stat & ~(0x5555555555555555UL)) == 0) { + if (dispatch_stat & busy_mask) { /* Busy bits will not clear, continue instead * of freezing up on this cpu. */ |