diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 3f25f7fc79fc..e5de31aa0015 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -1307,11 +1308,14 @@ int iSeries_set_rtc_time(struct rtc_time *tm) return 0; } -void iSeries_get_boot_time(struct rtc_time *tm) +unsigned long iSeries_get_boot_time(void) { - if (piranha_simulator) - return; + struct rtc_time tm; - mf_get_boot_rtc(tm); - tm->tm_mon -= 1; + if (piranha_simulator) + return 0; + + mf_get_boot_rtc(&tm); + return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); } diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 93852c2ee5de..41cd5b689545 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -73,8 +73,8 @@ extern void hvlog(char *fmt, ...); extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); -static int iseries_shared_idle(void); -static int iseries_dedicated_idle(void); +static void iseries_shared_idle(void); +static void iseries_dedicated_idle(void); #ifdef CONFIG_PCI extern void iSeries_pci_final_fixup(void); #else @@ -693,7 +693,7 @@ static void yield_shared_processor(void) process_iSeries_events(); } -static int iseries_shared_idle(void) +static void iseries_shared_idle(void) { while (1) { while (!need_resched() && !hvlpevent_is_pending()) { @@ -715,11 +715,9 @@ static int iseries_shared_idle(void) schedule(); } - - return 0; } -static int iseries_dedicated_idle(void) +static void iseries_dedicated_idle(void) { long oldval; @@ -749,8 +747,6 @@ static int iseries_dedicated_idle(void) ppc64_runlatch_on(); schedule(); } - - return 0; } #ifndef CONFIG_PCI diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h index 6da89ae991ce..5213044ec411 100644 --- a/arch/powerpc/platforms/iseries/setup.h +++ b/arch/powerpc/platforms/iseries/setup.h @@ -17,7 +17,7 @@ #ifndef __ISERIES_SETUP_H__ #define __ISERIES_SETUP_H__ -extern void iSeries_get_boot_time(struct rtc_time *tm); +extern unsigned long iSeries_get_boot_time(void); extern int iSeries_set_rtc_time(struct rtc_time *tm); extern void iSeries_get_rtc_time(struct rtc_time *tm); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 81f52512b046..0a9ba704865e 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -10,9 +10,12 @@ * pmac_* files. Mostly for use by pmac_setup */ +struct rtc_time; + extern long pmac_time_init(void); -extern unsigned long pmac_get_rtc_time(void); -extern int pmac_set_rtc_time(unsigned long nowtime); +extern unsigned long pmac_get_boot_time(void); +extern void pmac_get_rtc_time(struct rtc_time *); +extern int pmac_set_rtc_time(struct rtc_time *); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); extern void pmac_pcibios_fixup(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 7eb0c34b6994..b6414e7c37d4 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -562,7 +562,6 @@ void __init pmac_init(void) ppc_md.setup_arch = pmac_setup_arch; ppc_md.show_cpuinfo = pmac_show_cpuinfo; ppc_md.show_percpuinfo = pmac_show_percpuinfo; - ppc_md.irq_canonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ @@ -578,6 +577,7 @@ void __init pmac_init(void) ppc_md.time_init = pmac_time_init; ppc_md.set_rtc_time = pmac_set_rtc_time; ppc_md.get_rtc_time = pmac_get_rtc_time; + ppc_md.get_boot_time = pmac_get_boot_time; ppc_md.calibrate_decr = pmac_calibrate_decr; ppc_md.feature_call = pmac_do_feature_call; diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index edb9fcc64790..3ee6d8aa14c4 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -77,8 +77,7 @@ pmac_time_init(void) #endif } -unsigned long -pmac_get_rtc_time(void) +unsigned long pmac_get_boot_time(void) { #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; @@ -118,20 +117,33 @@ pmac_get_rtc_time(void) return 0; } -int -pmac_set_rtc_time(unsigned long nowtime) +void pmac_get_rtc_time(struct rtc_time *tm) { + unsigned long now; + + now = pmac_get_boot_time(); + to_tm(now, tm); + tm->tm_year -= 1900; + tm->tm_mon -= 1; /* month is 0-based */ +} + +int pmac_set_rtc_time(struct rtc_time *tm) +{ + unsigned long nowtime; #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; #endif + nowtime = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); nowtime += RTC_OFFSET; switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, - nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + nowtime >> 24, nowtime >> 16, nowtime >> 8, + nowtime) < 0) return 0; while (!req.complete) cuda_poll(); @@ -221,7 +233,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) case PBOOK_SLEEP_NOW: do { seq = read_seqbegin_irqsave(&xtime_lock, flags); - time_diff = xtime.tv_sec - pmac_get_rtc_time(); + time_diff = xtime.tv_sec - pmac_get_boot_time(); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); break; case PBOOK_WAKE: diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index eb25ee2eead8..0c84a44b43b4 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -84,8 +84,8 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */ extern void pSeries_system_reset_exception(struct pt_regs *regs); extern int pSeries_machine_check_exception(struct pt_regs *regs); -static int pseries_shared_idle(void); -static int pseries_dedicated_idle(void); +static void pseries_shared_idle(void); +static void pseries_dedicated_idle(void); static volatile void __iomem * chrp_int_ack_special; struct mpic *pSeries_mpic; @@ -488,8 +488,8 @@ static inline void dedicated_idle_sleep(unsigned int cpu) } } -static int pseries_dedicated_idle(void) -{ +static void pseries_dedicated_idle(void) +{ long oldval; struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); @@ -544,7 +544,7 @@ static int pseries_dedicated_idle(void) } } -static int pseries_shared_idle(void) +static void pseries_shared_idle(void) { struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); @@ -586,8 +586,6 @@ static int pseries_shared_idle(void) if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } static int pSeries_pci_probe_mode(struct pci_bus *bus) diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 954395d42636..8abd2ad92832 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -31,7 +31,7 @@ extern void power4_idle(void); -int default_idle(void) +void default_idle(void) { long oldval; unsigned int cpu = smp_processor_id(); @@ -64,11 +64,9 @@ int default_idle(void) if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } -int native_idle(void) +void native_idle(void) { while (1) { ppc64_runlatch_off(); @@ -85,8 +83,6 @@ int native_idle(void) system_state == SYSTEM_RUNNING) cpu_die(); } - - return 0; } void cpu_idle(void) diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c index 22987675f544..a107ed69a355 100644 --- a/arch/ppc64/kernel/maple_setup.c +++ b/arch/ppc64/kernel/maple_setup.c @@ -70,7 +70,7 @@ extern int maple_set_rtc_time(struct rtc_time *tm); extern void maple_get_rtc_time(struct rtc_time *tm); -extern void maple_get_boot_time(struct rtc_time *tm); +extern unsigned long maple_get_boot_time(void); extern void maple_calibrate_decr(void); extern void maple_pci_init(void); extern void maple_pcibios_fixup(void); diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c index d65210abcd03..cf5186335900 100644 --- a/arch/ppc64/kernel/maple_time.c +++ b/arch/ppc64/kernel/maple_time.c @@ -156,8 +156,9 @@ int maple_set_rtc_time(struct rtc_time *tm) return 0; } -void __init maple_get_boot_time(struct rtc_time *tm) +unsigned long __init maple_get_boot_time(void) { + struct rtc_time tm; struct device_node *rtcs; rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); @@ -170,6 +171,8 @@ void __init maple_get_boot_time(struct rtc_time *tm) "legacy address (0x%x)\n", maple_rtc_addr); } - maple_get_rtc_time(tm); + maple_get_rtc_time(&tm); + return mktime(time->tm_year+1900, time->tm_mon+1, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); } diff --git a/arch/ppc64/kernel/pmac.h b/arch/ppc64/kernel/pmac.h index 40e1c5030f74..fa59f2a5c722 100644 --- a/arch/ppc64/kernel/pmac.h +++ b/arch/ppc64/kernel/pmac.h @@ -9,7 +9,7 @@ * pmac_* files. Mostly for use by pmac_setup */ -extern void pmac_get_boot_time(struct rtc_time *tm); +extern unsigned long pmac_get_boot_time(void); extern void pmac_get_rtc_time(struct rtc_time *tm); extern int pmac_set_rtc_time(struct rtc_time *tm); extern void pmac_read_rtc_time(void); diff --git a/arch/ppc64/kernel/pmac_nvram.c b/arch/ppc64/kernel/pmac_nvram.c index 11586d535f81..5fe9785ad7d8 100644 --- a/arch/ppc64/kernel/pmac_nvram.c +++ b/arch/ppc64/kernel/pmac_nvram.c @@ -341,7 +341,7 @@ static int amd_write_bank(int bank, u8* datas) } -static int core99_nvram_sync(void) +static void core99_nvram_sync(void) { struct core99_header* hdr99; unsigned long flags; @@ -369,8 +369,6 @@ static int core99_nvram_sync(void) printk("nvram: Error writing bank %d\n", core99_bank); bail: spin_unlock_irqrestore(&nv_lock, flags); - - return 0; } int __init pmac_nvram_init(void) diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c index 9d8c97decd32..c89bfefbbecd 100644 --- a/arch/ppc64/kernel/pmac_time.c +++ b/arch/ppc64/kernel/pmac_time.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -135,23 +136,13 @@ int pmac_set_rtc_time(struct rtc_time *tm) } } -void __init pmac_get_boot_time(struct rtc_time *tm) +unsigned long __init pmac_get_boot_time(void) { - pmac_get_rtc_time(tm); + struct rtc_time tm; -#ifdef disabled__CONFIG_NVRAM - s32 delta = 0; - int dst; - - delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; - delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; - delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); - if (delta & 0x00800000UL) - delta |= 0xFF000000UL; - dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); - printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, - dst ? "on" : "off"); -#endif + pmac_get_rtc_time(&tm); + return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); } /* diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c index 1f3ff860fdf0..5bdd5b079d96 100644 --- a/arch/ppc64/kernel/rtas-proc.c +++ b/arch/ppc64/kernel/rtas-proc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 88ae13f81c46..79e7ed2858dd 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -265,7 +265,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, #ifdef CONFIG_PPC_RTAS #define MAX_RTC_WAIT 5000 /* 5 sec */ #define RTAS_CLOCK_BUSY (-2) -void rtas_get_boot_time(struct rtc_time *rtc_tm) +unsigned long rtas_get_boot_time(void) { int ret[8]; int error, wait_time; @@ -285,15 +285,10 @@ void rtas_get_boot_time(struct rtc_time *rtc_tm) if (error != 0 && printk_ratelimit()) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", error); - return; + return 0; } - rtc_tm->tm_sec = ret[5]; - rtc_tm->tm_min = ret[4]; - rtc_tm->tm_hour = ret[3]; - rtc_tm->tm_mday = ret[2]; - rtc_tm->tm_mon = ret[1] - 1; - rtc_tm->tm_year = ret[0] - 1900; + return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]); } /* NOTE: get_rtc_time will get an error if executed in interrupt context diff --git a/include/asm-ppc64/machdep.h b/include/asm-powerpc/machdep.h similarity index 59% rename from include/asm-ppc64/machdep.h rename to include/asm-powerpc/machdep.h index d35d9d3e44cf..f060553b997a 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-powerpc/machdep.h @@ -1,6 +1,6 @@ -#ifdef __KERNEL__ #ifndef _PPC64_MACHDEP_H #define _PPC64_MACHDEP_H +#ifdef __KERNEL__ /* * This program is free software; you can redistribute it and/or @@ -16,6 +16,11 @@ #include +/* We export this macro for external modules like Alsa to know if + * ppc_md.feature_call is implemented or not + */ +#define CONFIG_PPC_HAS_FEATURE_CALLS + struct pt_regs; struct pci_bus; struct device_node; @@ -39,6 +44,7 @@ struct smp_ops_t { #endif struct machdep_calls { +#ifdef CONFIG_PPC64 void (*hpte_invalidate)(unsigned long slot, unsigned long va, int large, @@ -74,6 +80,7 @@ struct machdep_calls { void (*iommu_dev_setup)(struct pci_dev *dev); void (*iommu_bus_setup)(struct pci_bus *bus); void (*irq_bus_setup)(struct pci_bus *bus); +#endif int (*probe)(int platform); void (*setup_arch)(void); @@ -86,6 +93,7 @@ struct machdep_calls { void (*cpu_irq_down)(int secondary); /* PCI stuff */ + /* Called after scanning the bus, before allocating resources */ void (*pcibios_fixup)(void); int (*pci_probe_mode)(struct pci_bus *); @@ -95,9 +103,13 @@ struct machdep_calls { void (*panic)(char *str); void (*cpu_die)(void); + long (*time_init)(void); /* Optional, may be NULL */ + int (*set_rtc_time)(struct rtc_time *); void (*get_rtc_time)(struct rtc_time *); - void (*get_boot_time)(struct rtc_time *); + unsigned long (*get_boot_time)(void); + unsigned char (*rtc_read_val)(int addr); + void (*rtc_write_val)(int addr, unsigned char val); void (*calibrate_decr)(void); @@ -109,7 +121,7 @@ struct machdep_calls { ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_size)(void); - int (*nvram_sync)(void); + void (*nvram_sync)(void); /* Exception handlers */ void (*system_reset_exception)(struct pt_regs *regs); @@ -134,14 +146,100 @@ struct machdep_calls { pgprot_t vma_prot); /* Idle loop for this platform, leave empty for default idle loop */ - int (*idle_loop)(void); + void (*idle_loop)(void); - /* Function to enable pmcs for this platform, called once per cpu. */ + /* Function to enable performance monitor counters for this + platform, called once per cpu. */ void (*enable_pmcs)(void); + +#ifdef CONFIG_PPC32 /* XXX for now */ + /* Optional, may be NULL. */ + int (*show_cpuinfo)(struct seq_file *m); + int (*show_percpuinfo)(struct seq_file *m, int i); + + /* 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; + + unsigned long (*find_end_of_memory)(void); + void (*setup_io_mappings)(void); + + void (*early_serial_map)(void); + void (*kgdb_map_scc)(void); + + unsigned char (*nvram_read_val)(int addr); + void (*nvram_write_val)(int addr, unsigned char val); + + /* + * optional PCI "hooks" + */ + + /* Called after PPC generic resource fixup to perform + machine specific fixups */ + void (*pcibios_fixup_resources)(struct pci_dev *); + + /* Called for each PCI bus in the system when it's probed */ + void (*pcibios_fixup_bus)(struct pci_bus *); + + /* Called when pci_enable_device() is called (initial=0) or + * when a device with no assigned resource is found (initial=1). + * Returns 0 to allow assignment/enabling of the device. */ + int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); + + /* For interrupt routing */ + unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *); + int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char); + + /* Called in indirect_* to avoid touching devices */ + int (*pci_exclude_device)(unsigned char, unsigned char); + + /* Called at then very end of pcibios_init() */ + void (*pcibios_after_init)(void); + + /* this is for modules, since _machine can be a define -- Cort */ + int ppc_machine; + +#ifdef CONFIG_KEXEC + /* Called to shutdown machine specific hardware not already controlled + * by other drivers. + * XXX Should we move this one out of kexec scope? + */ + void (*machine_shutdown)(void); + + /* Called to do the minimal shutdown needed to run a kexec'd kernel + * to run successfully. + * XXX Should we move this one out of kexec scope? + */ + void (*machine_crash_shutdown)(void); + + /* Called to do what every setup is needed on image and the + * reboot code buffer. Returns 0 on success. + * Provide your own (maybe dummy) implementation if your platform + * claims to support kexec. + */ + int (*machine_kexec_prepare)(struct kimage *image); + + /* Called to handle any machine specific cleanup on image */ + void (*machine_kexec_cleanup)(struct kimage *image); + + /* Called to perform the _real_ kexec. + * Do NOT allocate memory or fail here. We are past the point of + * no return. + */ + void (*machine_kexec)(struct kimage *image); +#endif /* CONFIG_KEXEC */ +#endif /* CONFIG_PPC32 */ }; -extern int default_idle(void); -extern int native_idle(void); +extern void default_idle(void); +extern void native_idle(void); extern struct machdep_calls ppc_md; extern char cmd_line[COMMAND_LINE_SIZE]; @@ -161,6 +259,13 @@ extern sys_ctrler_t sys_ctrler; #endif /* CONFIG_PPC_PMAC */ +extern void setup_pci_ptrs(void); + +#ifdef CONFIG_SMP +/* Poor default implementations */ +extern void __devinit smp_generic_give_timebase(void); +extern void __devinit smp_generic_take_timebase(void); +#endif /* CONFIG_SMP */ /* Functions to produce codes on the leds. @@ -180,5 +285,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal) ppc_md.log_error(buf, err_type, fatal); } -#endif /* _PPC64_MACHDEP_H */ #endif /* __KERNEL__ */ +#endif /* _PPC64_MACHDEP_H */ diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h index 5c904d371963..2c050332471d 100644 --- a/include/asm-powerpc/rtas.h +++ b/include/asm-powerpc/rtas.h @@ -190,7 +190,7 @@ extern void rtas_progress(char *s, unsigned short hex); extern void rtas_initialize(void); struct rtc_time; -extern void rtas_get_boot_time(struct rtc_time *rtc_time); +extern unsigned long rtas_get_boot_time(void); extern void rtas_get_rtc_time(struct rtc_time *rtc_time); extern int rtas_set_rtc_time(struct rtc_time *rtc_time);