* Re: [PATCH] powerpc: Kill machine numbers
From: Arnd Bergmann @ 2006-03-24 9:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <1143178947.4257.78.camel@localhost.localdomain>
On Friday 24 March 2006 06:42, Benjamin Herrenschmidt wrote:
> - if (strstr(p, RELOC("IBM,CPB")))
> - return PLATFORM_CELL;
> +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> +{
> + const char* cp;
> + unsigned long cplen, l;
> +
> + cp = of_get_flat_dt_prop(node, "compatible", &cplen);
> + if (cp == NULL)
> + return 0;
> + while (cplen > 0) {
> + if (strncasecmp(cp, compat, strlen(compat)) == 0)
> + return 1;
> + l = strlen(cp) + 1;
> + cp += l;
> + cplen -= l;
> + }
> +
> + return 0;
> +}
> +static int __init cell_probe(void)
> {
> - if (platform != PLATFORM_CELL)
> + unsigned long root = of_get_flat_dt_root();
> + if (!of_flat_dt_is_compatible(root, "IBM,CPB"))
> return 0;
>
Unfortunately, this breaks cell detection. The string in our current
hardware is 'IBM,CPBW-1.0', for reasons you don't want to know.
We just relied on strstr being able to scan for everything starting
with 'IBM,CPB'.
For even more obscure reasons, our future firmware is planned
to no no longer claim compatibility with that but rather with
'CBEA' _and_ 'IBM,CBEA'.
At this point, the issue is getting really complicated, as CBEA
was meant to be a generic identifier for all systems based on
that architecture extension, but we probably want to have different
machine_description data for e.g. IBM and Sony hardware, so they
should check for different values.
As soon as I get to the office, I'll try to do a patch that at
least
- restores the current functionality by checking for 'IBM,CPBW-1.0'
- also checks for 'IBM,CBEA' so we don't break on future IBM systems
but we should make sure we come to a solution that is practical
to all system vendors that are participating in Linux support.
Arnd <><
^ permalink raw reply
* [PATCH] powerpc: Unify the 32 and 64 bit idle loops
From: Paul Mackerras @ 2006-03-24 9:54 UTC (permalink / raw)
To: linuxppc-dev
This unifies the 32-bit (ARCH=ppc and ARCH=powerpc) and 64-bit idle
loops. It brings over the concept of having a ppc_md.power_save
function from 32-bit to ARCH=powerpc, which lets us get rid of
native_idle(). With that, we can also reduce the amount of special
code for pSeries and cell because the special code has only to do what
needs to be done when there is no work to do, rather than being a
complete idle loop.
iSeries still has its own idle loops because it wants to test
hvlpevents_pending() as well as need_resched() etc. I don't know if
that is essential but I have left it as-is for now.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 80e9fe2..f2c47e9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -10,16 +10,16 @@ CFLAGS_prom_init.o += -fPIC
CFLAGS_btext.o += -fPIC
endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
irq.o align.o signal_32.o pmc.o vdso.o \
- init_task.o process.o systbl.o
+ init_task.o process.o systbl.o idle.o
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o cpu_setup_power4.o \
- firmware.o sysfs.o idle_64.o
+ firmware.o sysfs.o
obj-$(CONFIG_PPC64) += vdso64/
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_POWER4) += idle_power4.o
obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
procfs-$(CONFIG_PPC64) := proc_ppc64.o
@@ -32,10 +32,11 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_IBMEBUS) += ibmebus.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_6xx) += idle_6xx.o
ifeq ($(CONFIG_PPC_MERGE),y)
extra-$(CONFIG_PPC_STD_MMU) := head_32.o
extra-$(CONFIG_PPC64) := head_64.o
@@ -49,11 +50,10 @@ obj-y += time.o prom.o traps.o setup-
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
-obj-$(CONFIG_6xx) += idle_6xx.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4827ca1..b3a9794 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -133,14 +133,14 @@ transfer_to_handler:
*/
#ifdef CONFIG_6xx
mfspr r11,SPRN_HID0
mtcr r11
BEGIN_FTR_SECTION
- bt- 8,power_save_6xx_restore /* Check DOZE */
+ bt- 8,4f /* Check DOZE */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
BEGIN_FTR_SECTION
- bt- 9,power_save_6xx_restore /* Check NAP */
+ bt- 9,4f /* Check NAP */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
transfer_to_handler_cont:
lwz r11,THREAD_INFO-THREAD(r12)
@@ -155,10 +155,14 @@ transfer_to_handler_cont:
mtspr SPRN_SRR1,r10
mtlr r9
SYNC
RFI /* jump to handler, enable MMU */
+#ifdef CONFIG_6xx
+4: b power_save_6xx_restore
+#endif
+
/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
*/
stack_ovf:
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
new file mode 100644
index 0000000..e9f321d
--- /dev/null
+++ b/arch/powerpc/kernel/idle.c
@@ -0,0 +1,122 @@
+/*
+ * Idle daemon for PowerPC. Idle daemon will handle any action
+ * that needs to be taken when the system becomes idle.
+ *
+ * Originally written by Cort Dougan (cort@cs.nmt.edu).
+ * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
+ * Paul Mackerras and others.
+ *
+ * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
+ *
+ * Additional shared processor, SMT, and firmware support
+ * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ *
+ * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
+ *
+ * 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/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/cpu.h>
+#include <linux/sysctl.h>
+
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/smp.h>
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
+ system_state == SYSTEM_RUNNING)
+#else
+#define cpu_should_die() 0
+#endif
+
+/*
+ * The body of the idle task.
+ */
+void cpu_idle(void)
+{
+ if (ppc_md.idle_loop)
+ ppc_md.idle_loop(); /* doesn't return */
+
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ while (1) {
+ ppc64_runlatch_off();
+
+ while (!need_resched() && !cpu_should_die()) {
+ if (ppc_md.power_save) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ /*
+ * smp_mb is so clearing of TIF_POLLING_NRFLAG
+ * is ordered w.r.t. need_resched() test.
+ */
+ smp_mb();
+ local_irq_disable();
+
+ /* check again after disabling irqs */
+ if (!need_resched() && !cpu_should_die())
+ ppc_md.power_save();
+
+ local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
+ } else {
+ /*
+ * Go into low thread priority and possibly
+ * low power mode.
+ */
+ HMT_low();
+ HMT_very_low();
+ }
+ }
+
+ HMT_medium();
+ ppc64_runlatch_on();
+ if (cpu_should_die())
+ cpu_die();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+int powersave_nap;
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Register the sysctl to set/clear powersave_nap.
+ */
+static ctl_table powersave_nap_ctl_table[]={
+ {
+ .ctl_name = KERN_PPC_POWERSAVE_NAP,
+ .procname = "powersave-nap",
+ .data = &powersave_nap,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ { 0, },
+};
+static ctl_table powersave_nap_sysctl_root[] = {
+ { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
+ { 0,},
+};
+
+static int __init
+register_powersave_nap_sysctl(void)
+{
+ register_sysctl_table(powersave_nap_sysctl_root, 0);
+
+ return 0;
+}
+__initcall(register_powersave_nap_sysctl);
+#endif
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle_64.c
deleted file mode 100644
index b879d30..0000000
--- a/arch/powerpc/kernel/idle_64.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Idle daemon for PowerPC. Idle daemon will handle any action
- * that needs to be taken when the system becomes idle.
- *
- * Originally Written by Cort Dougan (cort@cs.nmt.edu)
- *
- * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
- *
- * Additional shared processor, SMT, and firmware support
- * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
- *
- * 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/config.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-#include <linux/sysctl.h>
-
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/smp.h>
-
-extern void power4_idle(void);
-
-void default_idle(void)
-{
- unsigned int cpu = smp_processor_id();
- set_thread_flag(TIF_POLLING_NRFLAG);
-
- while (1) {
- if (!need_resched()) {
- while (!need_resched() && !cpu_is_offline(cpu)) {
- ppc64_runlatch_off();
-
- /*
- * Go into low thread priority and possibly
- * low power mode.
- */
- HMT_low();
- HMT_very_low();
- }
-
- HMT_medium();
- }
-
- ppc64_runlatch_on();
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
- cpu_die();
- }
-}
-
-void native_idle(void)
-{
- while (1) {
- ppc64_runlatch_off();
-
- if (!need_resched())
- power4_idle();
-
- if (need_resched()) {
- ppc64_runlatch_on();
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
-
- if (cpu_is_offline(smp_processor_id()) &&
- system_state == SYSTEM_RUNNING)
- cpu_die();
- }
-}
-
-void cpu_idle(void)
-{
- BUG_ON(NULL == ppc_md.idle_loop);
- ppc_md.idle_loop();
-}
-
-int powersave_nap;
-
-#ifdef CONFIG_SYSCTL
-/*
- * Register the sysctl to set/clear powersave_nap.
- */
-static ctl_table powersave_nap_ctl_table[]={
- {
- .ctl_name = KERN_PPC_POWERSAVE_NAP,
- .procname = "powersave-nap",
- .data = &powersave_nap,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- { 0, },
-};
-static ctl_table powersave_nap_sysctl_root[] = {
- { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
- { 0,},
-};
-
-static int __init
-register_powersave_nap_sysctl(void)
-{
- register_sysctl_table(powersave_nap_sysctl_root, 0);
-
- return 0;
-}
-__initcall(register_powersave_nap_sysctl);
-#endif
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 444fdcc..1647ea3 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -85,23 +85,10 @@ BEGIN_FTR_SECTION
1:
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
cmpwi 0,r3,0
beqlr
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Check current_thread_info()->flags */
- rlwinm r4,r1,0,0,18
- lwz r4,TI_FLAGS(r4)
- andi. r0,r4,_TIF_NEED_RESCHED
- beq 1f
- mtmsr r7 /* out of line this ? */
- blr
-1:
/* Some pre-nap cleanups needed on some CPUs */
andis. r0,r3,HID0_NAP@h
beq 2f
BEGIN_FTR_SECTION
/* Disable L2 prefetch on some 745x and try to ensure
@@ -218,12 +205,10 @@ _GLOBAL(nap_save_msscr0)
.space 4*NR_CPUS
_GLOBAL(nap_save_hid1)
.space 4*NR_CPUS
-_GLOBAL(powersave_nap)
- .long 0
_GLOBAL(powersave_lowspeed)
.long 0
#ifdef DEBUG
_GLOBAL(nap_enter_count)
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index c16b4af..692cf2e 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -47,25 +47,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
LOAD_REG_ADDRBASE(r3,powersave_nap)
lwz r4,ADDROFF(powersave_nap)(r3)
cmpwi 0,r4,0
beqlr
- /* Clear MSR:EE */
- mfmsr r7
- li r4,0
- ori r4,r4,MSR_EE
- andc r0,r7,r4
- mtmsrd r0
-
- /* Check current_thread_info()->flags */
- clrrdi r4,r1,THREAD_SHIFT
- ld r4,TI_FLAGS(r4)
- andi. r0,r4,_TIF_NEED_RESCHED
- beq 1f
- mtmsrd r7 /* out of line this ? */
- blr
-1:
/* Go to NAP now */
BEGIN_FTR_SECTION
DSSALL
sync
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index db72a92..791edcd 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -51,13 +51,10 @@
#endif
extern void platform_init(void);
extern void bootx_init(unsigned long r4, unsigned long phys);
-extern void ppc6xx_idle(void);
-extern void power4_idle(void);
-
boot_infos_t *boot_infos;
struct ide_machdep_calls ppc_ide_md;
int boot_cpuid;
EXPORT_SYMBOL_GPL(boot_cpuid);
@@ -192,11 +189,13 @@ void __init machine_init(unsigned long d
/* Base init based on machine type */
platform_init();
#ifdef CONFIG_6xx
- ppc_md.power_save = ppc6xx_idle;
+ if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
+ cpu_has_feature(CPU_FTR_CAN_NAP))
+ ppc_md.power_save = ppc6xx_idle;
#endif
if (ppc_md.progress)
ppc_md.progress("id mach(): done", 0x200);
}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2f3fdad..f47b3cc 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -599,16 +599,10 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
ppc_md.setup_arch();
- /* Use the default idle loop if the platform hasn't provided one. */
- if (NULL == ppc_md.idle_loop) {
- ppc_md.idle_loop = default_idle;
- printk(KERN_INFO "Using default idle loop\n");
- }
-
paging_init();
ppc64_boot_msg(0x15, "Setup Done");
}
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index e0e051c..07f0c33 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -98,50 +98,33 @@ static void __init cbe_enable_pause_zero
out:
spin_unlock_irq(&cbe_pervasive_lock);
}
-static void cbe_idle(void)
+static void cbe_idle_sleep(void)
{
unsigned long ctrl;
cbe_enable_pause_zero();
- while (1) {
- if (!need_resched()) {
- local_irq_disable();
- while (!need_resched()) {
- /* go into low thread priority */
- HMT_low();
-
- /*
- * atomically disable thread execution
- * and runlatch.
- * External and Decrementer exceptions
- * are still handled when the thread
- * is disabled but now enter in
- * cbe_system_reset_exception()
- */
- ctrl = mfspr(SPRN_CTRLF);
- ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
- mtspr(SPRN_CTRLT, ctrl);
- }
- /* restore thread prio */
- HMT_medium();
- local_irq_enable();
- }
+ /* go into low thread priority */
+ HMT_low();
- /*
- * turn runlatch on again before scheduling the
- * process we just woke up
- */
- ppc64_runlatch_on();
-
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
+ /*
+ * atomically disable thread execution
+ * and runlatch.
+ * External and Decrementer exceptions
+ * are still handled when the thread
+ * is disabled but now enter in
+ * cbe_system_reset_exception()
+ */
+ ctrl = mfspr(SPRN_CTRLF);
+ ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
+ mtspr(SPRN_CTRLT, ctrl);
+
+ /* restore thread prio */
+ HMT_medium();
}
static int cbe_system_reset_exception(struct pt_regs *regs)
{
switch (regs->msr & SRR1_WAKEMASK) {
@@ -222,8 +205,8 @@ void __init cell_pervasive_init(void)
ret = cbe_find_pmd_mmio(cpu, p);
if (ret)
return;
}
- ppc_md.idle_loop = cbe_idle;
+ ppc_md.power_save = cbe_idle_sleep;
ppc_md.system_reset_exception = cbe_system_reset_exception;
}
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ec5c1e1..137d606 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -288,11 +288,11 @@ struct machdep_calls __initdata maple_md
.get_boot_time = maple_get_boot_time,
.set_rtc_time = maple_set_rtc_time,
.get_rtc_time = maple_get_rtc_time,
.calibrate_decr = generic_calibrate_decr,
.progress = maple_progress,
- .idle_loop = native_idle,
+ .power_save = power4_idle,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
.machine_crash_shutdown = default_machine_crash_shutdown,
#endif
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 385aab9..c2696d0 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -731,11 +731,11 @@ struct machdep_calls __initdata pmac_md
.feature_call = pmac_do_feature_call,
.check_legacy_ioport = pmac_check_legacy_ioport,
.progress = udbg_progress,
#ifdef CONFIG_PPC64
.pci_probe_mode = pmac_pci_probe_mode,
- .idle_loop = native_idle,
+ .power_save = power4_idle,
.enable_pmcs = power4_enable_pmcs,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
.machine_crash_shutdown = default_machine_crash_shutdown,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 44d5c7f..213bf98 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -79,12 +79,12 @@
extern void find_udbg_vterm(void);
int fwnmi_active; /* TRUE if an FWNMI handler is present */
-static void pseries_shared_idle(void);
-static void pseries_dedicated_idle(void);
+static void pseries_shared_idle_sleep(void);
+static void pseries_dedicated_idle_sleep(void);
struct mpic *pSeries_mpic;
static void pSeries_show_cpuinfo(struct seq_file *m)
{
@@ -234,18 +234,17 @@ static void __init pSeries_setup_arch(vo
/* Choose an idle loop */
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
vpa_init(boot_cpuid);
if (get_lppaca()->shared_proc) {
printk(KERN_INFO "Using shared processor idle loop\n");
- ppc_md.idle_loop = pseries_shared_idle;
+ ppc_md.power_save = pseries_shared_idle_sleep;
} else {
printk(KERN_INFO "Using dedicated idle loop\n");
- ppc_md.idle_loop = pseries_dedicated_idle;
+ ppc_md.power_save = pseries_dedicated_idle_sleep;
}
} else {
printk(KERN_INFO "Using default idle loop\n");
- ppc_md.idle_loop = default_idle;
}
if (firmware_has_feature(FW_FEATURE_LPAR))
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
else
@@ -391,140 +390,91 @@ static int __init pSeries_probe(int plat
return 1;
}
DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
-static inline void dedicated_idle_sleep(unsigned int cpu)
-{
- struct lppaca *plppaca = &lppaca[cpu ^ 1];
-
- /* Only sleep if the other thread is not idle */
- if (!(plppaca->idle)) {
- local_irq_disable();
-
- /*
- * We are about to sleep the thread and so wont be polling any
- * more.
- */
- clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb__after_clear_bit();
-
- /*
- * SMT dynamic mode. Cede will result in this thread going
- * dormant, if the partner thread is still doing work. Thread
- * wakes up if partner goes idle, an interrupt is presented, or
- * a prod occurs. Returning from the cede enables external
- * interrupts.
- */
- if (!need_resched())
- cede_processor();
- else
- local_irq_enable();
- set_thread_flag(TIF_POLLING_NRFLAG);
- } else {
- /*
- * Give the HV an opportunity at the processor, since we are
- * not doing any work.
- */
- poll_pending();
- }
-}
-
-static void pseries_dedicated_idle(void)
+static void pseries_dedicated_idle_sleep(void)
{
unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
- set_thread_flag(TIF_POLLING_NRFLAG);
- while (1) {
- /*
- * Indicate to the HV that we are idle. Now would be
- * a good time to find other work to dispatch.
- */
- get_lppaca()->idle = 1;
-
- if (!need_resched()) {
- start_snooze = get_tb() +
- *smt_snooze_delay * tb_ticks_per_usec;
-
- while (!need_resched() && !cpu_is_offline(cpu)) {
- ppc64_runlatch_off();
-
- /*
- * Go into low thread priority and possibly
- * low power mode.
- */
- HMT_low();
- HMT_very_low();
-
- if (*smt_snooze_delay != 0 &&
- get_tb() > start_snooze) {
- HMT_medium();
- dedicated_idle_sleep(cpu);
- }
+ /*
+ * Indicate to the HV that we are idle. Now would be
+ * a good time to find other work to dispatch.
+ */
+ get_lppaca()->idle = 1;
- }
+ /*
+ * We come in with interrupts disabled, and need_resched()
+ * has been checked recently. If we should poll for a little
+ * while, do so.
+ */
+ if (*smt_snooze_delay) {
+ start_snooze = get_tb() +
+ *smt_snooze_delay * tb_ticks_per_usec;
+ local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
- HMT_medium();
+ while (get_tb() < start_snooze) {
+ if (need_resched() || cpu_is_offline(cpu))
+ goto out;
+ ppc64_runlatch_off();
+ HMT_low();
+ HMT_very_low();
}
- get_lppaca()->idle = 0;
- ppc64_runlatch_on();
+ HMT_medium();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb();
+ local_irq_disable();
+ if (need_resched() || cpu_is_offline(cpu))
+ goto out;
+ }
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
+ /*
+ * Cede if the other thread is not idle, so that it can
+ * go single-threaded. If the other thread is idle,
+ * we ask the hypervisor if it has pending work it
+ * wants to do and cede if it does. Otherwise we keep
+ * polling in order to reduce interrupt latency.
+ *
+ * Doing the cede when the other thread is active will
+ * result in this thread going dormant, meaning the other
+ * thread gets to run in single-threaded (ST) mode, which
+ * is slightly faster than SMT mode with this thread at
+ * very low priority. The cede enables interrupts, which
+ * doesn't matter here.
+ */
+ if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending)
+ cede_processor();
- if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
- cpu_die();
- }
+out:
+ HMT_medium();
+ get_lppaca()->idle = 0;
}
-static void pseries_shared_idle(void)
+static void pseries_shared_idle_sleep(void)
{
unsigned int cpu = smp_processor_id();
- while (1) {
- /*
- * Indicate to the HV that we are idle. Now would be
- * a good time to find other work to dispatch.
- */
- get_lppaca()->idle = 1;
-
- while (!need_resched() && !cpu_is_offline(cpu)) {
- local_irq_disable();
- ppc64_runlatch_off();
-
- /*
- * Yield the processor to the hypervisor. We return if
- * an external interrupt occurs (which are driven prior
- * to returning here) or if a prod occurs from another
- * processor. When returning here, external interrupts
- * are enabled.
- *
- * Check need_resched() again with interrupts disabled
- * to avoid a race.
- */
- if (!need_resched())
- cede_processor();
- else
- local_irq_enable();
-
- HMT_medium();
- }
-
- get_lppaca()->idle = 0;
- ppc64_runlatch_on();
+ /*
+ * Indicate to the HV that we are idle. Now would be
+ * a good time to find other work to dispatch.
+ */
+ get_lppaca()->idle = 1;
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
+ /*
+ * Yield the processor to the hypervisor. We return if
+ * an external interrupt occurs (which are driven prior
+ * to returning here) or if a prod occurs from another
+ * processor. When returning here, external interrupts
+ * are enabled.
+ */
+ cede_processor();
- if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
- cpu_die();
- }
+ get_lppaca()->idle = 0;
}
static int pSeries_pci_probe_mode(struct pci_bus *bus)
{
if (firmware_has_feature(FW_FEATURE_LPAR))
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 98e940b..e6154b6 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -57,12 +57,10 @@ head-y := arch/ppc/kernel/head.o
head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o
head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
-head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
-head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
arch/ppc/platforms/ \
arch/ppc/mm/ arch/ppc/lib/ \
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index e399bbb..1b2c745 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -6,14 +6,13 @@ ifneq ($(CONFIG_PPC_MERGE),y)
extra-$(CONFIG_PPC_STD_MMU) := head.o
extra-$(CONFIG_40x) := head_4xx.o
extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
-extra-$(CONFIG_6xx) += idle_6xx.o
extra-y += vmlinux.lds
-obj-y := entry.o traps.o idle.o time.o misc.o \
+obj-y := entry.o traps.o time.o misc.o \
setup.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
@@ -33,11 +32,10 @@ obj-$(CONFIG_8xx) += softemu8xx.o
endif
# These are here while we do the architecture merge
else
-obj-y := idle.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
obj-$(CONFIG_KGDB) += ppc-stub.o
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 3a28159..fa8d497 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -133,14 +133,14 @@ transfer_to_handler:
*/
#ifdef CONFIG_6xx
mfspr r11,SPRN_HID0
mtcr r11
BEGIN_FTR_SECTION
- bt- 8,power_save_6xx_restore /* Check DOZE */
+ bt- 8,4f /* Check DOZE */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
BEGIN_FTR_SECTION
- bt- 9,power_save_6xx_restore /* Check NAP */
+ bt- 9,4f /* Check NAP */
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
transfer_to_handler_cont:
lwz r11,THREAD_INFO-THREAD(r12)
@@ -155,10 +155,14 @@ transfer_to_handler_cont:
mtspr SPRN_SRR1,r10
mtlr r9
SYNC
RFI /* jump to handler, enable MMU */
+#ifdef CONFIG_6xx
+4: b power_save_6xx_restore
+#endif
+
/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
*/
stack_ovf:
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
deleted file mode 100644
index 1be3ca5..0000000
--- a/arch/ppc/kernel/idle.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Idle daemon for PowerPC. Idle daemon will handle any action
- * that needs to be taken when the system becomes idle.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu). Subsequently hacked
- * on by Tom Rini, Armin Kuster, Paul Mackerras and others.
- *
- * 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/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/sysctl.h>
-#include <linux/cpu.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/mmu.h>
-#include <asm/cache.h>
-#include <asm/cputable.h>
-#include <asm/machdep.h>
-#include <asm/smp.h>
-
-void default_idle(void)
-{
- void (*powersave)(void);
-
- powersave = ppc_md.power_save;
-
- if (!need_resched()) {
- if (powersave != NULL)
- powersave();
-#ifdef CONFIG_SMP
- else {
- set_thread_flag(TIF_POLLING_NRFLAG);
- while (!need_resched() &&
- !cpu_is_offline(smp_processor_id()))
- barrier();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- }
-#endif
- }
-}
-
-/*
- * The body of the idle task.
- */
-void cpu_idle(void)
-{
- int cpu = smp_processor_id();
-
- for (;;) {
- while (!need_resched()) {
- if (ppc_md.idle != NULL)
- ppc_md.idle();
- else
- default_idle();
- }
-
- if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
- cpu_die();
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
-}
-
-#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
-/*
- * Register the sysctl to set/clear powersave_nap.
- */
-extern int powersave_nap;
-
-static ctl_table powersave_nap_ctl_table[]={
- {
- .ctl_name = KERN_PPC_POWERSAVE_NAP,
- .procname = "powersave-nap",
- .data = &powersave_nap,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- { 0, },
-};
-static ctl_table powersave_nap_sysctl_root[] = {
- { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
- { 0,},
-};
-
-static int __init
-register_powersave_nap_sysctl(void)
-{
- register_sysctl_table(powersave_nap_sysctl_root, 0);
-
- return 0;
-}
-
-__initcall(register_powersave_nap_sysctl);
-#endif
diff --git a/arch/ppc/kernel/idle_6xx.S b/arch/ppc/kernel/idle_6xx.S
deleted file mode 100644
index 1a2194c..0000000
--- a/arch/ppc/kernel/idle_6xx.S
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file contains the power_save function for 6xx & 7xxx CPUs
- * rewritten in assembler
- *
- * Warning ! This code assumes that if your machine has a 750fx
- * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
- * if this is not the case some additional changes will have to
- * be done to check a runtime var (a bit like powersave-nap)
- *
- * 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/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-#undef DEBUG
-
- .text
-
-/*
- * Init idle, called at early CPU setup time from head.S for each CPU
- * Make sure no rest of NAP mode remains in HID0, save default
- * values for some CPU specific registers. Called with r24
- * containing CPU number and r3 reloc offset
- */
-_GLOBAL(init_idle_6xx)
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_HID0
- rlwinm r4,r4,0,10,8 /* Clear NAP */
- mtspr SPRN_HID0, r4
- b 1f
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
- blr
-1:
- slwi r5,r24,2
- add r5,r5,r3
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_MSSCR0
- addis r6,r5, nap_save_msscr0@ha
- stw r4,nap_save_msscr0@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_HID1
- addis r6,r5,nap_save_hid1@ha
- stw r4,nap_save_hid1@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
- blr
-
-/*
- * Here is the power_save_6xx function. This could eventually be
- * split into several functions & changing the function pointer
- * depending on the various features.
- */
-_GLOBAL(ppc6xx_idle)
- /* Check if we can nap or doze, put HID0 mask in r3
- */
- lis r3, 0
-BEGIN_FTR_SECTION
- lis r3,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-BEGIN_FTR_SECTION
- /* We must dynamically check for the NAP feature as it
- * can be cleared by CPU init after the fixups are done
- */
- lis r4,cur_cpu_spec@ha
- lwz r4,cur_cpu_spec@l(r4)
- lwz r4,CPU_SPEC_FEATURES(r4)
- andi. r0,r4,CPU_FTR_CAN_NAP
- beq 1f
- /* Now check if user or arch enabled NAP mode */
- lis r4,powersave_nap@ha
- lwz r4,powersave_nap@l(r4)
- cmpwi 0,r4,0
- beq 1f
- lis r3,HID0_NAP@h
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
- cmpwi 0,r3,0
- beqlr
-
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Check current_thread_info()->flags */
- rlwinm r4,r1,0,0,18
- lwz r4,TI_FLAGS(r4)
- andi. r0,r4,_TIF_NEED_RESCHED
- beq 1f
- mtmsr r7 /* out of line this ? */
- blr
-1:
- /* Some pre-nap cleanups needed on some CPUs */
- andis. r0,r3,HID0_NAP@h
- beq 2f
-BEGIN_FTR_SECTION
- /* Disable L2 prefetch on some 745x and try to ensure
- * L2 prefetch engines are idle. As explained by errata
- * text, we can't be sure they are, we just hope very hard
- * that well be enough (sic !). At least I noticed Apple
- * doesn't even bother doing the dcbf's here...
- */
- mfspr r4,SPRN_MSSCR0
- rlwinm r4,r4,0,0,29
- sync
- mtspr SPRN_MSSCR0,r4
- sync
- isync
- lis r4,KERNELBASE@h
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-#ifdef DEBUG
- lis r6,nap_enter_count@ha
- lwz r4,nap_enter_count@l(r6)
- addi r4,r4,1
- stw r4,nap_enter_count@l(r6)
-#endif
-2:
-BEGIN_FTR_SECTION
- /* Go to low speed mode on some 750FX */
- lis r4,powersave_lowspeed@ha
- lwz r4,powersave_lowspeed@l(r4)
- cmpwi 0,r4,0
- beq 1f
- mfspr r4,SPRN_HID1
- oris r4,r4,0x0001
- mtspr SPRN_HID1,r4
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
-
- /* Go to NAP or DOZE now */
- mfspr r4,SPRN_HID0
- lis r5,(HID0_NAP|HID0_SLEEP)@h
-BEGIN_FTR_SECTION
- oris r5,r5,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
- andc r4,r4,r5
- or r4,r4,r3
-BEGIN_FTR_SECTION
- oris r4,r4,HID0_DPM@h /* that should be done once for all */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
- mtspr SPRN_HID0,r4
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
- ori r7,r7,MSR_EE /* Could be ommited (already set) */
- oris r7,r7,MSR_POW@h
- sync
- isync
- mtmsr r7
- isync
- sync
- blr
-
-/*
- * Return from NAP/DOZE mode, restore some CPU specific registers,
- * we are called with DR/IR still off and r2 containing physical
- * address of current.
- */
-_GLOBAL(power_save_6xx_restore)
- mfspr r11,SPRN_HID0
- rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
- cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
-BEGIN_FTR_SECTION
- rlwinm r11,r11,0,9,7 /* Clear DOZE */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
- mtspr SPRN_HID0, r11
-
-#ifdef DEBUG
- beq cr1,1f
- lis r11,(nap_return_count-KERNELBASE)@ha
- lwz r9,nap_return_count@l(r11)
- addi r9,r9,1
- stw r9,nap_return_count@l(r11)
-1:
-#endif
-
- rlwinm r9,r1,0,0,18
- tophys(r9,r9)
- lwz r11,TI_CPU(r9)
- slwi r11,r11,2
- /* Todo make sure all these are in the same page
- * and load r22 (@ha part + CPU offset) only once
- */
-BEGIN_FTR_SECTION
- beq cr1,1f
- addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
- lwz r9,nap_save_msscr0@l(r9)
- mtspr SPRN_MSSCR0, r9
- sync
- isync
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
- addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
- lwz r9,nap_save_hid1@l(r9)
- mtspr SPRN_HID1, r9
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
- b transfer_to_handler_cont
-
- .data
-
-_GLOBAL(nap_save_msscr0)
- .space 4*NR_CPUS
-
-_GLOBAL(nap_save_hid1)
- .space 4*NR_CPUS
-
-_GLOBAL(powersave_nap)
- .long 0
-_GLOBAL(powersave_lowspeed)
- .long 0
-
-#ifdef DEBUG
-_GLOBAL(nap_enter_count)
- .space 4
-_GLOBAL(nap_return_count)
- .space 4
-#endif
diff --git a/arch/ppc/kernel/idle_power4.S b/arch/ppc/kernel/idle_power4.S
deleted file mode 100644
index cc0d535..0000000
--- a/arch/ppc/kernel/idle_power4.S
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This file contains the power_save function for 6xx & 7xxx CPUs
- * rewritten in assembler
- *
- * Warning ! This code assumes that if your machine has a 750fx
- * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
- * if this is not the case some additional changes will have to
- * be done to check a runtime var (a bit like powersave-nap)
- *
- * 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/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-#undef DEBUG
-
- .text
-
-/*
- * Init idle, called at early CPU setup time from head.S for each CPU
- * So nothing for now. Called with r24 containing CPU number and r3
- * reloc offset
- */
- .globl init_idle_power4
-init_idle_power4:
- blr
-
-/*
- * Here is the power_save_6xx function. This could eventually be
- * split into several functions & changing the function pointer
- * depending on the various features.
- */
- .globl power4_idle
-power4_idle:
-BEGIN_FTR_SECTION
- blr
-END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
- /* We must dynamically check for the NAP feature as it
- * can be cleared by CPU init after the fixups are done
- */
- lis r4,cur_cpu_spec@ha
- lwz r4,cur_cpu_spec@l(r4)
- lwz r4,CPU_SPEC_FEATURES(r4)
- andi. r0,r4,CPU_FTR_CAN_NAP
- beqlr
- /* Now check if user or arch enabled NAP mode */
- lis r4,powersave_nap@ha
- lwz r4,powersave_nap@l(r4)
- cmpwi 0,r4,0
- beqlr
-
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Check current_thread_info()->flags */
- rlwinm r4,r1,0,0,18
- lwz r4,TI_FLAGS(r4)
- andi. r0,r4,_TIF_NEED_RESCHED
- beq 1f
- mtmsr r7 /* out of line this ? */
- blr
-1:
- /* Go to NAP now */
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
- ori r7,r7,MSR_EE /* Could be ommited (already set) */
- oris r7,r7,MSR_POW@h
- sync
- isync
- mtmsr r7
- isync
- sync
- blr
-
- .globl powersave_nap
-powersave_nap:
- .long 0
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 38ca9ad..b72c04f 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -7,10 +7,11 @@
#define H_Success 0
#define H_Busy 1 /* Hardware busy -- retry later */
#define H_Closed 2 /* Resource closed */
#define H_Constrained 4 /* Resource request constrained to max allowed */
#define H_InProgress 14 /* Kind of like busy */
+#define H_Pending 17 /* returned from H_POLL_PENDING */
#define H_Continue 18 /* Returned from H_Join on success */
#define H_LongBusyStartRange 9900 /* Start of long busy range */
#define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */
#define H_LongBusyOrder10msec 9901 /* Long busy, hint that 10msec is a good time to retry */
#define H_LongBusyOrder100msec 9902 /* Long busy, hint that 100msec is a good time to retry */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 5348b82..21c8dc9 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -156,10 +156,16 @@ struct machdep_calls {
pgprot_t vma_prot);
/* Idle loop for this platform, leave empty for default idle loop */
void (*idle_loop)(void);
+ /*
+ * Function for waiting for work with reduced power in idle loop;
+ * called with interrupts disabled.
+ */
+ void (*power_save)(void);
+
/* Function to enable performance monitor counters for this
platform, called once per cpu. */
void (*enable_pmcs)(void);
/* Set DABR for this platform, leave empty for default implemenation */
@@ -168,13 +174,10 @@ struct machdep_calls {
#ifdef CONFIG_PPC32 /* XXX for now */
/* A general init function, called by ppc_init in init/main.c.
May be NULL. */
void (*init)(void);
- void (*idle)(void);
- void (*power_save)(void);
-
void (*heartbeat)(void);
unsigned long heartbeat_reset;
unsigned long heartbeat_count;
void (*setup_io_mappings)(void);
@@ -240,12 +243,12 @@ struct machdep_calls {
*/
void (*machine_kexec)(struct kimage *image);
#endif /* CONFIG_KEXEC */
};
-extern void default_idle(void);
-extern void native_idle(void);
+extern void power4_idle(void);
+extern void ppc6xx_idle(void);
extern struct machdep_calls ppc_md;
extern char cmd_line[COMMAND_LINE_SIZE];
#ifdef CONFIG_PPC_PMAC
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 72bfe3a..bd467bf 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -620,10 +620,14 @@ extern void ppc64_runlatch_on(void);
extern void ppc64_runlatch_off(void);
extern unsigned long scom970_read(unsigned int address);
extern void scom970_write(unsigned int address, unsigned long value);
+#else
+#define ppc64_runlatch_on()
+#define ppc64_runlatch_off()
+
#endif /* CONFIG_PPC64 */
#define __get_SP() ({unsigned long sp; \
asm volatile("mr %0,1": "=r" (sp)); sp;})
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index a3e8a45..ebbef64 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -42,11 +42,11 @@ struct machdep_calls {
void (*restart)(char *cmd);
void (*power_off)(void);
void (*halt)(void);
- void (*idle)(void);
+ void (*idle_loop)(void);
void (*power_save)(void);
long (*time_init)(void); /* Optional, may be NULL */
int (*set_rtc_time)(unsigned long nowtime);
unsigned long (*get_rtc_time)(void);
^ permalink raw reply related
* Re: [BULK] Re: "transmit timed out" on FCC in MPC8260 as well as MPC8247
From: Siju Viswanath K E @ 2006-03-24 9:47 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20060324075148.4C106353BFB@atlas.denx.de>
Hi Denk,
Thanks for the suggestion. I had a look at the source repository
at projects/linuxppc_2_4_devel.git site. Outdated code doesnt seem to be
the issue. My repository is patched upto
"Patch by Wojciech Kromer, 06 Jan 2004" and later changes are only
adding extra board support.
regards,
Siju Viswanath
On Fri, 2006-03-24 at 13:21, Wolfgang Denk wrote:
> In message <1143177651.22246.3.camel@Blaze> you wrote:
> >
> > I am using denk's linuxppc-2.4.20 . I am getting this problem of
>
> Why don't you try using a more current version of the code? 2.4.20 is
> *very* old, and *lots* of bugs and problems have been fixed since.
>
> It really does not make sense to spend effort on such old code.
>
> Best regards,
>
> Wolfgang Denk
^ permalink raw reply
* Re: pci-x
From: Carlos Mitidieri @ 2006-03-24 11:21 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <AD260576-EB34-4B56-9FB7-CE3A2DAEBFE7@kernel.crashing.org>
On Thursday 23 March 2006 16:41, Kumar Gala wrote:
> > Is there PCI-X support for the mpc8540ads?
>
> Yes. You have to make sure the board is setup (switches in the right
> place) properly for it.
Thank you for answering.
Looking the manuals and schematics, I have changed the "config" switch in
SW1, and now the PCI-X support is activated in the kernel at the system
initialization. Nevertheless, when I plug a bridge board to the slot 0, I
get the following messages:
PCI: Probing PCI hardware
PCI: Cannot allocate resource region 1 of PCI bridge 1
PCI: bridge 1 resource 1 moved to 9ff00000..9fffffff
PCI: Cannot allocate resource region 2 of PCI bridge 1
PCI: bridge 1 resource 2 moved to 9fe00000..9fefffff
Would you guess that this is a driver problem, or that my board setup is still
incorrect?
--
Carlos Mitidieri
SYSGO AG - Office Ulm
^ permalink raw reply
* Re: new sound driver
From: Johannes Berg @ 2006-03-24 11:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1143020119.11724.41.camel@localhost>
[-- Attachment #1: Type: text/plain, Size: 428 bytes --]
On Wed, 2006-03-22 at 10:35 +0100, Johannes Berg wrote:
> So I started to rewrite snd-powermac as snd-aoa, which I currently keep
> in a git tree at http://johannes.sipsolutions.net/snd-aoa.git/
It's a bit hacky (but hopefully those hacks can be removed rather
easily) but it works now for the onyx based machines (powermac8,1, quad
powermac, last 15" powerbook and probably more if you add the layout id)
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply
* Re: "transmit timed out" on FCC in MPC8260 => bug corrected
From: hubert.loewenguth @ 2006-03-24 11:44 UTC (permalink / raw)
To: Siju Viswanath K E; +Cc: Hunter, David, linuxppc-embedded
In-Reply-To: <1143193658.22246.20.camel@Blaze>
[-- Attachment #1.1: Type: text/plain, Size: 5744 bytes --]
Hi to the community.
I'm the man who has posted numerous questions about this problem of
fcc_enet timeout in ppc8260.
I just want to say that the 2.6 kernel doesn't solve the problem if you
have it on your board (I tried it, normally I have a 2.4-20 linux too).
I have search for this bug during a long time, and fortunatly, I 'm
happy to say you that finally, it is corrected since few days.
Special thanks to "Hunter, David" for having take in consideration my
problem, and proposing me some way of invastigations in this thread:
http://ozlabs.org/pipermail/linuxppc-embedded/2006-January/021842.html
In fact the solution comes from the new "MPC8260 PowerQUICC II Family
Reference Manual" fresescale has delivered 01/19/2006.
http://www.freescale.com/files/product/doc/MPC8260UM.pdf
They have added a very interesting paragraph about error handling in
ethernet mode:
/29.10.1.3 Adjusting Transmitter BD Handling
When a TXE event occurs, the TBPTR may already point beyond BDs still
marked as ready due to internal
pipelining. If the TBPTR is not adjusted, these BDs would be skipped
while still being marked as ready.
Software must determine if these BDs should be retransmitted or if they
should be skipped, depending on
the protocol and application needs. This requires the following steps:
1. From the current TBPTR value, search backwards over all (if any) BDs
still marked as ready to
find the first BD that has not been closed by the CPM. The search
process should stop if the BD to
be checked next is not ready or if it is the most recent BD marked as
ready by the CPU transmit
software. This is to avoid an endless loop in case the CPU software
fills the BD ring completely.
2. A) For skipping BDs, manually close all BDs from the BD just found up
to and including the BD
just before TBPTR. Leave the TBPTR value untouched.
B) For retransmitting BDs, change the TBPTR value to point to the BD
just found.
/
So, here is the correction I have done to the fcc-enet.c driver, and
wich I'am very satsify
I have tested it on my platform which was always entering in this
infernal timeout loop when there was successive plug/unplug during
important data transfert.
Thanks to some trace, I have seen that, as it is said in the new manual,
the error comes from the pipelining and a bad restart procedure in the
driver.
(I think it is the same restart procedure in the 2.6 kernel ??? to
verify ...)
With this correction, I have no more infernal timeout loop.
In fact, I replace the restart procedure in the fcc_enet_interrupt
method by this one, which respect the MPC8260 manual restart procedure:
if (must_restart) {
volatile cpm8260_t *cp;
/* Some transmit errors cause the transmitter to shut
* down. We now issue a restart transmit. Since the
* errors close the BD and update the pointers, the restart
* _should_ pick up without having to reset any of our
* pointers either. Also, To workaround 8260 device erratum
* CPM37, we must disable and then re-enable the transmitter
* following a Late Collision, Underrun, or Retry Limit error.
*/
// disable Transmitter
cep->fccp->fcc_gfmr &= ~FCC_GFMR_ENT;
udelay(10); /* wait a few microseconds just on principle */
#ifdef THALES_DEBUG_TRACE
printk("Thales restart debug trace :\n");
printk("first dirty tx %d, final dirty_tx %d, tbptr
%d\n",cbt_ptr2index(dev,first_bdp_dirty_tx),cbt_ptr2index(dev,cep->dirty_tx),tbptr_ptr2index(dev,ep->fen_genfcc.fcc_tbptr));
#endif
// RESTART TX command to the cpm
cp = cpmp;
cp->cp_cpcr = mk_cr_cmd(cep->fip->fc_cpmpage,
cep->fip->fc_cpmblock,0x0c, CPM_CR_RESTART_TX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
// Adjusting Transmitter BD Handling
/* HLO : I do not search backwards from the current TBPTR value
to found skip BDs, but I directly
* adjust the tbptr value to the dirty_tx current value.
* In case of problemes occuring, change it and do like
indicated in 29.10.3 of MPC8260 manual
*/
ep->fen_genfcc.fcc_tbptr = __pa(cep->dirty_tx);
#ifdef THALES_DEBUG_TRACE
printk(" Thales workaround tbptr value adjusted :
%d\n",tbptr_ptr2index(dev,ep->fen_genfcc.fcc_tbptr));
#endif
// re-enable Transmitter
cep->fccp->fcc_gfmr |= FCC_GFMR_ENT;
}
I hope this correction will help you and the community.
Best regards
Siju Viswanath K E a écrit :
>Hi Denk,
> Thanks for the suggestion. I had a look at the source repository
>at projects/linuxppc_2_4_devel.git site. Outdated code doesnt seem to be
>the issue. My repository is patched upto
>"Patch by Wojciech Kromer, 06 Jan 2004" and later changes are only
>adding extra board support.
>
>regards,
>Siju Viswanath
>
>On Fri, 2006-03-24 at 13:21, Wolfgang Denk wrote:
>
>
>>In message <1143177651.22246.3.camel@Blaze> you wrote:
>>
>>
>>> I am using denk's linuxppc-2.4.20 . I am getting this problem of
>>>
>>>
>>Why don't you try using a more current version of the code? 2.4.20 is
>>*very* old, and *lots* of bugs and problems have been fixed since.
>>
>>It really does not make sense to spend effort on such old code.
>>
>>Best regards,
>>
>>Wolfgang Denk
>>
>>
>
>_______________________________________________
>Linuxppc-embedded mailing list
>Linuxppc-embedded@ozlabs.org
>https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
>
[-- Attachment #1.2: Type: text/html, Size: 8250 bytes --]
[-- Attachment #2: hubert.loewenguth.vcf --]
[-- Type: text/x-vcard, Size: 285 bytes --]
begin:vcard
fn:Hubert Loewenguth
n:Loewenguth;Hubert
org:Thales Broadcast & Multimedia
adr:;;1 rue de l'hautil;Conflans Ste Honorine;;78700;France
email;internet:hubert.loewenguth@thales-bm.com
title:Software Engineer
tel;work:01-34-90-37-56
x-mozilla-html:TRUE
version:2.1
end:vcard
^ permalink raw reply
* Re: [PATCH] return to OF via trap, not exit
From: Segher Boessenkool @ 2006-03-24 12:13 UTC (permalink / raw)
To: Olaf Hering; +Cc: Michael Ellerman, linuxppc-dev
In-Reply-To: <20060323210357.GC24667@suse.de>
On 23-mrt-2006, at 22:03, Olaf Hering wrote:
> On Mon, Mar 06, Segher Boessenkool wrote:
>> That's better than always calling trap, sure. Is there any reason
>> you can't just do it on Macs though? Because the problem you're
>> trying
>> to work around only happens there.
>
> Maybe something like this? Only compile tested
That looks fine yes (if it runs ;-) ), thanks!
> Do not call prom exit prom_panic. It clears the screen and the exit
> message is lost.
> On some (or all?) pmacs it causes another crash when OF tries to
> print the
> date and time in its banner.
>
> Set of_platform earlier to catch more prom_panic() calls.
>
> Signed-off-by: Olaf Hering <olh@suse.de>
Acked-by: Segher Boessenkool <segher@kernel.crashing.org>
^ permalink raw reply
* Re: [PATCH] powerpc: Kill machine numbers
From: Segher Boessenkool @ 2006-03-24 12:23 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linuxppc-dev, Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <200603240946.51793.arnd@arndb.de>
> One thing I have been wondering about is what should be the right way
> to check whether we're running on something based on the
> Cell Broadband Engine Architecture, if that is needed somewhere.
> My original idea was to make this the platform number, but this
> seems impractical now.
Just check the PVR? Either directly, or in the device tree.
It's not likely that there will be a million different CBEA
compliant CPUs any time soon ;-)
There really should be some other OF property in the CPU nodes
that tells us the CPU is CBEA, but I don't think we have one
right now :-(
Segher
^ permalink raw reply
* MTD physmap issues trying to map flash
From: Randy Smith @ 2006-03-24 13:32 UTC (permalink / raw)
To: linuxppc-embedded
Hello everyone,
I have been trying to get my flash memory to show up as an mtd device in
my 2.4.25 kernel and I get the following error:
physmap flash device: 0 at 0
__ioremap(): phys addr 00000000 is RAM lr c000f67c
Failed to ioremap
My hardware is based on the Icecube reference design but uses one
Spansion S29G128M-R2 16 MByte flash chip at physical address 0xff00000.
I am using u-boot 1.1.4 and the flash operates correctly in that
environment (after some tweaking). I am using a vanilla 2.4.25 linux
kernel from DENX's ELDK 3.1 and I have tried almost every incantation
regarding MTD configuration but no joy.
Some questions:
1. Does 2.4.25 expect the physmap_map structure to be populated by
u-boot and if so, where should I look in u-boot to make that happen?
2. I am assuming that this chip is CFI compliant and should show up
with that probing (and AMD support) enabled. Does it matter if turn on
both CFI and JEDEC probes? Or put another way, why should I have to
probe if this information is passed by u-boot, if it is?
3. How does the partitioning (command line) of the chip effect the
recognition of the chip?
4. What should I put in the physmap menuconfig line for the physical
address and size of the chip? I am using 0xff000000 and 0x01000000. Is
this correct and something else is broken?
5. Is there a patch to the kernel or u-boot that addresses this type of
failure?
Thanks,
Randy Smith
Software Engineer
ImageMap, Inc.
^ permalink raw reply
* Re: pci-x
From: Kumar Gala @ 2006-03-24 14:53 UTC (permalink / raw)
To: Carlos Mitidieri; +Cc: linuxppc-embedded
In-Reply-To: <200603241221.44576.carlos.mitidieri@sysgo.com>
On Mar 24, 2006, at 5:21 AM, Carlos Mitidieri wrote:
>
> On Thursday 23 March 2006 16:41, Kumar Gala wrote:
>>> Is there PCI-X support for the mpc8540ads?
>>
>> Yes. You have to make sure the board is setup (switches in the right
>> place) properly for it.
>
> Thank you for answering.
>
> Looking the manuals and schematics, I have changed the "config"
> switch in
> SW1, and now the PCI-X support is activated in the kernel at the
> system
> initialization. Nevertheless, when I plug a bridge board to the
> slot 0, I
> get the following messages:
>
> PCI: Probing PCI hardware
> PCI: Cannot allocate resource region 1 of PCI bridge 1
> PCI: bridge 1 resource 1 moved to 9ff00000..9fffffff
> PCI: Cannot allocate resource region 2 of PCI bridge 1
> PCI: bridge 1 resource 2 moved to 9fe00000..9fefffff
>
> Would you guess that this is a driver problem, or that my board
> setup is still
> incorrect?
That seems like a driver problem. Does lspci show your devices after
you boot? Also, what kernel ver are you using?
- k
^ permalink raw reply
* Re: pci-x
From: Carlos Mitidieri @ 2006-03-24 15:07 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <24661B8C-C4DF-4D9C-8F4A-F2E6600AFFE2@kernel.crashing.org>
On Friday 24 March 2006 15:53, Kumar Gala wrote:
> That seems like a driver problem. Does lspci show your devices after
> you boot? Also, what kernel ver are you using?
No, the device behind the bridge is not recognized, although the bridge itself
is. I am using kernel 2.6.15.
--
Carlos Mitidieri
SYSGO AG - Office Ulm
^ permalink raw reply
* Re: pci_dlpar.c & probe mode
From: John Rose @ 2006-03-24 16:16 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: External List
In-Reply-To: <1143160576.4257.51.camel@localhost.localdomain>
> I noticed that pcibios_add_pci_devices() test the platform type to
> decide wether to do a device-tree based probe or a direct PCI probe. Why
> can't it use ppc_md.probe_mode() like the rest of the PCI code does ?
I can't see a good reason either! :) I'll have a patch in two shakes of
a lamb's tail.
On a related note, I don't understand why devtree-based probe is only
desirable for the LPAR case (on pSeries).
Also, do we anticipate future probe modes for new platforms or
something? Adding such logic to ppc_md seems like mucho infrastructure
to answer a simple question (lpar or not). For exmaple, _machine gets
used all over the pmac code.
John
^ permalink raw reply
* [PATCH] powerpc: dynamic probe - use ppc_md.pci_probe_mode()
From: John Rose @ 2006-03-24 17:19 UTC (permalink / raw)
To: benh; +Cc: External List, Paul Mackerras
Change the dynamic PCI probe function for pSeries to use
ppc_md.pci_probe_mode() when appropriate.
Signed-off-by: John Rose <johnrose@austin.ibm.com>
---
As suggested by BenH. Tested on POWER5.
Thanks-
John
diff -puN arch/powerpc/platforms/pseries/pci_dlpar.c~use_probe_mode arch/powerpc/platforms/pseries/pci_dlpar.c
--- 2_6_cleanups/arch/powerpc/platforms/pseries/pci_dlpar.c~use_probe_mode 2006-03-24 09:57:08.000000000 -0600
+++ 2_6_cleanups-johnrose/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-03-24 10:12:49.000000000 -0600
@@ -152,20 +152,26 @@ pcibios_pci_config_bridge(struct pci_dev
void
pcibios_add_pci_devices(struct pci_bus * bus)
{
- int slotno, num;
+ int slotno, num, mode;
struct pci_dev *dev;
struct device_node *dn = pci_bus_to_OF_node(bus);
eeh_add_device_tree_early(dn);
- if (_machine == PLATFORM_PSERIES_LPAR) {
+ mode = PCI_PROBE_NORMAL;
+ if (ppc_md.pci_probe_mode)
+ mode = ppc_md.pci_probe_mode(bus);
+
+ if (mode == PCI_PROBE_DEVTREE) {
+ printk("%s: jhr: new probe\n", __FUNCTION__);
/* use ofdt-based probe */
of_scan_bus(dn, bus);
if (!list_empty(&bus->devices)) {
pcibios_fixup_new_pci_devices(bus, 0);
pci_bus_add_devices(bus);
}
- } else {
+ } else if (mode == PCI_PROBE_NORMAL) {
+ printk("%s: jhr: old probe\n", __FUNCTION__);
/* use legacy probe */
slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
_
^ permalink raw reply
* [PATCH] powerpc: dynamic probe - use ppc_md.pci_probe_mode()
From: John Rose @ 2006-03-24 17:25 UTC (permalink / raw)
To: benh; +Cc: External List, Paul Mackerras
In-Reply-To: <1143220753.2567.22.camel@sinatra.austin.ibm.com>
Change the dynamic PCI probe function for pSeries to use
ppc_md.pci_probe_mode() when appropriate.
Signed-off-by: John Rose <johnrose@austin.ibm.com>
---
Actually - how about a version without debug prints!? Original change
suggested by BenH. Tested on POWER5.
Thanks-
John
diff -puN arch/powerpc/platforms/pseries/pci_dlpar.c~use_probe_mode arch/powerpc/platforms/pseries/pci_dlpar.c
--- 2_6_linus/arch/powerpc/platforms/pseries/pci_dlpar.c~use_probe_mode 2006-03-24 09:57:08.000000000 -0600
+++ 2_6_linus-johnrose/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-03-24 11:26:23.000000000 -0600
@@ -152,20 +152,24 @@ pcibios_pci_config_bridge(struct pci_dev
void
pcibios_add_pci_devices(struct pci_bus * bus)
{
- int slotno, num;
+ int slotno, num, mode;
struct pci_dev *dev;
struct device_node *dn = pci_bus_to_OF_node(bus);
eeh_add_device_tree_early(dn);
- if (_machine == PLATFORM_PSERIES_LPAR) {
+ mode = PCI_PROBE_NORMAL;
+ if (ppc_md.pci_probe_mode)
+ mode = ppc_md.pci_probe_mode(bus);
+
+ if (mode == PCI_PROBE_DEVTREE) {
/* use ofdt-based probe */
of_scan_bus(dn, bus);
if (!list_empty(&bus->devices)) {
pcibios_fixup_new_pci_devices(bus, 0);
pci_bus_add_devices(bus);
}
- } else {
+ } else if (mode == PCI_PROBE_NORMAL) {
/* use legacy probe */
slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
_
^ permalink raw reply
* Re: [patch 06/13] powerpc: cell interrupt controller updates
From: Milton Miller @ 2006-03-24 17:43 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Arnd Bergmann, stk, linux-kernel, linuxppc-dev, Paul Mackerras,
hpenner, cbe-oss-dev
In-Reply-To: <20060323203521.862355000@dyn-9-152-242-103.boeblingen.de.ibm.com>
On Mar 22, 2006, at 5:00 PM, Arnd Bergmann wrote:
> static void spider_enable_irq(unsigned int irq)
> {
> + int nodeid = (irq / IIC_NODE_STRIDE) * 0x10;
> void __iomem *cfg = spider_get_irq_config(irq);
> irq = spider_get_nr(irq);
>
> - out_be32(cfg, in_be32(cfg) | 0x3107000eu);
> + out_be32(cfg, in_be32(cfg) | 0x3107000eu | nodeid);
> out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
> }
>
I just did a quick read of the code, but my first thought is what if
some other node id was previously set? Perhaps you should mask off
some bits before or'ing in the node id?
milton
^ permalink raw reply
* Re: [patch 06/13] powerpc: cell interrupt controller updates
From: Arnd Bergmann @ 2006-03-24 18:05 UTC (permalink / raw)
To: Milton Miller
Cc: stk, linux-kernel, linuxppc-dev, Paul Mackerras, hpenner,
Arnd Bergmann, cbe-oss-dev
In-Reply-To: <32140afe2349e8f1726d188eb85c780c@bga.com>
On Friday 24 March 2006 18:43, Milton Miller wrote:
> On Mar 22, 2006, at 5:00 PM, Arnd Bergmann wrote:
> > static void spider_enable_irq(unsigned int irq)
> > {
> > + int nodeid = (irq / IIC_NODE_STRIDE) * 0x10;
> > void __iomem *cfg = spider_get_irq_config(irq);
> > irq = spider_get_nr(irq);
> >
> > - out_be32(cfg, in_be32(cfg) | 0x3107000eu);
> > + out_be32(cfg, in_be32(cfg) | 0x3107000eu | nodeid);
> > out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
> > }
> >
>
> I just did a quick read of the code, but my first thought is what if
> some other node id was previously set? Perhaps you should mask off
> some bits before or'ing in the node id?
Good point. The firmware always sets nodeid zero (or the same one that
we set), but I can't see any reason why we should take that for granted.
Thanks,
Arnd <><
^ permalink raw reply
* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Hollis Blanchard @ 2006-03-24 18:26 UTC (permalink / raw)
To: linuxppc-dev, mikey; +Cc: michael
In-Reply-To: <20060324041727.F131267B56@ozlabs.org>
On Thursday 23 March 2006 22:17, Michael Neuling wrote:
> We only ever execute the loop once, so let's move it to a function
> making it more readable. Cleanup patch, no functional change.
I don't understand: it's only used once, so make it a function? Why not just
change the "while" to an "if"?
Regardless, two style issues:
- remove the plain "return"
- reduce indenting like so:
if (console < 0)
return;
struct legacy_serial_info *info = ...
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> arch/powerpc/kernel/legacy_serial.c | 39
+++++++++++++++++++-----------------
> 1 files changed, 21 insertions(+), 18 deletions(-)
>
> Index: linux-2.6-linus/arch/powerpc/kernel/legacy_serial.c
> ===================================================================
> --- linux-2.6-linus.orig/arch/powerpc/kernel/legacy_serial.c
> +++ linux-2.6-linus/arch/powerpc/kernel/legacy_serial.c
> @@ -236,6 +236,26 @@ static int __init add_legacy_pci_port(st
> }
> #endif
>
> +static void __init setup_legacy_serial_console(int console)
> +{
> + if (console >= 0) {
> + struct legacy_serial_info *info =
> + &legacy_serial_infos[legacy_serial_console];
> + void __iomem *addr;
> +
> + if (info->taddr == 0)
> + return;
> + addr = ioremap(info->taddr, 0x1000);
> + if (addr == NULL)
> + return;
> + if (info->speed == 0)
> + info->speed = udbg_probe_uart_speed(addr, info->clock);
> + DBG("default console speed = %d\n", info->speed);
> + udbg_init_uart(addr, info->speed, info->clock);
> + }
> + return;
> +}
> +
> /*
> * This is called very early, as part of setup_system() or eventually
> * setup_arch(), basically before anything else in this file. This function
> @@ -319,24 +339,7 @@ void __init find_legacy_serial_ports(voi
>
> DBG("legacy_serial_console = %d\n", legacy_serial_console);
>
> - /* udbg is 64 bits only for now, that will change soon though ... */
> - while (legacy_serial_console >= 0) {
> - struct legacy_serial_info *info =
> - &legacy_serial_infos[legacy_serial_console];
> - void __iomem *addr;
> -
> - if (info->taddr == 0)
> - break;
> - addr = ioremap(info->taddr, 0x1000);
> - if (addr == NULL)
> - break;
> - if (info->speed == 0)
> - info->speed = udbg_probe_uart_speed(addr, info->clock);
> - DBG("default console speed = %d\n", info->speed);
> - udbg_init_uart(addr, info->speed, info->clock);
> - break;
> - }
> -
> + setup_legacy_serial_console(legacy_serial_console);
> DBG(" <- find_legacy_serial_port()\n");
> }
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
^ permalink raw reply
* [PATCH] powerpc: fix spider-pic affinity setting
From: Arnd Bergmann @ 2006-03-24 18:46 UTC (permalink / raw)
To: linuxppc-dev
Cc: Arnd Bergmann, Paul Mackerras, linux-kernel, Milton Miller,
cbe-oss-dev
In-Reply-To: <200603241905.04356.arnd.bergmann@de.ibm.com>
As noticed by Milton Miller, setting the initial affinity in
spider-pic can go wrong if the target node field was not orinally
empty.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
--- linus-2.6.orig/arch/powerpc/platforms/cell/spider-pic.c
+++ linus-2.6/arch/powerpc/platforms/cell/spider-pic.c
@@ -88,7 +88,7 @@ static void spider_enable_irq(unsigned i
void __iomem *cfg = spider_get_irq_config(irq);
irq = spider_get_nr(irq);
- out_be32(cfg, in_be32(cfg) | 0x3107000eu | nodeid);
+ out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid);
out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
}
^ permalink raw reply
* [PATCH] powerpc: use guarded ioremap for on-chip mappings
From: Arnd Bergmann @ 2006-03-24 18:47 UTC (permalink / raw)
To: linuxppc-dev
Cc: stk, linux-kernel, Milton Miller, Paul Mackerras, hpenner,
Arnd Bergmann, cbe-oss-dev
In-Reply-To: <1143152153.4257.28.camel@localhost.localdomain>
Subject: powerpc: use guarded ioremap for cell on-chip mappings
I'm not sure where the information came from, but I assumed
that doing cache-inhibited mappings for mmio regions was
sufficient.
It seems we also need the guarded bit set, like everyone
else, which is the default for ioremap.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
Index: linus-2.6/arch/powerpc/platforms/cell/interrupt.c
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/interrupt.c
+++ linus-2.6/arch/powerpc/platforms/cell/interrupt.c
@@ -226,9 +226,7 @@ static int setup_iic_hardcoded(void)
regs += 0x20;
printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs);
- iic->regs = __ioremap(regs, sizeof(struct iic_regs),
- _PAGE_NO_CACHE);
-
+ iic->regs = ioremap(regs, sizeof(struct iic_regs));
iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe);
}
@@ -269,14 +267,12 @@ static int setup_iic(void)
}
iic = &per_cpu(iic, np[0]);
- iic->regs = __ioremap(regs[0], sizeof(struct iic_regs),
- _PAGE_NO_CACHE);
+ iic->regs = ioremap(regs[0], sizeof(struct iic_regs));
iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe);
printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs);
iic = &per_cpu(iic, np[1]);
- iic->regs = __ioremap(regs[2], sizeof(struct iic_regs),
- _PAGE_NO_CACHE);
+ iic->regs = ioremap(regs[2], sizeof(struct iic_regs));
iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe);
printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs);
Index: linus-2.6/arch/powerpc/platforms/cell/iommu.c
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/iommu.c
+++ linus-2.6/arch/powerpc/platforms/cell/iommu.c
@@ -344,8 +344,8 @@ static int cell_map_iommu_hardcoded(int
/* node 0 */
iommu = &cell_iommus[0];
- iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE);
- iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE);
+ iommu->mapped_base = ioremap(0x20000511000, 0x1000);
+ iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000);
enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
@@ -357,8 +357,8 @@ static int cell_map_iommu_hardcoded(int
/* node 1 */
iommu = &cell_iommus[1];
- iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE);
- iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE);
+ iommu->mapped_base = ioremap(0x30000511000, 0x1000);
+ iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000);
enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
@@ -407,8 +407,8 @@ static int cell_map_iommu(void)
iommu->base = *base;
iommu->mmio_base = *mmio_base;
- iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE);
- iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE);
+ iommu->mapped_base = ioremap(*base, 0x1000);
+ iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000);
enable_mapping(iommu->mapped_base,
iommu->mapped_mmio_base);
Index: linus-2.6/arch/powerpc/platforms/cell/pervasive.c
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/pervasive.c
+++ linus-2.6/arch/powerpc/platforms/cell/pervasive.c
@@ -203,7 +203,7 @@ found:
pr_debug("pervasive area for CPU %d at %lx, size %x\n",
cpu, real_address, size);
- p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE);
+ p->regs = ioremap(real_address, size);
p->thread = thread;
return 0;
}
Index: linus-2.6/arch/powerpc/platforms/cell/spider-pic.c
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/spider-pic.c
+++ linus-2.6/arch/powerpc/platforms/cell/spider-pic.c
@@ -159,7 +159,7 @@ void spider_init_IRQ_hardcoded(void)
for (node = 0; node < num_present_cpus()/2; node++) {
spiderpic = pics[node];
printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
- spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE);
+ spider_pics[node] = ioremap(spiderpic, 0x800);
for (n = 0; n < IIC_NUM_EXT; n++) {
int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
get_irq_desc(irq)->handler = &spider_pic;
@@ -210,7 +210,7 @@ void spider_init_IRQ(void)
if ( n != 2)
printk("reg property with invalid number of elements \n");
- spider_pics[node] = __ioremap(spider_reg, 0x800, _PAGE_NO_CACHE);
+ spider_pics[node] = ioremap(spider_reg, 0x800);
printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n",
spider_reg, n, spider_pics[node]);
^ permalink raw reply
* [PATCH] spufs: Fix endless protection fault on LS writes by SPE.
From: Arnd Bergmann @ 2006-03-24 18:49 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Arnd Bergmann, cbe-oss-dev, linux-kernel
In-Reply-To: <20060323203423.620978000@dyn-9-152-242-103.boeblingen.de.ibm.com>
If an SPE attempts a DMA put to a local store after already doing
a get, the kernel must update the HW PTE to allow the write access.
This case was not being handled correctly.
From: Mike Kistler <mkistler@us.ibm.com>
Signed-off-by: Mike Kistler <mkistler@us.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
diff -ur linux-2.6.15/arch/powerpc/platforms/cell/spu_base.c linux-2.6.15.fixed/arch/powerpc/platforms/cell/spu_base.c
--- linux-2.6.15/arch/powerpc/platforms/cell/spu_base.c 2006-03-22 12:30:07.000000000 -0600
+++ linux-2.6.15.fixed/arch/powerpc/platforms/cell/spu_base.c 2006-03-22 10:21:26.000000000 -0600
@@ -486,14 +486,13 @@
ea = spu->dar;
dsisr = spu->dsisr;
- if (dsisr & MFC_DSISR_PTE_NOT_FOUND) {
+ if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
access = (_PAGE_PRESENT | _PAGE_USER);
access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
if (hash_page(ea, access, 0x300) != 0)
error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
}
- if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) ||
- (dsisr & MFC_DSISR_ACCESS_DENIED)) {
+ if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
if ((ret = spu_handle_mm_fault(spu)) != 0)
error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
else
^ permalink raw reply
* [PATCH] powerpc: fix cell platform detection
From: Arnd Bergmann @ 2006-03-24 18:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, Linux Kernel list, cbe-oss-dev
In-Reply-To: <200603240946.51793.arnd@arndb.de>
All future firmware should have 'CBEA' in the compatible
property in order to tell us that we are running on the
cell platform, so check for that as well as the now
deprecated value we have been using so far.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
This applies on top of the 'Kill machine numbers' patch
from Ben Herrenschmidt.
Index: linus-2.6/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linus-2.6.orig/arch/powerpc/platforms/cell/setup.c
+++ linus-2.6/arch/powerpc/platforms/cell/setup.c
@@ -198,7 +198,14 @@ static void __init cell_init_early(void)
static int __init cell_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- if (!of_flat_dt_is_compatible(root, "IBM,CPB"))
+
+ /*
+ * CPBW was used on early prototypes and will be removed.
+ * The correct identification is CBEA.
+ */
+ if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0") &&
+ !of_flat_dt_is_compatible(root, "IBM,CBEA") &&
+ !of_flat_dt_is_compatible(root, "CBEA"))
return 0;
return 1;
^ permalink raw reply
* powerpc: fix hvc-rtas comments
From: Arnd Bergmann @ 2006-03-24 18:58 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, cbe-oss-dev, linux-kernel
In-Reply-To: <200603232336.19683.arnd@arndb.de>
As notice by Olof Johansson, the comment about module_exit
in hvc_rtas is rather confusing, so remove it.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
Index: linus-2.6/drivers/char/hvc_rtas.c
===================================================================
--- linus-2.6.orig/drivers/char/hvc_rtas.c
+++ linus-2.6/drivers/char/hvc_rtas.c
@@ -119,7 +119,7 @@ static void __exit hvc_rtas_exit(void)
if (hvc_rtas_dev)
hvc_remove(hvc_rtas_dev);
}
-module_exit(hvc_rtas_exit); /* before drivers/char/hvc_console.c */
+module_exit(hvc_rtas_exit);
/* This will happen prior to module init. There is no tty at this time? */
static int hvc_rtas_console_init(void)
^ permalink raw reply
* Re: [PATCH] powerpc: Kill machine numbers
From: Olof Johansson @ 2006-03-24 18:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Paul Mackerras, Linux Kernel list
In-Reply-To: <1143187298.3710.3.camel@localhost.localdomain>
On Fri, Mar 24, 2006 at 07:01:38PM +1100, Benjamin Herrenschmidt wrote:
>
> > It would be very useful to print the ppc_md.name of the found machine
> > here, even without debugging enabled.
>
> Not sure ... without debugging enabled, it's likely that you won't see
> anything that early anyway :)
True, but it'd be in the dmesg, and get printed when the console comes up.
> > It's really weird that IBM chose to use "chrp" to describe a
> > PAPR-compliant platform. I guess it's for historical reasons, but it
> > sure isn't CHRP any more.
>
> Yup, I'm trying to get that changed in the architecture but even if I'm
> successful, we'll have to deal with existing machines.
Right, it was mostly a side comment.
> > > + is _not_ "chrp" as this will be matched by the kernel to be a
> > > + CHRP machine on 32 bits kernel or a pSeries on 64 bits kernels
> >
> > ...or a PAPR-compliant machine on 64-bit kernels.
> >
> > (Also, "xx-bit kernels", not "xx bits kernels").
>
> yeah yeah :) Thanks for the review anyway !
Hey, I couldn't find much technical issues, so I ended up reading your
comments and picking errors there instead. :-)
-Olof
^ permalink raw reply
* RE: memory with __get_free_pages and disabling caching
From: Kallol Biswas @ 2006-03-24 19:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
We have a little endian device on a PPC 440GX based system.
The descriptors need to be swapped. With E bit turned on we can save swapping time.
May be all the pages with _get_free_page already are mapped with large tlb entry.
How about making a window (ptes) like consistent memory?
-----Original Message-----
From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
Sent: Thursday, March 23, 2006 7:06 PM
To: Kallol Biswas
Cc: linuxppc-dev@ozlabs.org
Subject: Re: memory with __get_free_pages and disabling caching
On Thu, 2006-03-23 at 18:15 -0800, Kallol Biswas wrote:
> Hello,
> Is there an easy way to set page table attributes for the
> memory returned by __get_free_pages()?
>
> I need to be able to turn off caching and turn on E bit for these
> pages.
The Evil bit ? heh ! what are you trying to do ? here ... you can always create a virtual mapping to those pages with different attributes but that's nor recommended as some processors will shoke pretty badly if you end up with both cacheable and non-cacheable mappings for the same page.
However, it's not always possible to unmap the initial mapping since it's common to use things like large pages, BATs, large TLB entries etc... to map kernel memory..
> I tried to walk through the page tables data structures to get the
> pte, but it seems that the pmd is not present for the pages. If
> someone has done investigation on this before please send me a reply.
>
Kernel linear memory isn't necessarily mapped by the page tables. What are you trying to do and with what processor ?
Ben.
^ permalink raw reply
* Re: memory with __get_free_pages and disabling caching
From: Kumar Gala @ 2006-03-24 19:29 UTC (permalink / raw)
To: Kallol Biswas; +Cc: linuxppc-dev
In-Reply-To: <478F19F21671F04298A2116393EEC3D50A9C21@sjc1exm08.pmc_nt.nt.pmc-sierra.bc.ca>
On Mar 24, 2006, at 1:13 PM, Kallol Biswas wrote:
>
> We have a little endian device on a PPC 440GX based system.
> The descriptors need to be swapped. With E bit turned on we can
> save swapping time.
What's the device and what bus is it on? Are you writing a standard
kernel driver for it?
> May be all the pages with _get_free_page already are mapped with
> large tlb entry.
>
> How about making a window (ptes) like consistent memory?
>
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
> Sent: Thursday, March 23, 2006 7:06 PM
> To: Kallol Biswas
> Cc: linuxppc-dev@ozlabs.org
> Subject: Re: memory with __get_free_pages and disabling caching
>
> On Thu, 2006-03-23 at 18:15 -0800, Kallol Biswas wrote:
>> Hello,
>> Is there an easy way to set page table attributes for the
>> memory returned by __get_free_pages()?
>>
>> I need to be able to turn off caching and turn on E bit for these
>> pages.
>
> The Evil bit ? heh ! what are you trying to do ? here ... you can
> always create a virtual mapping to those pages with different
> attributes but that's nor recommended as some processors will shoke
> pretty badly if you end up with both cacheable and non-cacheable
> mappings for the same page.
> However, it's not always possible to unmap the initial mapping
> since it's common to use things like large pages, BATs, large TLB
> entries etc... to map kernel memory..
>
>> I tried to walk through the page tables data structures to get the
>> pte, but it seems that the pmd is not present for the pages. If
>> someone has done investigation on this before please send me a reply.
>>
> Kernel linear memory isn't necessarily mapped by the page tables.
> What are you trying to do and with what processor ?
>
>
>
> Ben.
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox