Commit c4888f9f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (37 commits)
  [POWERPC] EEH: Make sure warning message is printed
  [POWERPC] Make altivec code in swsusp_32.S depend on CONFIG_ALTIVEC
  [POWERPC] windfarm: Fix windfarm thread freezer interaction
  [POWERPC] Fix si_addr value on low level hash failures
  [POWERPC] Refresh ppc64_defconfig and enable pasemi-related options
  [POWERPC] pasemi: Update defconfig
  [POWERPC] iSeries: Fix ref counting in vio setup
  [POWERPC] ] Fix memset size error
  [POWERPC] Fix link errors for allyesconfig
  [POWERPC] iSeries_init_IRQ non-PCI tidy
  [POWERPC] Change fallocate to match unistd.h on powerpc
  [POWERPC] EEH: Avoid crash on null device
  [POWERPC] EEH: Drivers that need reset trump others
  [POWERPC] EEH: Clean up comments
  [POWERPC] Fix off-by-one error in setting decrementer on Book E/4xx (v2)
  [POWERPC] Fix switch_slb handling of 1T ESID values
  [POWERPC] Fix build failure when CONFIG_VIRT_CPU_ACCOUNTING is not defined
  [POWERPC] Include udbg.h when using udbg_printf
  [POWERPC] Fix cache line vs. block size confusion
  [POWERPC] Fix sysctl table check failure on PowerMac
  ...
parents e36aeee6 688016f4
...@@ -122,7 +122,9 @@ EMAC: ethernet@ef600800 { ...@@ -122,7 +122,9 @@ EMAC: ethernet@ef600800 {
device_type = "network"; device_type = "network";
compatible = "ibm,emac-405gp", "ibm,emac"; compatible = "ibm,emac-405gp", "ibm,emac";
interrupt-parent = <&UIC0>; interrupt-parent = <&UIC0>;
interrupts = <9 4 f 4>; interrupts = <
f 4 /* Ethernet */
9 4 /* Ethernet Wake Up */>;
local-mac-address = [000000000000]; /* Filled in by zImage */ local-mac-address = [000000000000]; /* Filled in by zImage */
reg = <ef600800 70>; reg = <ef600800 70>;
mal-device = <&MAL>; mal-device = <&MAL>;
......
...@@ -21,6 +21,14 @@ ...@@ -21,6 +21,14 @@
# (default ./arch/powerpc/boot) # (default ./arch/powerpc/boot)
# -W dir specify working directory for temporary files (default .) # -W dir specify working directory for temporary files (default .)
# Stop execution if any command fails
set -e
# Allow for verbose output
if [ "$V" = 1 ]; then
set -x
fi
# defaults # defaults
kernel= kernel=
ofile=zImage ofile=zImage
...@@ -111,7 +119,7 @@ if [ -n "$dts" ]; then ...@@ -111,7 +119,7 @@ if [ -n "$dts" ]; then
if [ -z "$dtb" ]; then if [ -z "$dtb" ]; then
dtb="$platform.dtb" dtb="$platform.dtb"
fi fi
dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1 dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
fi fi
if [ -z "$kernel" ]; then if [ -z "$kernel" ]; then
...@@ -149,7 +157,6 @@ cuboot*) ...@@ -149,7 +157,6 @@ cuboot*)
ps3) ps3)
platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
lds=$object/zImage.ps3.lds lds=$object/zImage.ps3.lds
binary=y
gzip= gzip=
ext=bin ext=bin
objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data" objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
...@@ -233,7 +240,7 @@ entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3` ...@@ -233,7 +240,7 @@ entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
if [ -n "$binary" ]; then if [ -n "$binary" ]; then
mv "$ofile" "$ofile".elf mv "$ofile" "$ofile".elf
${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin ${CROSS}objcopy -O binary "$ofile".elf "$ofile"
fi fi
# post-processing needed for some platforms # post-processing needed for some platforms
...@@ -246,9 +253,9 @@ coff) ...@@ -246,9 +253,9 @@ coff)
$object/hack-coff "$ofile" $object/hack-coff "$ofile"
;; ;;
cuboot*) cuboot*)
gzip -f -9 "$ofile".bin gzip -f -9 "$ofile"
mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \ mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
$uboot_version -d "$ofile".bin.gz "$ofile" $uboot_version -d "$ofile".gz "$ofile"
;; ;;
treeboot*) treeboot*)
mv "$ofile" "$ofile.elf" mv "$ofile" "$ofile.elf"
...@@ -269,11 +276,11 @@ ps3) ...@@ -269,11 +276,11 @@ ps3)
# then copied to offset 0x100. At runtime the bootwrapper program # then copied to offset 0x100. At runtime the bootwrapper program
# copies the 0x100 bytes at __system_reset_kernel to addr 0x100. # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
system_reset_overlay=0x`${CROSS}nm "$ofile".elf \ system_reset_overlay=0x`${CROSS}nm "$ofile" \
| grep ' __system_reset_overlay$' \ | grep ' __system_reset_overlay$' \
| cut -d' ' -f1` | cut -d' ' -f1`
system_reset_overlay=`printf "%d" $system_reset_overlay` system_reset_overlay=`printf "%d" $system_reset_overlay`
system_reset_kernel=0x`${CROSS}nm "$ofile".elf \ system_reset_kernel=0x`${CROSS}nm "$ofile" \
| grep ' __system_reset_kernel$' \ | grep ' __system_reset_kernel$' \
| cut -d' ' -f1` | cut -d' ' -f1`
system_reset_kernel=`printf "%d" $system_reset_kernel` system_reset_kernel=`printf "%d" $system_reset_kernel`
...@@ -282,23 +289,15 @@ ps3) ...@@ -282,23 +289,15 @@ ps3)
rm -f "$object/otheros.bld" rm -f "$object/otheros.bld"
msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
skip=$overlay_dest seek=$system_reset_kernel \
count=$overlay_size bs=1 2>&1)
if [ $? -ne "0" ]; then dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
echo $msg skip=$overlay_dest seek=$system_reset_kernel \
exit 1 count=$overlay_size bs=1
fi
msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
skip=$system_reset_overlay seek=$overlay_dest \
count=$overlay_size bs=1 2>&1)
if [ $? -ne "0" ]; then dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
echo $msg skip=$system_reset_overlay seek=$overlay_dest \
exit 2 count=$overlay_size bs=1
fi
gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld" gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
;; ;;
......
This diff is collapsed.
This diff is collapsed.
...@@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
{ {
.pvr_mask = 0xf0000fff, .pvr_mask = 0xf0000fff,
.pvr_value = 0x40000850, .pvr_value = 0x40000850,
.cpu_name = "440GR Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32,
.dcache_bsize = 32,
.platform = "ppc440",
},
{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000858,
.cpu_name = "440EP Rev. A", .cpu_name = "440EP Rev. A",
.cpu_features = CPU_FTRS_44X, .cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
...@@ -1115,28 +1125,27 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1115,28 +1125,27 @@ static struct cpu_spec __initdata cpu_specs[] = {
{ {
.pvr_mask = 0xf0000fff, .pvr_mask = 0xf0000fff,
.pvr_value = 0x400008d3, .pvr_value = 0x400008d3,
.cpu_name = "440EP Rev. B", .cpu_name = "440GR Rev. B",
.cpu_features = CPU_FTRS_44X, .cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440EPX */ { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
.pvr_mask = 0xf0000ffb, .pvr_mask = 0xf0000fff,
.pvr_value = 0x200008D0, .pvr_value = 0x400008db,
.cpu_name = "440EPX", .cpu_name = "440EP Rev. B",
.cpu_features = CPU_FTRS_44X, .cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440epx, .cpu_setup = __setup_cpu_440ep,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GRX */ { /* 440GRX */
.pvr_mask = 0xf0000ffb, .pvr_mask = 0xf0000ffb,
.pvr_value = 0x200008D8, .pvr_value = 0x200008D0,
.cpu_name = "440GRX", .cpu_name = "440GRX",
.cpu_features = CPU_FTRS_44X, .cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
...@@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_440grx, .cpu_setup = __setup_cpu_440grx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
.pvr_mask = 0xf0000ffb,
.pvr_value = 0x200008D8,
.cpu_name = "440EPX",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440epx,
.platform = "ppc440",
},
{ /* 440GP Rev. B */ { /* 440GP Rev. B */
.pvr_mask = 0xf0000fff, .pvr_mask = 0xf0000fff,
.pvr_value = 0x40000440, .pvr_value = 0x40000440,
......
...@@ -244,6 +244,13 @@ syscall_exit_cont: ...@@ -244,6 +244,13 @@ syscall_exit_cont:
andis. r10,r0,DBCR0_IC@h andis. r10,r0,DBCR0_IC@h
bnel- load_dbcr0 bnel- load_dbcr0
#endif #endif
#ifdef CONFIG_44x
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
bne- 2f
1:
#endif /* CONFIG_44x */
stwcx. r0,0,r1 /* to clear the reservation */ stwcx. r0,0,r1 /* to clear the reservation */
lwz r4,_LINK(r1) lwz r4,_LINK(r1)
lwz r5,_CCR(r1) lwz r5,_CCR(r1)
...@@ -258,6 +265,12 @@ syscall_exit_cont: ...@@ -258,6 +265,12 @@ syscall_exit_cont:
mtspr SPRN_SRR1,r8 mtspr SPRN_SRR1,r8
SYNC SYNC
RFI RFI
#ifdef CONFIG_44x
2: li r7,0
iccci r0,r0
stw r7,icache_44x_need_flush@l(r4)
b 1b
#endif /* CONFIG_44x */
66: li r3,-ENOSYS 66: li r3,-ENOSYS
b ret_from_syscall b ret_from_syscall
...@@ -683,6 +696,16 @@ resume_kernel: ...@@ -683,6 +696,16 @@ resume_kernel:
/* interrupts are hard-disabled at this point */ /* interrupts are hard-disabled at this point */
restore: restore:
#ifdef CONFIG_44x
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
beq+ 1f
li r6,0
iccci r0,r0
stw r6,icache_44x_need_flush@l(r4)
1:
#endif /* CONFIG_44x */
lwz r0,GPR0(r1) lwz r0,GPR0(r1)
lwz r2,GPR2(r1) lwz r2,GPR2(r1)
REST_4GPRS(3, r1) REST_4GPRS(3, r1)
......
...@@ -904,7 +904,7 @@ handle_page_fault: ...@@ -904,7 +904,7 @@ handle_page_fault:
*/ */
12: bl .save_nvgprs 12: bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
lwz r4,_DAR(r1) ld r4,_DAR(r1)
bl .low_hash_fault bl .low_hash_fault
b .ret_from_except b .ret_from_except
......
...@@ -122,7 +122,7 @@ static ctl_table powersave_nap_sysctl_root[] = { ...@@ -122,7 +122,7 @@ static ctl_table powersave_nap_sysctl_root[] = {
{ {
.ctl_name = CTL_KERN, .ctl_name = CTL_KERN,
.procname = "kernel", .procname = "kernel",
.mode = 0755, .mode = 0555,
.child = powersave_nap_ctl_table, .child = powersave_nap_ctl_table,
}, },
{} {}
......
...@@ -288,7 +288,16 @@ _GLOBAL(_tlbia) ...@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
*/ */
_GLOBAL(_tlbie) _GLOBAL(_tlbie)
#if defined(CONFIG_40x) #if defined(CONFIG_40x)
/* We run the search with interrupts disabled because we have to change
* the PID and I don't want to preempt when that happens.
*/
mfmsr r5
mfspr r6,SPRN_PID
wrteei 0
mtspr SPRN_PID,r4
tlbsx. r3, 0, r3 tlbsx. r3, 0, r3
mtspr SPRN_PID,r6
wrtee r5
bne 10f bne 10f
sync sync
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
...@@ -297,23 +306,23 @@ _GLOBAL(_tlbie) ...@@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
tlbwe r3, r3, TLB_TAG tlbwe r3, r3, TLB_TAG
isync isync
10: 10:
#elif defined(CONFIG_44x) #elif defined(CONFIG_44x)
mfspr r4,SPRN_MMUCR mfspr r5,SPRN_MMUCR
mfspr r5,SPRN_PID /* Get PID */ rlwimi r5,r4,0,24,31 /* Set TID */
rlwimi r4,r5,0,24,31 /* Set TID */
/* We have to run the search with interrupts disabled, even critical /* We have to run the search with interrupts disabled, even critical
* and debug interrupts (in fact the only critical exceptions we have * and debug interrupts (in fact the only critical exceptions we have
* are debug and machine check). Otherwise an interrupt which causes * are debug and machine check). Otherwise an interrupt which causes
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
mfmsr r5 mfmsr r4
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
andc r6,r5,r6 andc r6,r4,r6
mtmsr r6 mtmsr r6
mtspr SPRN_MMUCR,r4 mtspr SPRN_MMUCR,r5
tlbsx. r3, 0, r3 tlbsx. r3, 0, r3
mtmsr r5 mtmsr r4
bne 10f bne 10f
sync sync
/* There are only 64 TLB entries, so r3 < 64, /* There are only 64 TLB entries, so r3 < 64,
...@@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) ...@@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
addi r3,r3,L1_CACHE_BYTES addi r3,r3,L1_CACHE_BYTES
bdnz 0b bdnz 0b
sync sync
#ifndef CONFIG_44x
/* We don't flush the icache on 44x. Those have a virtual icache
* and we don't have access to the virtual address here (it's
* not the page vaddr but where it's mapped in user space). The
* flushing of the icache on these is handled elsewhere, when
* a change in the address space occurs, before returning to
* user space
*/
mtctr r4 mtctr r4
1: icbi 0,r6 1: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES addi r6,r6,L1_CACHE_BYTES
bdnz 1b bdnz 1b
sync sync
isync isync
#endif /* CONFIG_44x */
blr blr
/* /*
......
...@@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node, ...@@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
prop = of_get_flat_dt_prop(node, "cpu-version", NULL); prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
if (prop && (*prop & 0xff000000) == 0x0f000000) if (prop && (*prop & 0xff000000) == 0x0f000000)
identify_cpu(0, *prop); identify_cpu(0, *prop);
#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
/*
* Since 440GR(x)/440EP(x) processors have the same pvr,
* we check the node path and set bit 28 in the cur_cpu_spec
* pvr for EP(x) processor version. This bit is always 0 in
* the "real" pvr. Then we call identify_cpu again with
* the new logical pvr to enable FPU support.
*/
if (strstr(uname, "440EP")) {
identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
}
#endif
} }
check_cpu_feature_properties(node); check_cpu_feature_properties(node);
......
...@@ -1244,7 +1244,7 @@ static void __init prom_initialize_tce_table(void) ...@@ -1244,7 +1244,7 @@ static void __init prom_initialize_tce_table(void)
local_alloc_bottom = base; local_alloc_bottom = base;
/* It seems OF doesn't null-terminate the path :-( */ /* It seems OF doesn't null-terminate the path :-( */
memset(path, 0, sizeof(path)); memset(path, 0, PROM_SCRATCH_SIZE);
/* Call OF to setup the TCE hardware */ /* Call OF to setup the TCE hardware */
if (call_prom("package-to-path", 3, 1, node, if (call_prom("package-to-path", 3, 1, node,
path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) { path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
......
...@@ -291,23 +291,16 @@ static void __init initialize_cache_info(void) ...@@ -291,23 +291,16 @@ static void __init initialize_cache_info(void)
if ( num_cpus == 1 ) { if ( num_cpus == 1 ) {
const u32 *sizep, *lsizep; const u32 *sizep, *lsizep;
u32 size, lsize; u32 size, lsize;
const char *dc, *ic;
/* Then read cache informations */
if (machine_is(powermac)) {
dc = "d-cache-block-size";
ic = "i-cache-block-size";
} else {
dc = "d-cache-line-size";
ic = "i-cache-line-size";
}
size = 0; size = 0;
lsize = cur_cpu_spec->dcache_bsize; lsize = cur_cpu_spec->dcache_bsize;
sizep = of_get_property(np, "d-cache-size", NULL); sizep = of_get_property(np, "d-cache-size", NULL);
if (sizep != NULL) if (sizep != NULL)
size = *sizep; size = *sizep;
lsizep = of_get_property(np, dc, NULL); lsizep = of_get_property(np, "d-cache-block-size", NULL);
/* fallback if block size missing */
if (lsizep == NULL)
lsizep = of_get_property(np, "d-cache-line-size", NULL);
if (lsizep != NULL) if (lsizep != NULL)
lsize = *lsizep; lsize = *lsizep;
if (sizep == 0 || lsizep == 0) if (sizep == 0 || lsizep == 0)
...@@ -324,7 +317,9 @@ static void __init initialize_cache_info(void) ...@@ -324,7 +317,9 @@ static void __init initialize_cache_info(void)
sizep = of_get_property(np, "i-cache-size", NULL); sizep = of_get_property(np, "i-cache-size", NULL);
if (sizep != NULL) if (sizep != NULL)
size = *sizep; size = *sizep;
lsizep = of_get_property(np, ic, NULL); lsizep = of_get_property(np, "i-cache-block-size", NULL);
if (lsizep == NULL)
lsizep = of_get_property(np, "i-cache-line-size", NULL);
if (lsizep != NULL) if (lsizep != NULL)
lsize = *lsizep; lsize = *lsizep;
if (sizep == 0 || lsizep == 0) if (sizep == 0 || lsizep == 0)
......
...@@ -133,10 +133,12 @@ _GLOBAL(swsusp_arch_suspend) ...@@ -133,10 +133,12 @@ _GLOBAL(swsusp_arch_suspend)
/* Resume code */ /* Resume code */
_GLOBAL(swsusp_arch_resume) _GLOBAL(swsusp_arch_resume)
#ifdef CONFIG_ALTIVEC
/* Stop pending alitvec streams and memory accesses */ /* Stop pending alitvec streams and memory accesses */
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
DSSALL DSSALL
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif
sync sync
/* Disable MSR:DR to make sure we don't take a TLB or /* Disable MSR:DR to make sure we don't take a TLB or
......
...@@ -586,7 +586,7 @@ void timer_interrupt(struct pt_regs * regs) ...@@ -586,7 +586,7 @@ void timer_interrupt(struct pt_regs * regs)
/* not time for this event yet */ /* not time for this event yet */
now = per_cpu(decrementer_next_tb, cpu) - now; now = per_cpu(decrementer_next_tb, cpu) - now;
if (now <= DECREMENTER_MAX) if (now <= DECREMENTER_MAX)
set_dec((unsigned int)now - 1); set_dec((int)now);
return; return;
} }
old_regs = set_irq_regs(regs); old_regs = set_irq_regs(regs);
...@@ -611,8 +611,6 @@ void timer_interrupt(struct pt_regs * regs) ...@@ -611,8 +611,6 @@ void timer_interrupt(struct pt_regs * regs)
if (evt->event_handler) if (evt->event_handler)
evt->event_handler(evt); evt->event_handler(evt);
else
evt->set_next_event(DECREMENTER_MAX, evt);
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
...@@ -836,9 +834,6 @@ static int decrementer_set_next_event(unsigned long evt, ...@@ -836,9 +834,6 @@ static int decrementer_set_next_event(unsigned long evt,
struct clock_event_device *dev) struct clock_event_device *dev)
{ {
__get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt; __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
/* The decrementer interrupts on the 0 -> -1 transition */
if (evt)
--evt;
set_dec(evt); set_dec(evt);
return 0; return 0;
} }
...@@ -871,7 +866,8 @@ void init_decrementer_clockevent(void) ...@@ -871,7 +866,8 @@ void init_decrementer_clockevent(void)
decrementer_clockevent.shift); decrementer_clockevent.shift);
decrementer_clockevent.max_delta_ns = decrementer_clockevent.max_delta_ns =
clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent); clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
decrementer_clockevent.min_delta_ns = 1000; decrementer_clockevent.min_delta_ns =
clockevent_delta2ns(2, &decrementer_clockevent);
register_decrementer_clockevent(cpu); register_decrementer_clockevent(cpu);
} }
......
...@@ -37,11 +37,10 @@ SECTIONS ...@@ -37,11 +37,10 @@ SECTIONS
ALIGN_FUNCTION(); ALIGN_FUNCTION();
*(.text.head) *(.text.head)
_text = .; _text = .;
TEXT_TEXT *(.text .fixup .text.init.refok .exit.text.refok)
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
KPROBES_TEXT KPROBES_TEXT
*(.fixup)
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
*(.got1) *(.got1)
......
...@@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void)
v = KERNELBASE; v = KERNELBASE;
p = PPC_MEMSTART; p = PPC_MEMSTART;
s = 0; s = total_lowmem;
if (__map_without_ltlbs) { if (__map_without_ltlbs)
return s; return 0;
}
while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) { while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp; pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE; unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
...@@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_16M; v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M; p += LARGE_PAGE_SIZE_16M;
s += LARGE_PAGE_SIZE_16M; s -= LARGE_PAGE_SIZE_16M;
} }
while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) { while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp; pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE; unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
...@@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_4M; v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M; p += LARGE_PAGE_SIZE_4M;
s += LARGE_PAGE_SIZE_4M; s -= LARGE_PAGE_SIZE_4M;
} }
return s; return total_lowmem - s;
} }
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
*/ */
unsigned int tlb_44x_index; /* = 0 */ unsigned int tlb_44x_index; /* = 0 */
unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
int icache_44x_need_flush;
/* /*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
......
...@@ -309,7 +309,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -309,7 +309,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
set_bit(PG_arch_1, &page->flags); set_bit(PG_arch_1, &page->flags);
} }
pte_update(ptep, 0, _PAGE_HWEXEC); pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address); _tlbie(address, mm->context.id);
pte_unmap_unlock(ptep, ptl); pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return 0; return 0;
......
...@@ -331,7 +331,7 @@ htab_pte_insert_failure: ...@@ -331,7 +331,7 @@ htab_pte_insert_failure:
*****************************************************************************/ *****************************************************************************/
/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, /* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
* pte_t *ptep, unsigned long trap, int local) * pte_t *ptep, unsigned long trap, int local, int ssize)
*/ */
/* /*
...@@ -557,7 +557,8 @@ htab_inval_old_hpte: ...@@ -557,7 +557,8 @@ htab_inval_old_hpte:
mr r4,r31 /* PTE.pte */ mr r4,r31 /* PTE.pte */
li r5,0 /* PTE.hidx */ li r5,0 /* PTE.hidx */
li r6,MMU_PAGE_64K /* psize */ li r6,MMU_PAGE_64K /* psize */
ld r7,STK_PARM(r8)(r1) /* local */ ld r7,STK_PARM(r9)(r1) /* ssize */
ld r8,STK_PARM(r8)(r1) /* local */
bl .flush_hash_page bl .flush_hash_page
b htab_insert_pte b htab_insert_pte
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/spu.h> #include <asm/spu.h>
#include <asm/udbg.h>
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)
...@@ -791,8 +792,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) ...@@ -791,8 +792,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
} }
if (user_region) { if (user_region) {
if (psize != get_paca()->context.user_psize) { if (psize != get_paca()->context.user_psize) {
get_paca()->context.user_psize = get_paca()->context = mm->context;
mm->context.user_psize;
slb_flush_and_rebolt(); slb_flush_and_rebolt();
} }
} else if (get_paca()->vmalloc_sllp != } else if (get_paca()->vmalloc_sllp !=
...@@ -885,6 +885,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, ...@@ -885,6 +885,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
local_irq_restore(flags); local_irq_restore(flags);
} }
/* WARNING: This is called from hash_low_64.S, if you change this prototype,
* do not forget to update the assembly call site !
*/
void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
int local) int local)
{ {
......
...@@ -61,12 +61,12 @@ extern unsigned long total_lowmem; ...@@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
#define mmu_mapin_ram() (0UL) #define mmu_mapin_ram() (0UL)
#elif defined(CONFIG_4xx) #elif defined(CONFIG_4xx)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void); extern unsigned long mmu_mapin_ram(void);
#elif defined(CONFIG_FSL_BOOKE) #elif defined(CONFIG_FSL_BOOKE)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void); extern unsigned long mmu_mapin_ram(void);
extern void adjust_total_lowmem(void); extern void adjust_total_lowmem(void);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <asm/udbg.h>
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)
...@@ -148,6 +149,35 @@ void slb_vmalloc_update(void) ...@@ -148,6 +149,35 @@ void slb_vmalloc_update(void)
slb_flush_and_rebolt(); slb_flush_and_rebolt();
} }
/* Helper function to compare esids. There are four cases to handle.
* 1. The system is not 1T segment size capable. Use the GET_ESID compare.
* 2. The system is 1T capable, both addresses are < 1T, use the GET_ESID compare.
* 3. The system is 1T capable, only one of the two addresses is > 1T. This is not a match.
* 4. The system is 1T capable, both addresses are > 1T, use the GET_ESID_1T macro to compare.
*/
static inline int esids_match(unsigned long addr1, unsigned long addr2)
{
int esid_1t_count;
/* System is not 1T segment size capable. */
if (!cpu_has_feature(CPU_FTR_1T_SEGMENT))
return (GET_ESID(addr1) == GET_ESID(addr2));
esid_1t_count = (((addr1 >> SID_SHIFT_1T) != 0) +
((addr2 >> SID_SHIFT_1T) != 0));
/* both addresses are < 1T */
if (esid_1t_count == 0)
return (GET_ESID(addr1) == GET_ESID(addr2));
/* One address < 1T, the other > 1T. Not a match */
if (esid_1t_count == 1)
return 0;
/* Both addresses are > 1T. */
return (GET_ESID_1T(addr1) == GET_ESID_1T(addr2));
}
/* Flush all user entries from the segment table of the current processor. */ /* Flush all user entries from the segment table of the current processor. */
void switch_slb(struct task_struct *tsk, struct mm_struct *mm) void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
{ {
...@@ -193,15 +223,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) ...@@ -193,15 +223,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
return; return;
slb_allocate(pc); slb_allocate(pc);
if (GET_ESID(pc) == GET_ESID(stack)) if (esids_match(pc,stack))
return; return;
if (is_kernel_addr(stack)) if (is_kernel_addr(stack))
return; return;
slb_allocate(stack); slb_allocate(stack);
if ((GET_ESID(pc) == GET_ESID(unmapped_base)) if (esids_match(pc,unmapped_base) || esids_match(stack,unmapped_base))
|| (GET_ESID(stack) == GET_ESID(unmapped_base)))
return; return;
if (is_kernel_addr(unmapped_base)) if (is_kernel_addr(unmapped_base))
......
...@@ -158,6 +158,18 @@ static unsigned int iic_get_irq(void) ...@@ -158,6 +158,18 @@ static unsigned int iic_get_irq(void)
return virq; return virq;
} }
void iic_setup_cpu(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
}
u8 iic_get_target_id(int cpu)
{
return per_cpu(iic, cpu).target_id;
}
EXPORT_SYMBOL_GPL(iic_get_target_id);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Use the highest interrupt priorities for IPI */ /* Use the highest interrupt priorities for IPI */
...@@ -166,29 +178,17 @@ static inline int iic_ipi_to_irq(int ipi) ...@@ -166,29 +178,17 @@ static inline int iic_ipi_to_irq(int ipi)
return IIC_IRQ_TYPE_IPI + 0xf - ipi; return IIC_IRQ_TYPE_IPI + 0xf - ipi;
} }
void iic_setup_cpu(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
}
void iic_cause_IPI(int cpu, int mesg) void iic_cause_IPI(int cpu, int mesg)
{ {
out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4); out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
} }
u8 iic_get_target_id(int cpu)
{
return per_cpu(iic, cpu).target_id;
}
EXPORT_SYMBOL_GPL(iic_get_target_id);
struct irq_host *iic_get_irq_host(int node) struct irq_host *iic_get_irq_host(int node)
{ {
return iic_host; return iic_host;
} }
EXPORT_SYMBOL_GPL(iic_get_irq_host); EXPORT_SYMBOL_GPL(iic_get_irq_host);
static irqreturn_t iic_ipi_action(int irq, void *dev_id) static irqreturn_t iic_ipi_action(int irq, void *dev_id)
{ {
int ipi = (int)(long)dev_id; int ipi = (int)(long)dev_id;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/rtas.h> #include <asm/rtas.h>
#include "interrupt.h" #include "interrupt.h"
#include <asm/udbg.h>
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/time.h>
#include <asm/spu_priv1.h> #include <asm/spu_priv1.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/of_platform.h> #include <asm/of_platform.h>
......
#ifndef _ISERIES_IRQ_H #ifndef _ISERIES_IRQ_H
#define _ISERIES_IRQ_H #define _ISERIES_IRQ_H
#ifdef CONFIG_PCI
extern void iSeries_init_IRQ(void); extern void iSeries_init_IRQ(void);
extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
extern void iSeries_activate_IRQs(void); extern void iSeries_activate_IRQs(void);
#else
#define iSeries_init_IRQ NULL
#endif
extern unsigned int iSeries_get_irq(void); extern unsigned int iSeries_get_irq(void);
#endif /* _ISERIES_IRQ_H */ #endif /* _ISERIES_IRQ_H */
...@@ -617,10 +617,6 @@ static void iseries_dedicated_idle(void) ...@@ -617,10 +617,6 @@ static void iseries_dedicated_idle(void)
} }
} }
#ifndef CONFIG_PCI
void __init iSeries_init_IRQ(void) { }
#endif
static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size, static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
unsigned long flags) unsigned long flags)
{ {
......
...@@ -523,15 +523,16 @@ static void __init get_viotape_info(struct device_node *vio_root) ...@@ -523,15 +523,16 @@ static void __init get_viotape_info(struct device_node *vio_root)
static int __init iseries_vio_init(void) static int __init iseries_vio_init(void)
{ {
struct device_node *vio_root; struct device_node *vio_root;
int ret = -ENODEV;
if (!firmware_has_feature(FW_FEATURE_ISERIES)) if (!firmware_has_feature(FW_FEATURE_ISERIES))
return -ENODEV; goto out;
iommu_vio_init(); iommu_vio_init();
vio_root = of_find_node_by_path("/vdevice"); vio_root = of_find_node_by_path("/vdevice");
if (!vio_root) if (!vio_root)
return -ENODEV; goto out;
if (viopath_hostLp == HvLpIndexInvalid) { if (viopath_hostLp == HvLpIndexInvalid) {
vio_set_hostlp(); vio_set_hostlp();
...@@ -544,10 +545,11 @@ static int __init iseries_vio_init(void) ...@@ -544,10 +545,11 @@ static int __init iseries_vio_init(void)
get_viocd_info(vio_root); get_viocd_info(vio_root);
get_viotape_info(vio_root); get_viotape_info(vio_root);
return 0; ret = 0;
put_node: put_node:
of_node_put(vio_root); of_node_put(vio_root);
return -ENODEV; out:
return ret;
} }
arch_initcall(iseries_vio_init); arch_initcall(iseries_vio_init);
...@@ -186,6 +186,11 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) ...@@ -186,6 +186,11 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
if (!dev) {
printk(KERN_WARNING "EEH: no PCI device for this of node\n");
return n;
}
/* Gather bridge-specific registers */ /* Gather bridge-specific registers */
if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg); rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
...@@ -198,7 +203,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) ...@@ -198,7 +203,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
} }
/* Dump out the PCI-X command and status regs */ /* Dump out the PCI-X command and status regs */
cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX); cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (cap) { if (cap) {
rtas_read_config(pdn, cap, 4, &cfg); rtas_read_config(pdn, cap, 4, &cfg);
n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
...@@ -210,7 +215,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) ...@@ -210,7 +215,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
} }
/* If PCI-E capable, dump PCI-E cap 10, and the AER */ /* If PCI-E capable, dump PCI-E cap 10, and the AER */
cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_EXP); cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (cap) { if (cap) {
n += scnprintf(buf+n, len-n, "pci-e cap10:\n"); n += scnprintf(buf+n, len-n, "pci-e cap10:\n");
printk(KERN_WARNING printk(KERN_WARNING
...@@ -222,7 +227,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) ...@@ -222,7 +227,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
} }
cap = pci_find_ext_capability(pdn->pcidev, PCI_EXT_CAP_ID_ERR); cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (cap) { if (cap) {
n += scnprintf(buf+n, len-n, "pci-e AER:\n"); n += scnprintf(buf+n, len-n, "pci-e AER:\n");
printk(KERN_WARNING printk(KERN_WARNING
...@@ -318,7 +323,7 @@ eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs) ...@@ -318,7 +323,7 @@ eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs)
if (rets[2] == 0) return -1; /* permanently unavailable */ if (rets[2] == 0) return -1; /* permanently unavailable */
if (max_wait_msecs <= 0) return -1; if (max_wait_msecs <= 0) break;
mwait = rets[2]; mwait = rets[2];
if (mwait <= 0) { if (mwait <= 0) {
......
...@@ -105,17 +105,18 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) ...@@ -105,17 +105,18 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
return; return;
rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc;
if (*res == PCI_ERS_RESULT_DISCONNECT &&
rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
} }
/** /**
* eeh_report_mmio_enabled - tell drivers that MMIO has been enabled * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
* *
* Report an EEH error to each device driver, collect up and * Tells each device driver that IO ports, MMIO and config space I/O
* merge the device driver responses. Cumulative response * are now enabled. Collects up and merges the device driver responses.
* passed back in "userdata". * Cumulative response passed back in "userdata".
*/ */
static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
...@@ -123,17 +124,16 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) ...@@ -123,17 +124,16 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
enum pci_ers_result rc, *res = userdata; enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver; struct pci_driver *driver = dev->driver;
// dev->error_state = pci_channel_mmio_enabled;
if (!driver || if (!driver ||
!driver->err_handler || !driver->err_handler ||
!driver->err_handler->mmio_enabled) !driver->err_handler->mmio_enabled)
return; return;
rc = driver->err_handler->mmio_enabled (dev); rc = driver->err_handler->mmio_enabled (dev);
/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc;
if (*res == PCI_ERS_RESULT_DISCONNECT &&
rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
} }
/** /**
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/udbg.h>
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)
......
...@@ -171,6 +171,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) ...@@ -171,6 +171,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
struct pci_dn *pdn; struct pci_dn *pdn;
int hwirq, virq, i, rc; int hwirq, virq, i, rc;
struct msi_desc *entry; struct msi_desc *entry;
struct msi_msg msg;
pdn = get_pdn(pdev); pdn = get_pdn(pdev);
if (!pdn) if (!pdn)
...@@ -213,6 +214,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) ...@@ -213,6 +214,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq); dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
set_irq_msi(virq, entry); set_irq_msi(virq, entry);
/* Read config space back so we can restore after reset */
read_msi_msg(virq, &msg);
entry->msg = msg;
unmask_msi_irq(virq); unmask_msi_irq(virq);
} }
......
...@@ -137,6 +137,7 @@ static void i8259_unmask_irq(unsigned int irq_nr) ...@@ -137,6 +137,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
static struct irq_chip i8259_pic = { static struct irq_chip i8259_pic = {
.typename = " i8259 ", .typename = " i8259 ",
.mask = i8259_mask_irq, .mask = i8259_mask_irq,
.disable = i8259_mask_irq,
.unmask = i8259_unmask_irq, .unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq, .mask_ack = i8259_mask_and_ack_irq,
}; };
......
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
#define MV64X60_VAL_LEN_MAX 11 #define MV64X60_VAL_LEN_MAX 11
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68 #define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, static ssize_t mv64x60_hs_reg_read(struct kobject *kobj,
size_t count) struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{ {
struct pci_dev *phb; struct pci_dev *phb;
u32 v; u32 v;
...@@ -44,8 +45,9 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, ...@@ -44,8 +45,9 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
return sprintf(buf, "0x%08x\n", v); return sprintf(buf, "0x%08x\n", v);
} }
static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, static ssize_t mv64x60_hs_reg_write(struct kobject *kobj,
size_t count) struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{ {
struct pci_dev *phb; struct pci_dev *phb;
u32 v; u32 v;
......
...@@ -244,6 +244,13 @@ syscall_exit_cont: ...@@ -244,6 +244,13 @@ syscall_exit_cont:
andis. r10,r0,DBCR0_IC@h andis. r10,r0,DBCR0_IC@h
bnel- load_dbcr0 bnel- load_dbcr0
#endif #endif
#ifdef CONFIG_44x
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
bne- 2f
1:
#endif /* CONFIG_44x */
stwcx. r0,0,r1 /* to clear the reservation */ stwcx. r0,0,r1 /* to clear the reservation */
lwz r4,_LINK(r1) lwz r4,_LINK(r1)
lwz r5,_CCR(r1) lwz r5,_CCR(r1)
...@@ -258,6 +265,12 @@ syscall_exit_cont: ...@@ -258,6 +265,12 @@ syscall_exit_cont:
mtspr SPRN_SRR1,r8 mtspr SPRN_SRR1,r8
SYNC SYNC
RFI RFI
#ifdef CONFIG_44x
2: li r7,0
iccci r0,r0
stw r7,icache_44x_need_flush@l(r4)
b 1b
#endif /* CONFIG_44x */
66: li r3,-ENOSYS 66: li r3,-ENOSYS
b ret_from_syscall b ret_from_syscall
...@@ -679,6 +692,16 @@ resume_kernel: ...@@ -679,6 +692,16 @@ resume_kernel:
/* interrupts are hard-disabled at this point */ /* interrupts are hard-disabled at this point */
restore: restore:
#ifdef CONFIG_44x
lis r4,icache_44x_need_flush@ha
lwz r5,icache_44x_need_flush@l(r4)
cmplwi cr0,r5,0
beq+ 1f
li r6,0
iccci r0,r0
stw r6,icache_44x_need_flush@l(r4)
1:
#endif /* CONFIG_44x */
lwz r0,GPR0(r1) lwz r0,GPR0(r1)
lwz r2,GPR2(r1) lwz r2,GPR2(r1)
REST_4GPRS(3, r1) REST_4GPRS(3, r1)
......
...@@ -224,7 +224,16 @@ _GLOBAL(_tlbia) ...@@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
*/ */
_GLOBAL(_tlbie) _GLOBAL(_tlbie)
#if defined(CONFIG_40x) #if defined(CONFIG_40x)
/* We run the search with interrupts disabled because we have to change
* the PID and I don't want to preempt when that happens.
*/
mfmsr r5
mfspr r6,SPRN_PID
wrteei 0
mtspr SPRN_PID,r4
tlbsx. r3, 0, r3 tlbsx. r3, 0, r3
mtspr SPRN_PID,r6
wrtee r5
bne 10f bne 10f
sync sync
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
...@@ -234,22 +243,21 @@ _GLOBAL(_tlbie) ...@@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
isync isync
10: 10:
#elif defined(CONFIG_44x) #elif defined(CONFIG_44x)
mfspr r4,SPRN_MMUCR mfspr r5,SPRN_MMUCR
mfspr r5,SPRN_PID /* Get PID */ rlwimi r5,r4,0,24,31 /* Set TID */
rlwimi r4,r5,0,24,31 /* Set TID */
/* We have to run the search with interrupts disabled, even critical /* We have to run the search with interrupts disabled, even critical
* and debug interrupts (in fact the only critical exceptions we have * and debug interrupts (in fact the only critical exceptions we have
* are debug and machine check). Otherwise an interrupt which causes * are debug and machine check). Otherwise an interrupt which causes
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
mfmsr r5 mfmsr r4
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
andc r6,r5,r6 andc r6,r4,r6
mtmsr r6 mtmsr r6
mtspr SPRN_MMUCR,r4 mtspr SPRN_MMUCR,r5
tlbsx. r3, 0, r3 tlbsx. r3, 0, r3
mtmsr r5 mtmsr r4
bne 10f bne 10f
sync sync
/* There are only 64 TLB entries, so r3 < 64, /* There are only 64 TLB entries, so r3 < 64,
...@@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) ...@@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
addi r3,r3,L1_CACHE_BYTES addi r3,r3,L1_CACHE_BYTES
bdnz 0b bdnz 0b
sync sync
#ifndef CONFIG_44x
/* We don't flush the icache on 44x. Those have a virtual icache
* and we don't have access to the virtual address here (it's
* not the page vaddr but where it's mapped in user space). The
* flushing of the icache on these is handled elsewhere, when
* a change in the address space occurs, before returning to
* user space
*/
mtctr r4 mtctr r4
1: icbi 0,r6 1: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES addi r6,r6,L1_CACHE_BYTES
bdnz 1b bdnz 1b
sync sync
isync isync
#endif /* CONFIG_44x */
blr blr
/* /*
......
...@@ -61,6 +61,7 @@ extern char etext[], _stext[]; ...@@ -61,6 +61,7 @@ extern char etext[], _stext[];
*/ */
unsigned int tlb_44x_index = 0; unsigned int tlb_44x_index = 0;
unsigned int tlb_44x_hwater = 62; unsigned int tlb_44x_hwater = 62;
int icache_44x_need_flush;
/* /*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
......
...@@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void)
v = KERNELBASE; v = KERNELBASE;
p = PPC_MEMSTART; p = PPC_MEMSTART;
s = 0; s = total_lowmem;
if (__map_without_ltlbs) { if (__map_without_ltlbs)
return s; return 0;
}
while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) { while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp; pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE; unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
...@@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_16M; v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M; p += LARGE_PAGE_SIZE_16M;
s += LARGE_PAGE_SIZE_16M; s -= LARGE_PAGE_SIZE_16M;
} }
while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) { while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp; pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE; unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
...@@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void) ...@@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_4M; v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M; p += LARGE_PAGE_SIZE_4M;
s += LARGE_PAGE_SIZE_4M; s -= LARGE_PAGE_SIZE_4M;
} }
return s; return total_lowmem - s;
} }
...@@ -227,7 +227,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -227,7 +227,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
set_bit(PG_arch_1, &page->flags); set_bit(PG_arch_1, &page->flags);
} }
pte_update(ptep, 0, _PAGE_HWEXEC); pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address); _tlbie(address, mm->context.id);
pte_unmap_unlock(ptep, ptl); pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return 0; return 0;
......
...@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries; ...@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
#define mmu_mapin_ram() (0UL) #define mmu_mapin_ram() (0UL)
#elif defined(CONFIG_4xx) #elif defined(CONFIG_4xx)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void); extern unsigned long mmu_mapin_ram(void);
#elif defined(CONFIG_FSL_BOOKE) #elif defined(CONFIG_FSL_BOOKE)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void); extern unsigned long mmu_mapin_ram(void);
extern void adjust_total_lowmem(void); extern void adjust_total_lowmem(void);
......
...@@ -236,7 +236,7 @@ ebony_early_serial_map(void) ...@@ -236,7 +236,7 @@ ebony_early_serial_map(void)
gen550_init(0, &port); gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */ /* Purge TLB entry added in head_44x.S for early serial access */
_tlbie(UART0_IO_BASE); _tlbie(UART0_IO_BASE, 0);
#endif #endif
port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
......
...@@ -230,9 +230,14 @@ luan_setup_hoses(void) ...@@ -230,9 +230,14 @@ luan_setup_hoses(void)
/* Allocate hoses for PCIX1 and PCIX2 */ /* Allocate hoses for PCIX1 and PCIX2 */
hose1 = pcibios_alloc_controller(); hose1 = pcibios_alloc_controller();
if (!hose1)
return;
hose2 = pcibios_alloc_controller(); hose2 = pcibios_alloc_controller();
if (!hose1 || !hose2) if (!hose2) {
pcibios_free_controller(hose1);
return; return;
}
/* Setup PCIX1 */ /* Setup PCIX1 */
hose1->first_busno = 0; hose1->first_busno = 0;
......
...@@ -259,7 +259,7 @@ ocotea_early_serial_map(void) ...@@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
gen550_init(0, &port); gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */ /* Purge TLB entry added in head_44x.S for early serial access */
_tlbie(UART0_IO_BASE); _tlbie(UART0_IO_BASE, 0);
#endif #endif
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
......
...@@ -316,7 +316,7 @@ taishan_early_serial_map(void) ...@@ -316,7 +316,7 @@ taishan_early_serial_map(void)
gen550_init(0, &port); gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */ /* Purge TLB entry added in head_44x.S for early serial access */
_tlbie(UART0_IO_BASE); _tlbie(UART0_IO_BASE, 0);
#endif #endif
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
......
...@@ -127,6 +127,7 @@ static void i8259_unmask_irq(unsigned int irq_nr) ...@@ -127,6 +127,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
static struct irq_chip i8259_pic = { static struct irq_chip i8259_pic = {
.typename = " i8259 ", .typename = " i8259 ",
.mask = i8259_mask_irq, .mask = i8259_mask_irq,
.disable = i8259_mask_irq,
.unmask = i8259_unmask_irq, .unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq, .mask_ack = i8259_mask_and_ack_irq,
}; };
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/ppc_sys.h>
#include "cpm2_pic.h" #include "cpm2_pic.h"
...@@ -61,7 +62,7 @@ m8260_setup_arch(void) ...@@ -61,7 +62,7 @@ m8260_setup_arch(void)
#endif #endif
identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME, identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET)); in_be32((void *)CPM_MAP_ADDR + CPM_IMMR_OFFSET));
m82xx_board_setup(); m82xx_board_setup();
} }
...@@ -147,12 +148,12 @@ m8260_show_cpuinfo(struct seq_file *m) ...@@ -147,12 +148,12 @@ m8260_show_cpuinfo(struct seq_file *m)
seq_printf(m, "vendor\t\t: %s\n" seq_printf(m, "vendor\t\t: %s\n"
"machine\t\t: %s\n" "machine\t\t: %s\n"
"\n" "\n"
"mem size\t\t: 0x%08x\n" "mem size\t\t: 0x%08lx\n"
"console baud\t\t: %d\n" "console baud\t\t: %ld\n"
"\n" "\n"
"core clock\t: %u MHz\n" "core clock\t: %lu MHz\n"
"CPM clock\t: %u MHz\n" "CPM clock\t: %lu MHz\n"
"bus clock\t: %u MHz\n", "bus clock\t: %lu MHz\n",
CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize, CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
bp->bi_baudrate, bp->bi_intfreq / 1000000, bp->bi_baudrate, bp->bi_intfreq / 1000000,
bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000); bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
......
...@@ -94,7 +94,9 @@ static int wf_thread_func(void *data) ...@@ -94,7 +94,9 @@ static int wf_thread_func(void *data)
DBG("wf: thread started\n"); DBG("wf: thread started\n");
set_freezable(); set_freezable();
while(!kthread_should_stop()) { while (!kthread_should_stop()) {
try_to_freeze();
if (time_after_eq(jiffies, next)) { if (time_after_eq(jiffies, next)) {
wf_notify(WF_EVENT_TICK, NULL); wf_notify(WF_EVENT_TICK, NULL);
if (wf_overtemp) { if (wf_overtemp) {
...@@ -116,12 +118,6 @@ static int wf_thread_func(void *data) ...@@ -116,12 +118,6 @@ static int wf_thread_func(void *data)
delay = next - jiffies; delay = next - jiffies;
if (delay <= HZ) if (delay <= HZ)
schedule_timeout_interruptible(delay); schedule_timeout_interruptible(delay);
/* there should be no non-suspend signal, but oh well */
if (signal_pending(current) && !try_to_freeze()) {
printk(KERN_WARNING "windfarm: thread got sigl !\n");
break;
}
} }
DBG("wf: thread stopped\n"); DBG("wf: thread stopped\n");
......
...@@ -329,12 +329,14 @@ static struct uart_ops ulite_ops = { ...@@ -329,12 +329,14 @@ static struct uart_ops ulite_ops = {
static void ulite_console_wait_tx(struct uart_port *port) static void ulite_console_wait_tx(struct uart_port *port)
{ {
int i; int i;
u8 val;
/* wait up to 10ms for the character(s) to be sent */ /* Spin waiting for TX fifo to have space available */
for (i = 0; i < 10000; i++) { for (i = 0; i < 100000; i++) {
if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) val = readb(port->membase + ULITE_STATUS);
if ((val & ULITE_STATUS_TXFULL) == 0)
break; break;
udelay(1); cpu_relax();
} }
} }
......
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
extern unsigned long va_to_phys(unsigned long address); extern unsigned long va_to_phys(unsigned long address);
extern pte_t *va_to_pte(unsigned long address); extern pte_t *va_to_pte(unsigned long address);
extern unsigned long ioremap_bot, ioremap_base; extern unsigned long ioremap_bot, ioremap_base;
#ifdef CONFIG_44x
extern int icache_44x_need_flush;
#endif
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
/* /*
...@@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, ...@@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
: "=&r" (old), "=&r" (tmp), "=m" (*p) : "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" (clr), "r" (set), "m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p)
: "cc" ); : "cc" );
#ifdef CONFIG_44x
if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
icache_44x_need_flush = 1;
#endif
return old; return old;
} }
#else #else
...@@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr, ...@@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
: "=&r" (old), "=&r" (tmp), "=m" (*p) : "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
: "cc" ); : "cc" );
#ifdef CONFIG_44x
if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
icache_44x_need_flush = 1;
#endif
return old; return old;
} }
#endif #endif
......
...@@ -308,8 +308,8 @@ COMPAT_SYS_SPU(move_pages) ...@@ -308,8 +308,8 @@ COMPAT_SYS_SPU(move_pages)
SYSCALL_SPU(getcpu) SYSCALL_SPU(getcpu)
COMPAT_SYS(epoll_pwait) COMPAT_SYS(epoll_pwait)
COMPAT_SYS_SPU(utimensat) COMPAT_SYS_SPU(utimensat)
COMPAT_SYS(fallocate)
COMPAT_SYS_SPU(signalfd) COMPAT_SYS_SPU(signalfd)
COMPAT_SYS_SPU(timerfd) COMPAT_SYS_SPU(timerfd)
SYSCALL_SPU(eventfd) SYSCALL_SPU(eventfd)
COMPAT_SYS_SPU(sync_file_range2) COMPAT_SYS_SPU(sync_file_range2)
COMPAT_SYS(fallocate)
...@@ -176,25 +176,31 @@ static inline unsigned int get_dec(void) ...@@ -176,25 +176,31 @@ static inline unsigned int get_dec(void)
#endif #endif
} }
/*
* Note: Book E and 4xx processors differ from other PowerPC processors
* in when the decrementer generates its interrupt: on the 1 to 0
* transition for Book E/4xx, but on the 0 to -1 transition for others.
*/
static inline void set_dec(int val) static inline void set_dec(int val)
{ {
#if defined(CONFIG_40x) #if defined(CONFIG_40x)
mtspr(SPRN_PIT, val); mtspr(SPRN_PIT, val);
#elif defined(CONFIG_8xx_CPU6) #elif defined(CONFIG_8xx_CPU6)
set_dec_cpu6(val); set_dec_cpu6(val - 1);
#else #else
#ifndef CONFIG_BOOKE
--val;
#endif
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
int cur_dec;
if (firmware_has_feature(FW_FEATURE_ISERIES) && if (firmware_has_feature(FW_FEATURE_ISERIES) &&
get_lppaca()->shared_proc) { get_lppaca()->shared_proc) {
get_lppaca()->virtual_decr = val; get_lppaca()->virtual_decr = val;
cur_dec = get_dec(); if (get_dec() > val)
if (cur_dec > val)
HvCall_setVirtualDecr(); HvCall_setVirtualDecr();
} else return;
}
#endif #endif
mtspr(SPRN_DEC, val); mtspr(SPRN_DEC, val);
#endif /* not 40x or 8xx_CPU6 */ #endif /* not 40x or 8xx_CPU6 */
} }
......
#ifndef _ASM_POWERPC_TLBFLUSH_H #ifndef _ASM_POWERPC_TLBFLUSH_H
#define _ASM_POWERPC_TLBFLUSH_H #define _ASM_POWERPC_TLBFLUSH_H
/* /*
* TLB flushing: * TLB flushing:
* *
...@@ -16,9 +17,6 @@ ...@@ -16,9 +17,6 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
struct mm_struct;
struct vm_area_struct;
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE) #if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
/* /*
* TLB flushing for software loaded TLB chips * TLB flushing for software loaded TLB chips
...@@ -28,7 +26,9 @@ struct vm_area_struct; ...@@ -28,7 +26,9 @@ struct vm_area_struct;
* specific tlbie's * specific tlbie's
*/ */
extern void _tlbie(unsigned long address); #include <linux/mm.h>
extern void _tlbie(unsigned long address, unsigned int pid);
#if defined(CONFIG_40x) || defined(CONFIG_8xx) #if defined(CONFIG_40x) || defined(CONFIG_8xx)
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory") #define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
...@@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct mm_struct *mm) ...@@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
static inline void flush_tlb_page(struct vm_area_struct *vma, static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr) unsigned long vmaddr)
{ {
_tlbie(vmaddr); _tlbie(vmaddr, vma->vm_mm->context.id);
} }
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr) unsigned long vmaddr)
{ {
_tlbie(vmaddr); _tlbie(vmaddr, vma->vm_mm->context.id);
} }
static inline void flush_tlb_range(struct vm_area_struct *vma, static inline void flush_tlb_range(struct vm_area_struct *vma,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment