Commit 49b1e3ea 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:
  [POWERPC] Minor comment fix for misc_64.S
  [POWERPC] Use H_CEDE on non-SMT
  [POWERPC] force 64bit mode in fwnmi handlers to workaround firmware bugs
  [POWERPC] PMAC_APM_EMU should depend on ADB_PMU
  [POWERPC] Fix new interrupt code (MPIC detection)
  [POWERPC] Fix new interrupt code (MPIC endianness)
  [POWERPC] Add cpufreq support for Xserve G5
  [POWERPC] Xserve G5 thermal control fixes
  [POWERPC] Fix mem= handling when the memory limit is > RMO size
  [POWERPC] More offb/bootx fixes
  [POWERPC] Fix legacy_serial.c error handling on 32 bits
  [POWERPC] Fix default clock for udbg_16550
  [POWERPC] Fix non-MPIC CHRPs with CONFIG_SMP set
  [POWERPC] Fix 32 bits warning in prom_init.c
  [POWERPC] Workaround Pegasos incorrect ISA "ranges"
  [POWERPC] fix up front-LED Kconfig
parents ce38cac4 8d950cb8
...@@ -504,7 +504,7 @@ config CPU_FREQ_PMAC ...@@ -504,7 +504,7 @@ config CPU_FREQ_PMAC
config CPU_FREQ_PMAC64 config CPU_FREQ_PMAC64
bool "Support for some Apple G5s" bool "Support for some Apple G5s"
depends on CPU_FREQ && PMAC_SMU && PPC64 depends on CPU_FREQ && PPC64
select CPU_FREQ_TABLE select CPU_FREQ_TABLE
help help
This adds support for frequency switching on Apple iMac G5, This adds support for frequency switching on Apple iMac G5,
......
This diff is collapsed.
...@@ -191,6 +191,37 @@ exception_marker: ...@@ -191,6 +191,37 @@ exception_marker:
ori reg,reg,(label)@l; /* virt addr of handler ... */ ori reg,reg,(label)@l; /* virt addr of handler ... */
#endif #endif
/*
* Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode.
* The firmware calls the registered system_reset_fwnmi and
* machine_check_fwnmi handlers in 32bit mode if the cpu happens to run
* a 32bit application at the time of the event.
* This firmware bug is present on POWER4 and JS20.
*/
#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \
mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
mfspr r9,SPRN_SPRG1; \
std r9,area+EX_R13(r13); \
mfcr r9; \
clrrdi r12,r13,32; /* get high part of &label */ \
mfmsr r10; \
/* force 64bit mode */ \
li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \
rldimi r10,r11,61,0; /* insert into top 3 bits */ \
/* done 64bit mode */ \
mfspr r11,SPRN_SRR0; /* save SRR0 */ \
LOAD_HANDLER(r12,label) \
ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
mtspr SPRN_SRR0,r12; \
mfspr r12,SPRN_SRR1; /* and SRR1 */ \
mtspr SPRN_SRR1,r10; \
rfid; \
b . /* prevent speculative execution */
#define EXCEPTION_PROLOG_PSERIES(area, label) \ #define EXCEPTION_PROLOG_PSERIES(area, label) \
mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
...@@ -604,14 +635,14 @@ slb_miss_user_pseries: ...@@ -604,14 +635,14 @@ slb_miss_user_pseries:
system_reset_fwnmi: system_reset_fwnmi:
HMT_MEDIUM HMT_MEDIUM
mtspr SPRN_SPRG1,r13 /* save r13 */ mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXGEN, system_reset_common)
.globl machine_check_fwnmi .globl machine_check_fwnmi
.align 7 .align 7
machine_check_fwnmi: machine_check_fwnmi:
HMT_MEDIUM HMT_MEDIUM
mtspr SPRN_SPRG1,r13 /* save r13 */ mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common)
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
/*** ISeries-LPAR interrupt handlers ***/ /*** ISeries-LPAR interrupt handlers ***/
......
...@@ -112,7 +112,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, ...@@ -112,7 +112,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
static int __init add_legacy_soc_port(struct device_node *np, static int __init add_legacy_soc_port(struct device_node *np,
struct device_node *soc_dev) struct device_node *soc_dev)
{ {
phys_addr_t addr; u64 addr;
u32 *addrp; u32 *addrp;
upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
...@@ -143,7 +143,7 @@ static int __init add_legacy_isa_port(struct device_node *np, ...@@ -143,7 +143,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
u32 *reg; u32 *reg;
char *typep; char *typep;
int index = -1; int index = -1;
phys_addr_t taddr; u64 taddr;
DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
...@@ -165,10 +165,13 @@ static int __init add_legacy_isa_port(struct device_node *np, ...@@ -165,10 +165,13 @@ static int __init add_legacy_isa_port(struct device_node *np,
if (typep && *typep == 'S') if (typep && *typep == 'S')
index = simple_strtol(typep+1, NULL, 0) - 1; index = simple_strtol(typep+1, NULL, 0) - 1;
/* Translate ISA address */ /* Translate ISA address. If it fails, we still register the port
* with no translated address so that it can be picked up as an IO
* port later by the serial driver
*/
taddr = of_translate_address(np, reg); taddr = of_translate_address(np, reg);
if (taddr == OF_BAD_ADDR) if (taddr == OF_BAD_ADDR)
return -1; taddr = 0;
/* Add port, irq will be dealt with later */ /* Add port, irq will be dealt with later */
return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
...@@ -180,7 +183,7 @@ static int __init add_legacy_isa_port(struct device_node *np, ...@@ -180,7 +183,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
static int __init add_legacy_pci_port(struct device_node *np, static int __init add_legacy_pci_port(struct device_node *np,
struct device_node *pci_dev) struct device_node *pci_dev)
{ {
phys_addr_t addr, base; u64 addr, base;
u32 *addrp; u32 *addrp;
unsigned int flags; unsigned int flags;
int iotype, index = -1, lindex = 0; int iotype, index = -1, lindex = 0;
......
...@@ -687,7 +687,7 @@ _GLOBAL(kexec_sequence) ...@@ -687,7 +687,7 @@ _GLOBAL(kexec_sequence)
/* clear out hardware hash page table and tlb */ /* clear out hardware hash page table and tlb */
ld r5,0(r27) /* deref function descriptor */ ld r5,0(r27) /* deref function descriptor */
mtctr r5 mtctr r5
bctrl /* ppc_md.hash_clear_all(void); */ bctrl /* ppc_md.hpte_clear_all(void); */
/* /*
* kexec image calling is: * kexec image calling is:
......
...@@ -557,7 +557,9 @@ unsigned long prom_memparse(const char *ptr, const char **retptr) ...@@ -557,7 +557,9 @@ unsigned long prom_memparse(const char *ptr, const char **retptr)
static void __init early_cmdline_parse(void) static void __init early_cmdline_parse(void)
{ {
struct prom_t *_prom = &RELOC(prom); struct prom_t *_prom = &RELOC(prom);
#ifdef CONFIG_PPC64
const char *opt; const char *opt;
#endif
char *p; char *p;
int l = 0; int l = 0;
...@@ -2030,6 +2032,39 @@ static void __init fixup_device_tree_maple(void) ...@@ -2030,6 +2032,39 @@ static void __init fixup_device_tree_maple(void)
#define fixup_device_tree_maple() #define fixup_device_tree_maple()
#endif #endif
#ifdef CONFIG_PPC_CHRP
/* Pegasos lacks the "ranges" property in the isa node */
static void __init fixup_device_tree_chrp(void)
{
phandle isa;
u32 isa_ranges[6];
char *name;
int rc;
name = "/pci@80000000/isa@c";
isa = call_prom("finddevice", 1, 1, ADDR(name));
if (!PHANDLE_VALID(isa))
return;
rc = prom_getproplen(isa, "ranges");
if (rc != 0 && rc != PROM_ERROR)
return;
prom_printf("Fixing up missing ISA range on Pegasos...\n");
isa_ranges[0] = 0x1;
isa_ranges[1] = 0x0;
isa_ranges[2] = 0x01006000;
isa_ranges[3] = 0x0;
isa_ranges[4] = 0x0;
isa_ranges[5] = 0x00010000;
prom_setprop(isa, name, "ranges",
isa_ranges, sizeof(isa_ranges));
}
#else
#define fixup_device_tree_chrp()
#endif
#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
static void __init fixup_device_tree_pmac(void) static void __init fixup_device_tree_pmac(void)
{ {
...@@ -2077,6 +2112,7 @@ static void __init fixup_device_tree_pmac(void) ...@@ -2077,6 +2112,7 @@ static void __init fixup_device_tree_pmac(void)
static void __init fixup_device_tree(void) static void __init fixup_device_tree(void)
{ {
fixup_device_tree_maple(); fixup_device_tree_maple();
fixup_device_tree_chrp();
fixup_device_tree_pmac(); fixup_device_tree_pmac();
} }
......
...@@ -144,12 +144,14 @@ void smp_message_recv(int msg, struct pt_regs *regs) ...@@ -144,12 +144,14 @@ void smp_message_recv(int msg, struct pt_regs *regs)
void smp_send_reschedule(int cpu) void smp_send_reschedule(int cpu)
{ {
if (likely(smp_ops))
smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE);
} }
#ifdef CONFIG_DEBUGGER #ifdef CONFIG_DEBUGGER
void smp_send_debugger_break(int cpu) void smp_send_debugger_break(int cpu)
{ {
if (likely(smp_ops))
smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
} }
#endif #endif
...@@ -158,7 +160,7 @@ void smp_send_debugger_break(int cpu) ...@@ -158,7 +160,7 @@ void smp_send_debugger_break(int cpu)
void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
{ {
crash_ipi_function_ptr = crash_ipi_callback; crash_ipi_function_ptr = crash_ipi_callback;
if (crash_ipi_callback) { if (crash_ipi_callback && smp_ops) {
mb(); mb();
smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
} }
...@@ -220,6 +222,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, ...@@ -220,6 +222,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
/* Can deadlock when called with interrupts disabled */ /* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled()); WARN_ON(irqs_disabled());
if (unlikely(smp_ops == NULL))
return -1;
data.func = func; data.func = func;
data.info = info; data.info = info;
atomic_set(&data.started, 0); atomic_set(&data.started, 0);
...@@ -357,7 +362,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -357,7 +362,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpuid); smp_store_cpu_info(boot_cpuid);
cpu_callin_map[boot_cpuid] = 1; cpu_callin_map[boot_cpuid] = 1;
if (smp_ops)
max_cpus = smp_ops->probe(); max_cpus = smp_ops->probe();
else
max_cpus = 1;
smp_space_timers(max_cpus); smp_space_timers(max_cpus);
...@@ -453,7 +461,7 @@ void generic_mach_cpu_die(void) ...@@ -453,7 +461,7 @@ void generic_mach_cpu_die(void)
static int __devinit cpu_enable(unsigned int cpu) static int __devinit cpu_enable(unsigned int cpu)
{ {
if (smp_ops->cpu_enable) if (smp_ops && smp_ops->cpu_enable)
return smp_ops->cpu_enable(cpu); return smp_ops->cpu_enable(cpu);
return -ENOSYS; return -ENOSYS;
...@@ -467,7 +475,8 @@ int __devinit __cpu_up(unsigned int cpu) ...@@ -467,7 +475,8 @@ int __devinit __cpu_up(unsigned int cpu)
if (!cpu_enable(cpu)) if (!cpu_enable(cpu))
return 0; return 0;
if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) if (smp_ops == NULL ||
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
return -EINVAL; return -EINVAL;
/* Make sure callin-map entry is 0 (can be leftover a CPU /* Make sure callin-map entry is 0 (can be leftover a CPU
...@@ -568,6 +577,7 @@ void __init smp_cpus_done(unsigned int max_cpus) ...@@ -568,6 +577,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
old_mask = current->cpus_allowed; old_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
if (smp_ops)
smp_ops->setup_cpu(boot_cpuid); smp_ops->setup_cpu(boot_cpuid);
set_cpus_allowed(current, old_mask); set_cpus_allowed(current, old_mask);
......
...@@ -81,10 +81,14 @@ static int udbg_550_getc(void) ...@@ -81,10 +81,14 @@ static int udbg_550_getc(void)
void udbg_init_uart(void __iomem *comport, unsigned int speed, void udbg_init_uart(void __iomem *comport, unsigned int speed,
unsigned int clock) unsigned int clock)
{ {
unsigned int dll, base_bauds = clock / 16; unsigned int dll, base_bauds;
if (clock == 0)
clock = 1843200;
if (speed == 0) if (speed == 0)
speed = 9600; speed = 9600;
base_bauds = clock / 16;
dll = base_bauds / speed; dll = base_bauds / speed;
if (comport) { if (comport) {
......
...@@ -320,6 +320,7 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit) ...@@ -320,6 +320,7 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit)
break; break;
} }
if (lmb.memory.region[0].size < lmb.rmo_size)
lmb.rmo_size = lmb.memory.region[0].size; lmb.rmo_size = lmb.memory.region[0].size;
/* And truncate any reserves above the limit also. */ /* And truncate any reserves above the limit also. */
......
...@@ -291,10 +291,6 @@ void __init chrp_setup_arch(void) ...@@ -291,10 +291,6 @@ void __init chrp_setup_arch(void)
pci_create_OF_bus_map(); pci_create_OF_bus_map();
#ifdef CONFIG_SMP
smp_ops = &chrp_smp_ops;
#endif /* CONFIG_SMP */
/* /*
* Print the banner, then scroll down so boot progress * Print the banner, then scroll down so boot progress
* can be printed. -- Cort * can be printed. -- Cort
...@@ -479,6 +475,14 @@ void __init chrp_init_IRQ(void) ...@@ -479,6 +475,14 @@ void __init chrp_init_IRQ(void)
chrp_find_openpic(); chrp_find_openpic();
chrp_find_8259(); chrp_find_8259();
#ifdef CONFIG_SMP
/* Pegasos has no MPIC, those ops would make it crash. It might be an
* option to move setting them to after we probe the PIC though
*/
if (chrp_mpic != NULL)
smp_ops = &chrp_smp_ops;
#endif /* CONFIG_SMP */
if (_chrp_type == _CHRP_Pegasos) if (_chrp_type == _CHRP_Pegasos)
ppc_md.get_irq = i8259_irq; ppc_md.get_irq = i8259_irq;
......
...@@ -221,6 +221,13 @@ static void __init maple_init_IRQ(void) ...@@ -221,6 +221,13 @@ static void __init maple_init_IRQ(void)
* in Maple device-tree where the type of the controller is * in Maple device-tree where the type of the controller is
* open-pic and not interrupt-controller * open-pic and not interrupt-controller
*/ */
for_each_node_by_type(np, "interrupt-controller")
if (device_is_compatible(np, "open-pic")) {
mpic_node = np;
break;
}
if (mpic_node == NULL)
for_each_node_by_type(np, "open-pic") { for_each_node_by_type(np, "open-pic") {
mpic_node = np; mpic_node = np;
break; break;
...@@ -252,6 +259,8 @@ static void __init maple_init_IRQ(void) ...@@ -252,6 +259,8 @@ static void __init maple_init_IRQ(void)
/* XXX Maple specific bits */ /* XXX Maple specific bits */
flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET; flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET;
/* All U3/U4 are big-endian, older SLOF firmware doesn't encode this */
flags |= MPIC_BIG_ENDIAN;
/* Setup the openpic driver. More device-tree junks, we hard code no /* Setup the openpic driver. More device-tree junks, we hard code no
* ISUs for now. I'll have to revisit some stuffs with the folks doing * ISUs for now. I'll have to revisit some stuffs with the folks doing
......
...@@ -181,13 +181,18 @@ static void __init bootx_add_chosen_props(unsigned long base, ...@@ -181,13 +181,18 @@ static void __init bootx_add_chosen_props(unsigned long base,
} }
static void __init bootx_add_display_props(unsigned long base, static void __init bootx_add_display_props(unsigned long base,
unsigned long *mem_end) unsigned long *mem_end,
int has_real_node)
{ {
boot_infos_t *bi = bootx_info; boot_infos_t *bi = bootx_info;
u32 tmp; u32 tmp;
if (has_real_node) {
bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
} else
bootx_dt_add_prop("linux,bootx-noscreen", NULL, 0, mem_end);
tmp = bi->dispDeviceDepth; tmp = bi->dispDeviceDepth;
bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end); bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end);
tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0]; tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0];
...@@ -241,11 +246,6 @@ static void __init bootx_scan_dt_build_strings(unsigned long base, ...@@ -241,11 +246,6 @@ static void __init bootx_scan_dt_build_strings(unsigned long base,
DBG(" detected display ! adding properties names !\n"); DBG(" detected display ! adding properties names !\n");
bootx_dt_add_string("linux,boot-display", mem_end); bootx_dt_add_string("linux,boot-display", mem_end);
bootx_dt_add_string("linux,opened", mem_end); bootx_dt_add_string("linux,opened", mem_end);
bootx_dt_add_string("linux,bootx-depth", mem_end);
bootx_dt_add_string("linux,bootx-width", mem_end);
bootx_dt_add_string("linux,bootx-height", mem_end);
bootx_dt_add_string("linux,bootx-linebytes", mem_end);
bootx_dt_add_string("linux,bootx-addr", mem_end);
strncpy(bootx_disp_path, namep, 255); strncpy(bootx_disp_path, namep, 255);
} }
...@@ -329,10 +329,13 @@ static void __init bootx_scan_dt_build_struct(unsigned long base, ...@@ -329,10 +329,13 @@ static void __init bootx_scan_dt_build_struct(unsigned long base,
ppp = &pp->next; ppp = &pp->next;
} }
if (node == bootx_node_chosen) if (node == bootx_node_chosen) {
bootx_add_chosen_props(base, mem_end); bootx_add_chosen_props(base, mem_end);
if (node == bootx_info->dispDeviceRegEntryOffset) if (bootx_info->dispDeviceRegEntryOffset == 0)
bootx_add_display_props(base, mem_end); bootx_add_display_props(base, mem_end, 0);
}
else if (node == bootx_info->dispDeviceRegEntryOffset)
bootx_add_display_props(base, mem_end, 1);
/* do all our children */ /* do all our children */
cpp = &np->child; cpp = &np->child;
...@@ -374,6 +377,14 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) ...@@ -374,6 +377,14 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
mem_end += 4; mem_end += 4;
bootx_dt_strend = mem_end; bootx_dt_strend = mem_end;
bootx_scan_dt_build_strings(base, 4, &mem_end); bootx_scan_dt_build_strings(base, 4, &mem_end);
/* Add some strings */
bootx_dt_add_string("linux,bootx-noscreen", &mem_end);
bootx_dt_add_string("linux,bootx-depth", &mem_end);
bootx_dt_add_string("linux,bootx-width", &mem_end);
bootx_dt_add_string("linux,bootx-height", &mem_end);
bootx_dt_add_string("linux,bootx-linebytes", &mem_end);
bootx_dt_add_string("linux,bootx-addr", &mem_end);
/* Wrap up strings */
hdr->off_dt_strings = bootx_dt_strbase - mem_start; hdr->off_dt_strings = bootx_dt_strbase - mem_start;
hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase; hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
...@@ -471,6 +482,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) ...@@ -471,6 +482,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
if (bi->dispDeviceDepth == 16) if (bi->dispDeviceDepth == 16)
bi->dispDeviceDepth = 15; bi->dispDeviceDepth = 15;
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
ptr = (unsigned long)bi->logicalDisplayBase; ptr = (unsigned long)bi->logicalDisplayBase;
ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes; ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
...@@ -508,6 +520,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) ...@@ -508,6 +520,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
btext_welcome(bi); btext_welcome(bi);
#endif #endif
/* New BootX enters kernel with MMU off, i/os are not allowed /* New BootX enters kernel with MMU off, i/os are not allowed
* here. This hack will have been done by the boostrap anyway. * here. This hack will have been done by the boostrap anyway.
*/ */
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* that is iMac G5 and latest single CPU desktop. * that is iMac G5 and latest single CPU desktop.
*/ */
#undef DEBUG
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -30,13 +32,7 @@ ...@@ -30,13 +32,7 @@
#include <asm/smu.h> #include <asm/smu.h>
#include <asm/pmac_pfunc.h> #include <asm/pmac_pfunc.h>
#undef DEBUG #define DBG(fmt...) pr_debug(fmt)
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif
/* see 970FX user manual */ /* see 970FX user manual */
...@@ -82,8 +78,6 @@ static struct freq_attr* g5_cpu_freqs_attr[] = { ...@@ -82,8 +78,6 @@ static struct freq_attr* g5_cpu_freqs_attr[] = {
/* Power mode data is an array of the 32 bits PCR values to use for /* Power mode data is an array of the 32 bits PCR values to use for
* the various frequencies, retrieved from the device-tree * the various frequencies, retrieved from the device-tree
*/ */
static u32 *g5_pmode_data;
static int g5_pmode_max;
static int g5_pmode_cur; static int g5_pmode_cur;
static void (*g5_switch_volt)(int speed_mode); static void (*g5_switch_volt)(int speed_mode);
...@@ -93,6 +87,11 @@ static int (*g5_query_freq)(void); ...@@ -93,6 +87,11 @@ static int (*g5_query_freq)(void);
static DEFINE_MUTEX(g5_switch_mutex); static DEFINE_MUTEX(g5_switch_mutex);
#ifdef CONFIG_PMAC_SMU
static u32 *g5_pmode_data;
static int g5_pmode_max;
static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
static int g5_fvt_count; /* number of op. points */ static int g5_fvt_count; /* number of op. points */
static int g5_fvt_cur; /* current op. point */ static int g5_fvt_cur; /* current op. point */
...@@ -209,6 +208,16 @@ static int g5_scom_query_freq(void) ...@@ -209,6 +208,16 @@ static int g5_scom_query_freq(void)
return i; return i;
} }
/*
* Fake voltage switching for platforms with missing support
*/
static void g5_dummy_switch_volt(int speed_mode)
{
}
#endif /* CONFIG_PMAC_SMU */
/* /*
* Platform function based voltage switching for PowerMac7,2 & 7,3 * Platform function based voltage switching for PowerMac7,2 & 7,3
*/ */
...@@ -248,6 +257,9 @@ static int g5_pfunc_switch_freq(int speed_mode) ...@@ -248,6 +257,9 @@ static int g5_pfunc_switch_freq(int speed_mode)
struct pmf_args args; struct pmf_args args;
u32 done = 0; u32 done = 0;
unsigned long timeout; unsigned long timeout;
int rc;
DBG("g5_pfunc_switch_freq(%d)\n", speed_mode);
/* If frequency is going up, first ramp up the voltage */ /* If frequency is going up, first ramp up the voltage */
if (speed_mode < g5_pmode_cur) if (speed_mode < g5_pmode_cur)
...@@ -255,9 +267,12 @@ static int g5_pfunc_switch_freq(int speed_mode) ...@@ -255,9 +267,12 @@ static int g5_pfunc_switch_freq(int speed_mode)
/* Do it */ /* Do it */
if (speed_mode == CPUFREQ_HIGH) if (speed_mode == CPUFREQ_HIGH)
pmf_call_one(pfunc_cpu_setfreq_high, NULL); rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL);
else else
pmf_call_one(pfunc_cpu_setfreq_low, NULL); rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL);
if (rc)
printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc);
/* It's an irq GPIO so we should be able to just block here, /* It's an irq GPIO so we should be able to just block here,
* I'll do that later after I've properly tested the IRQ code for * I'll do that later after I've properly tested the IRQ code for
...@@ -296,13 +311,6 @@ static int g5_pfunc_query_freq(void) ...@@ -296,13 +311,6 @@ static int g5_pfunc_query_freq(void)
return val ? CPUFREQ_HIGH : CPUFREQ_LOW; return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
} }
/*
* Fake voltage switching for platforms with missing support
*/
static void g5_dummy_switch_volt(int speed_mode)
{
}
/* /*
* Common interface to the cpufreq core * Common interface to the cpufreq core
...@@ -375,6 +383,8 @@ static struct cpufreq_driver g5_cpufreq_driver = { ...@@ -375,6 +383,8 @@ static struct cpufreq_driver g5_cpufreq_driver = {
}; };
#ifdef CONFIG_PMAC_SMU
static int __init g5_neo2_cpufreq_init(struct device_node *cpus) static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
{ {
struct device_node *cpunode; struct device_node *cpunode;
...@@ -525,6 +535,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) ...@@ -525,6 +535,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
return rc; return rc;
} }
#endif /* CONFIG_PMAC_SMU */
static int __init g5_pm72_cpufreq_init(struct device_node *cpus) static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
{ {
struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
...@@ -533,6 +546,9 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) ...@@ -533,6 +546,9 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
u64 max_freq, min_freq, ih, il; u64 max_freq, min_freq, ih, il;
int has_volt = 1, rc = 0; int has_volt = 1, rc = 0;
DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
" RackMac3,1...\n");
/* Get first CPU node */ /* Get first CPU node */
for (cpunode = NULL; for (cpunode = NULL;
(cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
...@@ -636,6 +652,15 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) ...@@ -636,6 +652,15 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
*/ */
ih = *((u32 *)(eeprom + 0x10)); ih = *((u32 *)(eeprom + 0x10));
il = *((u32 *)(eeprom + 0x20)); il = *((u32 *)(eeprom + 0x20));
/* Check for machines with no useful settings */
if (il == ih) {
printk(KERN_WARNING "cpufreq: No low frequency mode available"
" on this model !\n");
rc = -ENODEV;
goto bail;
}
min_freq = 0; min_freq = 0;
if (ih != 0 && il != 0) if (ih != 0 && il != 0)
min_freq = (max_freq * il) / ih; min_freq = (max_freq * il) / ih;
...@@ -643,7 +668,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) ...@@ -643,7 +668,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
/* Sanity check */ /* Sanity check */
if (min_freq >= max_freq || min_freq < 1000) { if (min_freq >= max_freq || min_freq < 1000) {
printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n"); printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
rc = -ENODEV; rc = -ENXIO;
goto bail; goto bail;
} }
g5_cpu_freqs[0].frequency = max_freq; g5_cpu_freqs[0].frequency = max_freq;
...@@ -690,16 +715,10 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) ...@@ -690,16 +715,10 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
return rc; return rc;
} }
static int __init g5_rm31_cpufreq_init(struct device_node *cpus)
{
/* NYI */
return 0;
}
static int __init g5_cpufreq_init(void) static int __init g5_cpufreq_init(void)
{ {
struct device_node *cpus; struct device_node *cpus;
int rc; int rc = 0;
cpus = of_find_node_by_path("/cpus"); cpus = of_find_node_by_path("/cpus");
if (cpus == NULL) { if (cpus == NULL) {
...@@ -708,12 +727,13 @@ static int __init g5_cpufreq_init(void) ...@@ -708,12 +727,13 @@ static int __init g5_cpufreq_init(void)
} }
if (machine_is_compatible("PowerMac7,2") || if (machine_is_compatible("PowerMac7,2") ||
machine_is_compatible("PowerMac7,3")) machine_is_compatible("PowerMac7,3") ||
machine_is_compatible("RackMac3,1"))
rc = g5_pm72_cpufreq_init(cpus); rc = g5_pm72_cpufreq_init(cpus);
else if (machine_is_compatible("RackMac3,1")) #ifdef CONFIG_PMAC_SMU
rc = g5_rm31_cpufreq_init(cpus);
else else
rc = g5_neo2_cpufreq_init(cpus); rc = g5_neo2_cpufreq_init(cpus);
#endif /* CONFIG_PMAC_SMU */
of_node_put(cpus); of_node_put(cpus);
return rc; return rc;
......
...@@ -501,7 +501,8 @@ static void pseries_dedicated_idle_sleep(void) ...@@ -501,7 +501,8 @@ static void pseries_dedicated_idle_sleep(void)
} }
/* /*
* Cede if the other thread is not idle, so that it can * If not SMT, cede processor. If CPU is running SMT
* cede if the other thread is not idle, so that it can
* go single-threaded. If the other thread is idle, * go single-threaded. If the other thread is idle,
* we ask the hypervisor if it has pending work it * we ask the hypervisor if it has pending work it
* wants to do and cede if it does. Otherwise we keep * wants to do and cede if it does. Otherwise we keep
...@@ -514,7 +515,8 @@ static void pseries_dedicated_idle_sleep(void) ...@@ -514,7 +515,8 @@ static void pseries_dedicated_idle_sleep(void)
* very low priority. The cede enables interrupts, which * very low priority. The cede enables interrupts, which
* doesn't matter here. * doesn't matter here.
*/ */
if (!lppaca[cpu ^ 1].idle || poll_pending() == H_PENDING) if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
|| poll_pending() == H_PENDING)
cede_processor(); cede_processor();
out: out:
......
...@@ -774,20 +774,6 @@ config BLK_DEV_IDEDMA_PMAC ...@@ -774,20 +774,6 @@ config BLK_DEV_IDEDMA_PMAC
to transfer data to and from memory. Saying Y is safe and improves to transfer data to and from memory. Saying Y is safe and improves
performance. performance.
config BLK_DEV_IDE_PMAC_BLINK
bool "Blink laptop LED on drive activity (DEPRECATED)"
depends on BLK_DEV_IDE_PMAC && ADB_PMU
select ADB_PMU_LED
select LEDS_TRIGGERS
select LEDS_TRIGGER_IDE_DISK
help
This option enables the use of the sleep LED as a hard drive
activity LED.
This option is deprecated, it only selects ADB_PMU_LED and
LEDS_TRIGGER_IDE_DISK and changes the code in the new led class
device to default to the ide-disk trigger (which should be set
from userspace via sysfs).
config BLK_DEV_IDE_SWARM config BLK_DEV_IDE_SWARM
tristate "IDE for Sibyte evaluation boards" tristate "IDE for Sibyte evaluation boards"
depends on SIBYTE_SB1xxx_SOC depends on SIBYTE_SB1xxx_SOC
......
...@@ -90,6 +90,15 @@ config ADB_PMU_LED ...@@ -90,6 +90,15 @@ config ADB_PMU_LED
and the ide-disk LED trigger and configure appropriately through and the ide-disk LED trigger and configure appropriately through
sysfs. sysfs.
config ADB_PMU_LED_IDE
bool "Use front LED as IDE LED by default"
depends on ADB_PMU_LED
select LEDS_TRIGGERS
select LEDS_TRIGGER_IDE_DISK
help
This option makes the front LED default to the IDE trigger
so that it blinks on IDE activity.
config PMAC_SMU config PMAC_SMU
bool "Support for SMU based PowerMacs" bool "Support for SMU based PowerMacs"
depends on PPC_PMAC64 depends on PPC_PMAC64
...@@ -100,7 +109,7 @@ config PMAC_SMU ...@@ -100,7 +109,7 @@ config PMAC_SMU
config PMAC_APM_EMU config PMAC_APM_EMU
tristate "APM emulation" tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM depends on PPC_PMAC && PPC32 && PM && ADB_PMU
config PMAC_MEDIABAY config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay" bool "Support PowerBook hotswap media bay"
......
This diff is collapsed.
...@@ -105,6 +105,7 @@ static char * critical_overtemp_path = "/sbin/critical_overtemp"; ...@@ -105,6 +105,7 @@ static char * critical_overtemp_path = "/sbin/critical_overtemp";
#define DRIVES_DALLAS_ID 0x94 #define DRIVES_DALLAS_ID 0x94
#define BACKSIDE_MAX_ID 0x98 #define BACKSIDE_MAX_ID 0x98
#define XSERVE_DIMMS_LM87 0x25a #define XSERVE_DIMMS_LM87 0x25a
#define XSERVE_SLOTS_LM75 0x290
/* /*
* Some MAX6690, DS1775, LM87 register definitions * Some MAX6690, DS1775, LM87 register definitions
...@@ -198,7 +199,7 @@ struct drives_pid_state ...@@ -198,7 +199,7 @@ struct drives_pid_state
#define SLOTS_FAN_PWM_DEFAULT_ID 2 #define SLOTS_FAN_PWM_DEFAULT_ID 2
#define SLOTS_FAN_PWM_INDEX 2 #define SLOTS_FAN_PWM_INDEX 2
#define SLOTS_FAN_DEFAULT_PWM 50 /* Do better here ! */ #define SLOTS_FAN_DEFAULT_PWM 40 /* Do better here ! */
/* /*
...@@ -206,7 +207,7 @@ struct drives_pid_state ...@@ -206,7 +207,7 @@ struct drives_pid_state
*/ */
#define DIMM_PID_G_d 0 #define DIMM_PID_G_d 0
#define DIMM_PID_G_p 0 #define DIMM_PID_G_p 0
#define DIMM_PID_G_r 0x6553600 #define DIMM_PID_G_r 0x06553600
#define DIMM_PID_INPUT_TARGET 3276800 #define DIMM_PID_INPUT_TARGET 3276800
#define DIMM_PID_INTERVAL 1 #define DIMM_PID_INTERVAL 1
#define DIMM_PID_OUTPUT_MAX 14000 #define DIMM_PID_OUTPUT_MAX 14000
...@@ -226,6 +227,31 @@ struct dimm_pid_state ...@@ -226,6 +227,31 @@ struct dimm_pid_state
}; };
/*
* PID factors for the Xserve Slots control loop
*/
#define SLOTS_PID_G_d 0
#define SLOTS_PID_G_p 0
#define SLOTS_PID_G_r 0x00100000
#define SLOTS_PID_INPUT_TARGET 3200000
#define SLOTS_PID_INTERVAL 1
#define SLOTS_PID_OUTPUT_MAX 100
#define SLOTS_PID_OUTPUT_MIN 20
#define SLOTS_PID_HISTORY_SIZE 20
struct slots_pid_state
{
int ticks;
struct i2c_client * monitor;
s32 sample_history[SLOTS_PID_HISTORY_SIZE];
s32 error_history[SLOTS_PID_HISTORY_SIZE];
int cur_sample;
s32 last_temp;
int first;
int pwm;
};
/* Desktops */ /* Desktops */
...@@ -283,6 +309,9 @@ struct cpu_pid_state ...@@ -283,6 +309,9 @@ struct cpu_pid_state
s32 pump_max; s32 pump_max;
}; };
/* Tickle FCU every 10 seconds */
#define FCU_TICKLE_TICKS 10
/* /*
* Driver state * Driver state
*/ */
......
...@@ -74,7 +74,7 @@ static void pmu_led_set(struct led_classdev *led_cdev, ...@@ -74,7 +74,7 @@ static void pmu_led_set(struct led_classdev *led_cdev,
static struct led_classdev pmu_led = { static struct led_classdev pmu_led = {
.name = "pmu-front-led", .name = "pmu-front-led",
#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK #ifdef CONFIG_ADB_PMU_LED_IDE
.default_trigger = "ide-disk", .default_trigger = "ide-disk",
#endif #endif
.brightness_set = pmu_led_set, .brightness_set = pmu_led_set,
......
This diff is collapsed.
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