diff options
Diffstat (limited to 'arch')
1258 files changed, 19407 insertions, 8443 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 26b0e23..4b0669c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -178,4 +178,7 @@ config HAVE_ARCH_MUTEX_CPU_RELAX config HAVE_RCU_TABLE_FREE bool +config ARCH_HAVE_NMI_SAFE_CMPXCHG + bool + source "kernel/gcov/Kconfig" diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index ca2da8d..8bb9362 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -14,6 +14,7 @@ config ALPHA select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_HAVE_NMI_SAFE_CMPXCHG help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, @@ -50,7 +51,7 @@ config GENERIC_CMOS_UPDATE def_bool y config GENERIC_GPIO - def_bool y + bool config ZONE_DMA bool diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index e756d04..640f909 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -176,15 +176,15 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -196,10 +196,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /** * atomic64_add_unless - add unless the number is a given value @@ -208,7 +207,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) { @@ -256,5 +255,4 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() -#include <asm-generic/atomic-long.h> #endif /* _ALPHA_ATOMIC_H */ diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 85b8152..a19ba5e 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h @@ -456,8 +456,7 @@ sched_find_first_bit(const unsigned long b[2]) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) -#define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/alpha/include/asm/local.h b/arch/alpha/include/asm/local.h index b9e3e33..9c94b84 100644 --- a/arch/alpha/include/asm/local.h +++ b/arch/alpha/include/asm/local.h @@ -2,7 +2,7 @@ #define _ALPHA_LOCAL_H #include <linux/percpu.h> -#include <asm/atomic.h> +#include <linux/atomic.h> typedef struct { diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h index 65cf3e2..fd698a1 100644 --- a/arch/alpha/include/asm/ptrace.h +++ b/arch/alpha/include/asm/ptrace.h @@ -72,7 +72,6 @@ struct switch_stack { #define user_mode(regs) (((regs)->ps & 8) != 0) #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); #define task_pt_regs(task) \ ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) diff --git a/arch/alpha/include/asm/sysinfo.h b/arch/alpha/include/asm/sysinfo.h index 086aba2..e77d77c 100644 --- a/arch/alpha/include/asm/sysinfo.h +++ b/arch/alpha/include/asm/sysinfo.h @@ -27,13 +27,4 @@ #define UAC_NOFIX 2 #define UAC_SIGBUS 4 - -#ifdef __KERNEL__ - -/* This is the shift that is applied to the UAC bits as stored in the - per-thread flags. See thread_info.h. */ -#define UAC_SHIFT 6 - -#endif - #endif /* __ASM_ALPHA_SYSINFO_H */ diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 6f32f9c..ff73db0 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -74,9 +74,9 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */ #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ -#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */ -#define TIF_UAC_NOFIX 11 -#define TIF_UAC_SIGBUS 12 +#define TIF_UAC_NOPRINT 10 /* ! Preserve sequence of following */ +#define TIF_UAC_NOFIX 11 /* ! flags as they match */ +#define TIF_UAC_SIGBUS 12 /* ! userspace part of 'osf_sysinfo' */ #define TIF_MEMDIE 13 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */ #define TIF_FREEZE 16 /* is freezing for suspend */ @@ -97,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ | _TIF_SYSCALL_TRACE) -#define ALPHA_UAC_SHIFT 10 +#define ALPHA_UAC_SHIFT TIF_UAC_NOPRINT #define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \ 1 << TIF_UAC_SIGBUS) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 326f0a2..01e8715 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -42,6 +42,7 @@ #include <asm/uaccess.h> #include <asm/system.h> #include <asm/sysinfo.h> +#include <asm/thread_info.h> #include <asm/hwrpb.h> #include <asm/processor.h> @@ -633,9 +634,10 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer, case GSI_UACPROC: if (nbytes < sizeof(unsigned int)) return -EINVAL; - w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK; - if (put_user(w, (unsigned int __user *)buffer)) - return -EFAULT; + w = (current_thread_info()->flags >> ALPHA_UAC_SHIFT) & + UAC_BITMASK; + if (put_user(w, (unsigned int __user *)buffer)) + return -EFAULT; return 1; case GSI_PROC_TYPE: @@ -756,8 +758,8 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, case SSIN_UACPROC: again: old = current_thread_info()->flags; - new = old & ~(UAC_BITMASK << UAC_SHIFT); - new = new | (w & UAC_BITMASK) << UAC_SHIFT; + new = old & ~(UAC_BITMASK << ALPHA_UAC_SHIFT); + new = new | (w & UAC_BITMASK) << ALPHA_UAC_SHIFT; if (cmpxchg(¤t_thread_info()->flags, old, new) != old) goto again; diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 8e47709..8143cd7 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c @@ -17,7 +17,7 @@ #include <linux/init.h> #include <asm/hwrpb.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/irq_regs.h> #include <asm/pal.h> diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index d739703..4087a56 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -31,7 +31,7 @@ #include <asm/hwrpb.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 0e14399..8606d77 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -183,7 +183,7 @@ alcor_init_irq(void) */ static int __init -alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index c8c112d..1029619 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -175,7 +175,7 @@ pc164_init_irq(void) */ static inline int __init -eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -205,7 +205,7 @@ eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) */ static inline int __init -cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +cabriolet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -289,7 +289,7 @@ cia_cab_init_pci(void) */ static inline int __init -alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +alphapc164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index f885682..bb7f0c7 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -382,7 +382,7 @@ isa_irq_fixup(struct pci_dev *dev, int irq) } static int __init -dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[6][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -404,7 +404,7 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } static int __init -monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[13][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -466,7 +466,7 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp) } static int __init -webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[13][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -488,7 +488,7 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } static int __init -clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[7][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index a7a23b4..3c6c13c 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -169,7 +169,7 @@ eb64p_init_irq(void) */ static int __init -eb64p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index a60cd5b..35f480d 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -144,7 +144,7 @@ eiger_init_irq(void) } static int __init -eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u8 irq_orig; diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 388b99d..95cfc83 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -318,7 +318,7 @@ marvel_init_irq(void) } static int -marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *hose = dev->sysdata; struct io7_port *io7_port = hose->sysdata; diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index 61ccd95..258da68 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -151,7 +151,7 @@ miata_init_irq(void) */ static int __init -miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[18][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index 0e6e469..c0fd728 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -146,7 +146,7 @@ mikasa_init_irq(void) */ static int __init -mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[8][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 99c0f46..4112200 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -65,7 +65,7 @@ nautilus_init_irq(void) } static int __init -nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* Preserve the IRQ set up by the console. */ diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index a00ac70..2172528 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -194,7 +194,7 @@ noritake_init_irq(void) */ static int __init -noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[15][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 7f52161..a125d6b 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -223,7 +223,7 @@ rawhide_init_irq(void) */ static int __init -rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index f33648e..2581cbe 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c @@ -119,7 +119,7 @@ ruffian_kill_arch (int mode) */ static int __init -ruffian_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[11][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 216d94d..b172b27 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -144,7 +144,7 @@ rx164_init_irq(void) */ static int __init -rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { #if 0 static char irq_tab_pass1[6][5] __initdata = { diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index da714e4..98d1dbf 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -194,7 +194,7 @@ sable_init_irq(void) */ static int __init -sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[9][5] __initdata = { /*INT INTA INTB INTC INTD */ @@ -376,7 +376,7 @@ lynx_init_irq(void) */ static int __init -lynx_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[19][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index 85b4aea..47bec1e 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -146,7 +146,7 @@ sio_fixup_irq_levels(unsigned int level_bits) } static inline int __init -noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The Noname board has 5 PCI slots with each of the 4 @@ -185,7 +185,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) } static inline int __init -p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[][5] __initdata = { /*INT A B C D */ diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index 41d4ad4..73e1c31 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -95,7 +95,7 @@ sx164_init_irq(void) */ static int __init -sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[5][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index a31f8cd..2ae99ad 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -157,7 +157,7 @@ takara_init_irq(void) */ static int __init -takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) +takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[15][5] __initdata = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ @@ -188,7 +188,7 @@ takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) } static int __init -takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +takara_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[15][5] __initdata = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 6994407..f47b30a 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -305,7 +305,7 @@ titan_late_init(void) } static int __devinit -titan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +titan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u8 intline; int irq; diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index d92cdc7..17c85a6 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -290,7 +290,7 @@ wildfire_device_interrupt(unsigned long vector) */ static int __init -wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static char irq_tab[8][5] __initdata = { /*INT INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index b9c28f3..6acea1f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -360,7 +360,7 @@ sys_call_table: .quad sys_newuname .quad sys_nanosleep /* 340 */ .quad sys_mremap - .quad sys_nfsservctl + .quad sys_ni_syscall /* old nfsservctl */ .quad sys_setresuid .quad sys_getresuid .quad sys_pciconfig_read /* 345 */ diff --git a/arch/alpha/lib/dec_and_lock.c b/arch/alpha/lib/dec_and_lock.c index 0f5520d..f9f5fe8 100644 --- a/arch/alpha/lib/dec_and_lock.c +++ b/arch/alpha/lib/dec_and_lock.c @@ -6,7 +6,7 @@ */ #include <linux/spinlock.h> -#include <asm/atomic.h> +#include <linux/atomic.h> asm (".text \n\ .global _atomic_dec_and_lock \n\ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9cb1f4b..3269576 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -195,8 +195,7 @@ config VECTORS_BASE The base address of exception vectors. config ARM_PATCH_PHYS_VIRT - bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)" - depends on EXPERIMENTAL + bool "Patch physical to virtual translations at runtime" depends on !XIP_KERNEL && MMU depends on !ARCH_REALVIEW || !SPARSEMEM help @@ -242,6 +241,7 @@ config ARCH_INTEGRATOR select ARM_AMBA select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select ICST select GENERIC_CLOCKEVENTS select PLAT_VERSATILE @@ -253,6 +253,7 @@ config ARCH_REALVIEW bool "ARM Ltd. RealView family" select ARM_AMBA select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB @@ -268,6 +269,7 @@ config ARCH_VERSATILE select ARM_AMBA select ARM_VIC select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB @@ -284,6 +286,7 @@ config ARCH_VEXPRESS select ARM_AMBA select ARM_TIMER_SP804 select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select GENERIC_CLOCKEVENTS select HAVE_CLK select HAVE_PATA_PLATFORM @@ -324,7 +327,7 @@ config ARCH_CLPS711X config ARCH_CNS3XXX bool "Cavium Networks CNS3XXX family" - select CPU_V6 + select CPU_V6K select GENERIC_CLOCKEVENTS select ARM_GIC select MIGHT_HAVE_PCI @@ -340,6 +343,19 @@ config ARCH_GEMINI help Support for the Cortina Systems Gemini family SoCs +config ARCH_PRIMA2 + bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform" + select CPU_V7 + select GENERIC_TIME + select NO_IOPORT + select GENERIC_CLOCKEVENTS + select CLKDEV_LOOKUP + select GENERIC_IRQ_CHIP + select USE_OF + select ZONE_DMA + help + Support for CSR SiRFSoC ARM Cortex A9 Platform + config ARCH_EBSA110 bool "EBSA-110" select CPU_SA110 @@ -379,6 +395,7 @@ config ARCH_MXC select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP select CLKSRC_MMIO + select GENERIC_IRQ_CHIP select HAVE_SCHED_CLOCK help Support for Freescale MXC/iMX-based family of processors @@ -586,7 +603,6 @@ config ARCH_TEGRA select GENERIC_GPIO select HAVE_CLK select HAVE_SCHED_CLOCK - select ARCH_HAS_BARRIERS if CACHE_L2X0 select ARCH_HAS_CPUFREQ help This enables support for NVIDIA Tegra based systems (Tegra APX, @@ -613,6 +629,8 @@ config ARCH_PXA select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ + select AUTO_ZRELADDR + select MULTI_IRQ_HANDLER help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. @@ -633,6 +651,7 @@ config ARCH_SHMOBILE bool "Renesas SH-Mobile / R-Mobile" select HAVE_CLK select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select GENERIC_CLOCKEVENTS select NO_IOPORT select SPARSE_IRQ @@ -750,6 +769,7 @@ config ARCH_S5PV210 bool "Samsung S5PV210/S5PC110" select CPU_V7 select ARCH_SPARSEMEM_ENABLE + select ARCH_HAS_HOLES_MEMORYMODEL select GENERIC_GPIO select HAVE_CLK select CLKDEV_LOOKUP @@ -768,6 +788,7 @@ config ARCH_EXYNOS4 bool "Samsung EXYNOS4" select CPU_V7 select ARCH_SPARSEMEM_ENABLE + select ARCH_HAS_HOLES_MEMORYMODEL select GENERIC_GPIO select HAVE_CLK select CLKDEV_LOOKUP @@ -812,6 +833,7 @@ config ARCH_U300 select ARM_VIC select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP + select HAVE_MACH_CLKDEV select GENERIC_GPIO help Support for ST-Ericsson U300 series mobile platforms. @@ -884,6 +906,19 @@ config ARCH_VT8500 select HAVE_PWM help Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. + +config ARCH_ZYNQ + bool "Xilinx Zynq ARM Cortex A9 Platform" + select CPU_V7 + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select CLKDEV_LOOKUP + select ARM_GIC + select ARM_AMBA + select ICST + select USE_OF + help + Support for Xilinx Zynq ARM Cortex A9 Platform endchoice # @@ -1236,6 +1271,18 @@ config ARM_ERRATA_754327 This workaround defines cpu_relax() as smp_mb(), preventing correctly written polling loops from denying visibility of updates to memory. +config ARM_ERRATA_364296 + bool "ARM errata: Possible cache data corruption with hit-under-miss enabled" + depends on CPU_V6 && !SMP + help + This options enables the workaround for the 364296 ARM1136 + r0p2 erratum (possible cache data corruption with + hit-under-miss enabled). It sets the undocumented bit 31 in + the auxiliary control register and the FI bit in the control + register, thus disabling hit-under-miss without putting the + processor into full low interrupt latency mode. ARM11MPCore + is not affected. + endmenu source "arch/arm/common/Kconfig" @@ -1680,6 +1727,7 @@ config USE_OF bool "Flattened Device Tree support" select OF select OF_EARLY_FLATTREE + select IRQ_DOMAIN help Include support for flattened device tree machine descriptions. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 206c34e..70c424e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -168,6 +168,7 @@ machine-$(CONFIG_ARCH_OMAP3) := omap2 machine-$(CONFIG_ARCH_OMAP4) := omap2 machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_PNX4008) := pnx4008 +machine-$(CONFIG_ARCH_PRIMA2) := prima2 machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_REALVIEW) := realview machine-$(CONFIG_ARCH_RPC) := rpc @@ -194,6 +195,7 @@ machine-$(CONFIG_MACH_SPEAR300) := spear3xx machine-$(CONFIG_MACH_SPEAR310) := spear3xx machine-$(CONFIG_MACH_SPEAR320) := spear3xx machine-$(CONFIG_MACH_SPEAR600) := spear6xx +machine-$(CONFIG_ARCH_ZYNQ) := zynq # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -201,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC) := mxc plat-$(CONFIG_ARCH_OMAP) := omap plat-$(CONFIG_ARCH_S3C64XX) := samsung plat-$(CONFIG_ARCH_TCC_926) := tcc +plat-$(CONFIG_ARCH_ZYNQ) := versatile plat-$(CONFIG_PLAT_IOP) := iop plat-$(CONFIG_PLAT_NOMADIK) := nomadik plat-$(CONFIG_PLAT_ORION) := orion @@ -279,6 +282,12 @@ zImage Image xipImage bootpImage uImage: vmlinux zinstall uinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ +%.dtb: + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ + +dtbs: + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ + # We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) @@ -295,6 +304,7 @@ define archhelp echo ' uImage - U-Boot wrapped zImage' echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=<path>)' + echo ' dtbs - Build device tree blobs for enabled boards' echo ' install - Install uncompressed kernel' echo ' zinstall - Install compressed kernel' echo ' uinstall - Install U-Boot wrapped compressed kernel' diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 9128fdd..a1edfd5 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -59,6 +59,12 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE endif +# Rule to build device tree blobs +$(obj)/%.dtb: $(src)/dts/%.dts + $(call cmd,dtc) + +$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) + quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ -C none -a $(LOADADDR) -e $(STARTADDR) \ diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c index b6f61d9..672ae95 100644 --- a/arch/arm/boot/compressed/mmcif-sh7372.c +++ b/arch/arm/boot/compressed/mmcif-sh7372.c @@ -82,7 +82,7 @@ asmlinkage void mmc_loader(unsigned char *buf, unsigned long len) /* Disable clock to MMC hardware block */ - __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3); + __raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3); mmc_update_progress(MMC_PROGRESS_DONE); } diff --git a/arch/arm/boot/compressed/sdhi-sh7372.c b/arch/arm/boot/compressed/sdhi-sh7372.c index d403a8b..d279294 100644 --- a/arch/arm/boot/compressed/sdhi-sh7372.c +++ b/arch/arm/boot/compressed/sdhi-sh7372.c @@ -85,7 +85,7 @@ asmlinkage void mmc_loader(unsigned short *buf, unsigned long len) goto err; /* Disable clock to SDHI1 hardware block */ - __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3); + __raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3); mmc_update_progress(MMC_PROGRESS_DONE); diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts new file mode 100644 index 0000000..6fecc88 --- /dev/null +++ b/arch/arm/boot/dts/prima2-cb.dts @@ -0,0 +1,416 @@ +/dts-v1/; +/ { + model = "SiRF Prima2 eVB"; + compatible = "sirf,prima2-cb", "sirf,prima2"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + + memory { + reg = <0x00000000 0x20000000>; + }; + + chosen { + bootargs = "mem=512M real_root=/dev/mmcblk0p2 console=ttyS0 panel=1 bootsplash=true bpp=16 androidboot.console=ttyS1"; + linux,stdout-path = &uart1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + reg = <0x0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + /* from bootloader */ + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + }; + + axi { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x40000000 0x40000000 0x80000000>; + + l2-cache-controller@80040000 { + compatible = "arm,pl310-cache"; + reg = <0x80040000 0x1000>; + interrupts = <59>; + }; + + intc: interrupt-controller@80020000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "sirf,prima2-intc"; + reg = <0x80020000 0x1000>; + }; + + sys-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x88000000 0x88000000 0x40000>; + + clock-controller@88000000 { + compatible = "sirf,prima2-clkc"; + reg = <0x88000000 0x1000>; + interrupts = <3>; + }; + + reset-controller@88010000 { + compatible = "sirf,prima2-rstc"; + reg = <0x88010000 0x1000>; + }; + }; + + mem-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x90000000 0x90000000 0x10000>; + + memory-controller@90000000 { + compatible = "sirf,prima2-memc"; + reg = <0x90000000 0x10000>; + interrupts = <27>; + }; + }; + + disp-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x90010000 0x90010000 0x30000>; + + display@90010000 { + compatible = "sirf,prima2-lcd"; + reg = <0x90010000 0x20000>; + interrupts = <30>; + }; + + vpp@90020000 { + compatible = "sirf,prima2-vpp"; + reg = <0x90020000 0x10000>; + interrupts = <31>; + }; + }; + + graphics-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x98000000 0x98000000 0x8000000>; + + graphics@98000000 { + compatible = "powervr,sgx531"; + reg = <0x98000000 0x8000000>; + interrupts = <6>; + }; + }; + + multimedia-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xa0000000 0xa0000000 0x8000000>; + + multimedia@a0000000 { + compatible = "sirf,prima2-video-codec"; + reg = <0xa0000000 0x8000000>; + interrupts = <5>; + }; + }; + + dsp-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xa8000000 0xa8000000 0x2000000>; + + dspif@a8000000 { + compatible = "sirf,prima2-dspif"; + reg = <0xa8000000 0x10000>; + interrupts = <9>; + }; + + gps@a8010000 { + compatible = "sirf,prima2-gps"; + reg = <0xa8010000 0x10000>; + interrupts = <7>; + }; + + dsp@a9000000 { + compatible = "sirf,prima2-dsp"; + reg = <0xa9000000 0x1000000>; + interrupts = <8>; + }; + }; + + peri-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xb0000000 0xb0000000 0x180000>; + + timer@b0020000 { + compatible = "sirf,prima2-tick"; + reg = <0xb0020000 0x1000>; + interrupts = <0>; + }; + + nand@b0030000 { + compatible = "sirf,prima2-nand"; + reg = <0xb0030000 0x10000>; + interrupts = <41>; + }; + + audio@b0040000 { + compatible = "sirf,prima2-audio"; + reg = <0xb0040000 0x10000>; + interrupts = <35>; + }; + + uart0: uart@b0050000 { + cell-index = <0>; + compatible = "sirf,prima2-uart"; + reg = <0xb0050000 0x10000>; + interrupts = <17>; + }; + + uart1: uart@b0060000 { + cell-index = <1>; + compatible = "sirf,prima2-uart"; + reg = <0xb0060000 0x10000>; + interrupts = <18>; + }; + + uart2: uart@b0070000 { + cell-index = <2>; + compatible = "sirf,prima2-uart"; + reg = <0xb0070000 0x10000>; + interrupts = <19>; + }; + + usp0: usp@b0080000 { + cell-index = <0>; + compatible = "sirf,prima2-usp"; + reg = <0xb0080000 0x10000>; + interrupts = <20>; + }; + + usp1: usp@b0090000 { + cell-index = <1>; + compatible = "sirf,prima2-usp"; + reg = <0xb0090000 0x10000>; + interrupts = <21>; + }; + + usp2: usp@b00a0000 { + cell-index = <2>; + compatible = "sirf,prima2-usp"; + reg = <0xb00a0000 0x10000>; + interrupts = <22>; + }; + + dmac0: dma-controller@b00b0000 { + cell-index = <0>; + compatible = "sirf,prima2-dmac"; + reg = <0xb00b0000 0x10000>; + interrupts = <12>; + }; + + dmac1: dma-controller@b0160000 { + cell-index = <1>; + compatible = "sirf,prima2-dmac"; + reg = <0xb0160000 0x10000>; + interrupts = <13>; + }; + + vip@b00C0000 { + compatible = "sirf,prima2-vip"; + reg = <0xb00C0000 0x10000>; + }; + + spi0: spi@b00d0000 { + cell-index = <0>; + compatible = "sirf,prima2-spi"; + reg = <0xb00d0000 0x10000>; + interrupts = <15>; + }; + + spi1: spi@b0170000 { + cell-index = <1>; + compatible = "sirf,prima2-spi"; + reg = <0xb0170000 0x10000>; + interrupts = <16>; + }; + + i2c0: i2c@b00e0000 { + cell-index = <0>; + compatible = "sirf,prima2-i2c"; + reg = <0xb00e0000 0x10000>; + interrupts = <24>; + }; + + i2c1: i2c@b00f0000 { + cell-index = <1>; + compatible = "sirf,prima2-i2c"; + reg = <0xb00f0000 0x10000>; + interrupts = <25>; + }; + + tsc@b0110000 { + compatible = "sirf,prima2-tsc"; + reg = <0xb0110000 0x10000>; + interrupts = <33>; + }; + + gpio: gpio-controller@b0120000 { + #gpio-cells = <2>; + #interrupt-cells = <2>; + compatible = "sirf,prima2-gpio"; + reg = <0xb0120000 0x10000>; + gpio-controller; + interrupt-controller; + }; + + pwm@b0130000 { + compatible = "sirf,prima2-pwm"; + reg = <0xb0130000 0x10000>; + }; + + efusesys@b0140000 { + compatible = "sirf,prima2-efuse"; + reg = <0xb0140000 0x10000>; + }; + + pulsec@b0150000 { + compatible = "sirf,prima2-pulsec"; + reg = <0xb0150000 0x10000>; + interrupts = <48>; + }; + + pci-iobg { + compatible = "sirf,prima2-pciiobg", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x56000000 0x56000000 0x1b00000>; + + sd0: sdhci@56000000 { + cell-index = <0>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56000000 0x100000>; + interrupts = <38>; + }; + + sd1: sdhci@56100000 { + cell-index = <1>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56100000 0x100000>; + interrupts = <38>; + }; + + sd2: sdhci@56200000 { + cell-index = <2>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56200000 0x100000>; + interrupts = <23>; + }; + + sd3: sdhci@56300000 { + cell-index = <3>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56300000 0x100000>; + interrupts = <23>; + }; + + sd4: sdhci@56400000 { + cell-index = <4>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56400000 0x100000>; + interrupts = <39>; + }; + + sd5: sdhci@56500000 { + cell-index = <5>; + compatible = "sirf,prima2-sdhc"; + reg = <0x56500000 0x100000>; + interrupts = <39>; + }; + + pci-copy@57900000 { + compatible = "sirf,prima2-pcicp"; + reg = <0x57900000 0x100000>; + interrupts = <40>; + }; + + rom-interface@57a00000 { + compatible = "sirf,prima2-romif"; + reg = <0x57a00000 0x100000>; + }; + }; + }; + + rtc-iobg { + compatible = "sirf,prima2-rtciobg", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80030000 0x10000>; + + gpsrtc@1000 { + compatible = "sirf,prima2-gpsrtc"; + reg = <0x1000 0x1000>; + interrupts = <55 56 57>; + }; + + sysrtc@2000 { + compatible = "sirf,prima2-sysrtc"; + reg = <0x2000 0x1000>; + interrupts = <52 53 54>; + }; + + pwrc@3000 { + compatible = "sirf,prima2-pwrc"; + reg = <0x3000 0x1000>; + interrupts = <32>; + }; + }; + + uus-iobg { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xb8000000 0xb8000000 0x40000>; + + usb0: usb@b00e0000 { + compatible = "chipidea,ci13611a-prima2"; + reg = <0xb8000000 0x10000>; + interrupts = <10>; + }; + + usb1: usb@b00f0000 { + compatible = "chipidea,ci13611a-prima2"; + reg = <0xb8010000 0x10000>; + interrupts = <11>; + }; + + sata@b00f0000 { + compatible = "synopsys,dwc-ahsata"; + reg = <0xb8020000 0x10000>; + interrupts = <37>; + }; + + security@b00f0000 { + compatible = "sirf,prima2-security"; + reg = <0xb8030000 0x10000>; + interrupts = <42>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi new file mode 100644 index 0000000..b41d241 --- /dev/null +++ b/arch/arm/boot/dts/skeleton.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts new file mode 100644 index 0000000..4c05334 --- /dev/null +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -0,0 +1,70 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ "tegra20.dtsi" + +/ { + model = "NVIDIA Tegra2 Harmony evaluation board"; + compatible = "nvidia,harmony", "nvidia,tegra20"; + + chosen { + bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait"; + }; + + memory@0 { + reg = < 0x00000000 0x40000000 >; + }; + + i2c@7000c000 { + clock-frequency = <400000>; + + codec: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupts = < 347 >; + + gpio-controller; + #gpio-cells = <2>; + + /* 0x8000 = Not configured */ + gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >; + }; + }; + + i2c@7000c400 { + clock-frequency = <400000>; + }; + + i2c@7000c500 { + clock-frequency = <400000>; + }; + + i2c@7000d000 { + clock-frequency = <400000>; + }; + + sound { + compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903"; + + spkr-en-gpios = <&codec 2 0>; + hp-det-gpios = <&gpio 178 0>; + int-mic-en-gpios = <&gpio 184 0>; + ext-mic-en-gpios = <&gpio 185 0>; + }; + + serial@70006300 { + clock-frequency = < 216000000 >; + }; + + sdhci@c8000200 { + gpios = <&gpio 69 0>, /* cd, gpio PI5 */ + <&gpio 57 0>, /* wp, gpio PH1 */ + <&gpio 155 0>; /* power, gpio PT3 */ + }; + + sdhci@c8000600 { + gpios = <&gpio 58 0>, /* cd, gpio PH2 */ + <&gpio 59 0>, /* wp, gpio PH3 */ + <&gpio 70 0>; /* power, gpio PI6 */ + }; +}; diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts new file mode 100644 index 0000000..1940cae --- /dev/null +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -0,0 +1,28 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ "tegra20.dtsi" + +/ { + model = "NVIDIA Seaboard"; + compatible = "nvidia,seaboard", "nvidia,tegra20"; + + chosen { + bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait"; + }; + + memory { + device_type = "memory"; + reg = < 0x00000000 0x40000000 >; + }; + + serial@70006300 { + clock-frequency = < 216000000 >; + }; + + sdhci@c8000400 { + gpios = <&gpio 69 0>, /* cd, gpio PI5 */ + <&gpio 57 0>, /* wp, gpio PH1 */ + <&gpio 70 0>; /* power, gpio PI6 */ + }; +}; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi new file mode 100644 index 0000000..5727595 --- /dev/null +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -0,0 +1,139 @@ +/include/ "skeleton.dtsi" + +/ { + compatible = "nvidia,tegra20"; + interrupt-parent = <&intc>; + + intc: interrupt-controller@50041000 { + compatible = "nvidia,tegra20-gic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = < 0x50041000 0x1000 >, + < 0x50040100 0x0100 >; + }; + + i2c@7000c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C000 0x100>; + interrupts = < 70 >; + }; + + i2c@7000c400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C400 0x100>; + interrupts = < 116 >; + }; + + i2c@7000c500 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000C500 0x100>; + interrupts = < 124 >; + }; + + i2c@7000d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000D000 0x200>; + interrupts = < 85 >; + }; + + i2s@70002800 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2s"; + reg = <0x70002800 0x200>; + interrupts = < 45 >; + dma-channel = < 2 >; + }; + + i2s@70002a00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-i2s"; + reg = <0x70002a00 0x200>; + interrupts = < 35 >; + dma-channel = < 1 >; + }; + + das@70000c00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-das"; + reg = <0x70000c00 0x80>; + }; + + gpio: gpio@6000d000 { + compatible = "nvidia,tegra20-gpio"; + reg = < 0x6000d000 0x1000 >; + interrupts = < 64 65 66 67 87 119 121 >; + #gpio-cells = <2>; + gpio-controller; + }; + + serial@70006000 { + compatible = "nvidia,tegra20-uart"; + reg = <0x70006000 0x40>; + reg-shift = <2>; + interrupts = < 68 >; + }; + + serial@70006040 { + compatible = "nvidia,tegra20-uart"; + reg = <0x70006040 0x40>; + reg-shift = <2>; + interrupts = < 69 >; + }; + + serial@70006200 { + compatible = "nvidia,tegra20-uart"; + reg = <0x70006200 0x100>; + reg-shift = <2>; + interrupts = < 78 >; + }; + + serial@70006300 { + compatible = "nvidia,tegra20-uart"; + reg = <0x70006300 0x100>; + reg-shift = <2>; + interrupts = < 122 >; + }; + + serial@70006400 { + compatible = "nvidia,tegra20-uart"; + reg = <0x70006400 0x100>; + reg-shift = <2>; + interrupts = < 123 >; + }; + + sdhci@c8000000 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000000 0x200>; + interrupts = < 46 >; + }; + + sdhci@c8000200 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000200 0x200>; + interrupts = < 47 >; + }; + + sdhci@c8000400 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000400 0x200>; + interrupts = < 51 >; + }; + + sdhci@c8000600 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000600 0x200>; + interrupts = < 63 >; + }; +}; + diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts new file mode 100644 index 0000000..0b32925 --- /dev/null +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -0,0 +1,192 @@ +/dts-v1/; +/include/ "skeleton.dtsi" + +/ { + model = "ARM Versatile AB"; + compatible = "arm,versatile-ab"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&vic>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + i2c0 = &i2c0; + }; + + memory { + reg = <0x0 0x08000000>; + }; + + flash@34000000 { + compatible = "arm,versatile-flash"; + reg = <0x34000000 0x4000000>; + bank-width = <4>; + }; + + i2c0: i2c@10002000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "arm,versatile-i2c"; + reg = <0x10002000 0x1000>; + + rtc@68 { + compatible = "dallas,ds1338"; + reg = <0x68>; + }; + }; + + net@10010000 { + compatible = "smsc,lan91c111"; + reg = <0x10010000 0x10000>; + interrupts = <25>; + }; + + lcd@10008000 { + compatible = "arm,versatile-lcd"; + reg = <0x10008000 0x1000>; + }; + + amba { + compatible = "arm,amba-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + vic: intc@10140000 { + compatible = "arm,versatile-vic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x10140000 0x1000>; + }; + + sic: intc@10003000 { + compatible = "arm,versatile-sic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x10003000 0x1000>; + interrupt-parent = <&vic>; + interrupts = <31>; /* Cascaded to vic */ + }; + + dma@10130000 { + compatible = "arm,pl081", "arm,primecell"; + reg = <0x10130000 0x1000>; + interrupts = <17>; + }; + + uart0: uart@101f1000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x101f1000 0x1000>; + interrupts = <12>; + }; + + uart1: uart@101f2000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x101f2000 0x1000>; + interrupts = <13>; + }; + + uart2: uart@101f3000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x101f3000 0x1000>; + interrupts = <14>; + }; + + smc@10100000 { + compatible = "arm,primecell"; + reg = <0x10100000 0x1000>; + }; + + mpmc@10110000 { + compatible = "arm,primecell"; + reg = <0x10110000 0x1000>; + }; + + display@10120000 { + compatible = "arm,pl110", "arm,primecell"; + reg = <0x10120000 0x1000>; + interrupts = <16>; + }; + + sctl@101e0000 { + compatible = "arm,primecell"; + reg = <0x101e0000 0x1000>; + }; + + watchdog@101e1000 { + compatible = "arm,primecell"; + reg = <0x101e1000 0x1000>; + interrupts = <0>; + }; + + gpio0: gpio@101e4000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x101e4000 0x1000>; + gpio-controller; + interrupts = <6>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@101e5000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x101e5000 0x1000>; + interrupts = <7>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + rtc@101e8000 { + compatible = "arm,pl030", "arm,primecell"; + reg = <0x101e8000 0x1000>; + interrupts = <10>; + }; + + sci@101f0000 { + compatible = "arm,primecell"; + reg = <0x101f0000 0x1000>; + interrupts = <15>; + }; + + ssp@101f4000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x101f4000 0x1000>; + interrupts = <11>; + }; + + fpga { + compatible = "arm,versatile-fpga", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x10000000 0x10000>; + + aaci@4000 { + compatible = "arm,primecell"; + reg = <0x4000 0x1000>; + interrupts = <24>; + }; + mmc@5000 { + compatible = "arm,primecell"; + reg = < 0x5000 0x1000>; + interrupts = <22>; + }; + kmi@6000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x6000 0x1000>; + interrupt-parent = <&sic>; + interrupts = <3>; + }; + kmi@7000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x7000 0x1000>; + interrupt-parent = <&sic>; + interrupts = <4>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts new file mode 100644 index 0000000..8a614e3 --- /dev/null +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -0,0 +1,48 @@ +/include/ "versatile-ab.dts" + +/ { + model = "ARM Versatile PB"; + compatible = "arm,versatile-pb"; + + amba { + gpio2: gpio@101e6000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x101e6000 0x1000>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@101e7000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x101e7000 0x1000>; + interrupts = <9>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + fpga { + uart@9000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x9000 0x1000>; + interrupt-parent = <&sic>; + interrupts = <6>; + }; + sci@a000 { + compatible = "arm,primecell"; + reg = <0xa000 0x1000>; + interrupt-parent = <&sic>; + interrupts = <5>; + }; + mmc@b000 { + compatible = "arm,primecell"; + reg = <0xb000 0x1000>; + interrupts = <23>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/zynq-ep107.dts b/arch/arm/boot/dts/zynq-ep107.dts new file mode 100644 index 0000000..37ca192 --- /dev/null +++ b/arch/arm/boot/dts/zynq-ep107.dts @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +/ { + model = "Xilinx Zynq EP107"; + compatible = "xlnx,zynq-ep107"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + + memory { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; + + chosen { + bootargs = "console=ttyPS0,9600 root=/dev/ram rw initrd=0x800000,8M earlyprintk"; + linux,stdout-path = &uart0; + }; + + amba { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + intc: interrupt-controller@f8f01000 { + interrupt-controller; + compatible = "arm,gic"; + reg = <0xF8F01000 0x1000>; + #interrupt-cells = <2>; + }; + + uart0: uart@e0000000 { + compatible = "xlnx,xuartps"; + reg = <0xE0000000 0x1000>; + interrupts = <59 0>; + clock = <50000000>; + }; + }; +}; diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 7bdd917..3227ca9 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -38,12 +38,6 @@ static DEFINE_SPINLOCK(irq_controller_lock); /* Address of GIC 0 CPU interface */ void __iomem *gic_cpu_base_addr __read_mostly; -struct gic_chip_data { - unsigned int irq_offset; - void __iomem *dist_base; - void __iomem *cpu_base; -}; - /* * Supported arch specific GIC irq extension. * Default make them NULL. diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 14ad62e..a7934ba 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -144,7 +144,7 @@ void it8152_irq_demux(unsigned int irq, struct irq_desc *desc) } /* mapping for on-chip devices */ -int __init it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init it8152_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if ((dev->vendor == PCI_VENDOR_ID_ITE) && (dev->device == PCI_DEVICE_ID_ITE_8152)) { diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 5a6ff7c..db2cb7d 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -22,6 +22,8 @@ CONFIG_BLK_DEV_INTEGRITY=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_MXS=y +CONFIG_MACH_MX23EVK=y +CONFIG_MACH_MX28EVK=y CONFIG_MACH_STMP378X_DEVB=y CONFIG_MACH_TX28=y # CONFIG_ARM_THUMB is not set diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index a5cce24..97d31a4 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -11,12 +11,12 @@ CONFIG_ARCH_U8500=y CONFIG_UX500_SOC_DB5500=y CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_U8500=y +CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 -CONFIG_HOTPLUG_CPU=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" @@ -25,8 +25,13 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_NETFILTER=y CONFIG_PHONET=y -CONFIG_PHONET_PIPECTRLR=y # CONFIG_WIRELESS is not set CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -35,6 +40,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_MISC_DEVICES=y CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y +CONFIG_NETDEVICES=y +CONFIG_SMSC_PHY=y +CONFIG_NET_ETHERNET=y +CONFIG_SMSC911X=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -49,9 +61,9 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_AB8500_PONKEY=y # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_LEGACY_PTYS is not set CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y CONFIG_I2C=y @@ -64,14 +76,19 @@ CONFIG_GPIO_TC3589X=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y CONFIG_AB8500_CORE=y -CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_GADGET=y +CONFIG_AB8500_USB=y CONFIG_MMC=y +CONFIG_MMC_CLKGATE=y CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_LM3530=y CONFIG_LEDS_LP5521=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AB8500=y @@ -79,7 +96,6 @@ CONFIG_RTC_DRV_PL031=y CONFIG_DMADEVICES=y CONFIG_STE_DMA40=y CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y @@ -91,6 +107,8 @@ CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_CONFIGFS_FS=m # CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y @@ -99,7 +117,5 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_FTRACE is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 7e79503..86976d0 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -208,16 +208,15 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) c = old; - return c != u; + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic_inc(v) atomic_add(1, v) #define atomic_dec(v) atomic_sub(1, v) @@ -460,9 +459,6 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL) -#else /* !CONFIG_GENERIC_ATOMIC64 */ -#include <asm-generic/atomic64.h> -#endif -#include <asm-generic/atomic-long.h> +#endif /* !CONFIG_GENERIC_ATOMIC64 */ #endif #endif diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index f428059..f7419ef 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -310,10 +310,7 @@ static inline int find_next_bit_le(const void *p, int size, int offset) /* * Ext2 is defined to use little-endian byte ordering. */ -#define ext2_set_bit_atomic(lock, nr, p) \ - test_and_set_bit_le(nr, p) -#define ext2_clear_bit_atomic(lock, nr, p) \ - test_and_clear_bit_le(nr, p) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h index 765d332..80751c1 100644 --- a/arch/arm/include/asm/clkdev.h +++ b/arch/arm/include/asm/clkdev.h @@ -14,7 +14,12 @@ #include <linux/slab.h> +#ifdef CONFIG_HAVE_MACH_CLKDEV #include <mach/clkdev.h> +#else +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) +#endif static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) { diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 16bd480..99a6ed7 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -45,8 +45,13 @@ #define L2X0_CLEAN_INV_LINE_PA 0x7F0 #define L2X0_CLEAN_INV_LINE_IDX 0x7F8 #define L2X0_CLEAN_INV_WAY 0x7FC -#define L2X0_LOCKDOWN_WAY_D 0x900 -#define L2X0_LOCKDOWN_WAY_I 0x904 +/* + * The lockdown registers repeat 8 times for L310, the L210 has only one + * D and one I lockdown register at 0x0900 and 0x0904. + */ +#define L2X0_LOCKDOWN_WAY_D_BASE 0x900 +#define L2X0_LOCKDOWN_WAY_I_BASE 0x904 +#define L2X0_LOCKDOWN_STRIDE 0x08 #define L2X0_TEST_OPERATION 0xF00 #define L2X0_LINE_DATA 0xF10 #define L2X0_LINE_TAG 0xF30 @@ -64,7 +69,7 @@ #define L2X0_AUX_CTRL_MASK 0xc0000fff #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) +#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 0691f9d..435d3f8 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -41,6 +41,12 @@ void gic_secondary_init(unsigned int); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); void gic_enable_ppi(unsigned int); + +struct gic_chip_data { + unsigned int irq_offset; + void __iomem *dist_base; + void __iomem *cpu_base; +}; #endif #endif diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index b2f95c7..b3fea38 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -105,7 +105,7 @@ struct pci_sys_data; extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc); extern void it8152_init_irq(void); -extern int it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); +extern int it8152_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); extern int it8152_pci_setup(int nr, struct pci_sys_data *sys); extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys); diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 2721a58..5a526af 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -23,6 +23,7 @@ struct pt_regs; extern void migrate_irqs(void); extern void asm_do_IRQ(unsigned int, struct pt_regs *); +void handle_IRQ(unsigned int, struct pt_regs *); void init_IRQ(void); #endif diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 3281fb4..217aa191 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -74,4 +74,11 @@ static const struct machine_desc __mach_desc_##_type \ #define MACHINE_END \ }; +#define DT_MACHINE_START(_name, _namestr) \ +static const struct machine_desc __mach_desc_##_name \ + __used \ + __attribute__((__section__(".arch.info.init"))) = { \ + .nr = ~0, \ + .name = _namestr, + #endif diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 16330bd..186efd4 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -25,7 +25,7 @@ struct hw_pci { void (*preinit)(void); void (*postinit)(void); u8 (*swizzle)(struct pci_dev *dev, u8 *pin); - int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); + int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); }; /* @@ -44,7 +44,7 @@ struct pci_sys_data { /* Bridge swizzling */ u8 (*swizzle)(struct pci_dev *, u8 *); /* IRQ mapping */ - int (*map_irq)(struct pci_dev *, u8, u8); + int (*map_irq)(const struct pci_dev *, u8, u8); struct hw_pci *hw; void *private_data; /* platform controller private data */ }; diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 92e2a83..2b1f245 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -3,9 +3,19 @@ #ifdef __KERNEL__ #include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci-bridge.h> #include <asm/mach/pci.h> /* for pci_sys_data */ -#include <mach/hardware.h> /* for PCIBIOS_MIN_* */ + +extern unsigned long pcibios_min_io; +#define PCIBIOS_MIN_IO pcibios_min_io +extern unsigned long pcibios_min_mem; +#define PCIBIOS_MIN_MEM pcibios_min_mem + +static inline int pcibios_assign_all_busses(void) +{ + return pci_has_flag(PCI_REASSIGN_ALL_RSRC); +} #ifdef CONFIG_PCI_DOMAINS static inline int pci_domain_nr(struct pci_bus *bus) diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 67c70a3..b7e82c4 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -41,7 +41,7 @@ struct arm_pmu_platdata { * encoded error on failure. */ extern struct platform_device * -reserve_pmu(enum arm_pmu_type device); +reserve_pmu(enum arm_pmu_type type); /** * release_pmu() - Relinquish control of the performance counters @@ -62,26 +62,26 @@ release_pmu(enum arm_pmu_type type); * the actual hardware initialisation. */ extern int -init_pmu(enum arm_pmu_type device); +init_pmu(enum arm_pmu_type type); #else /* CONFIG_CPU_HAS_PMU */ #include <linux/err.h> static inline struct platform_device * -reserve_pmu(enum arm_pmu_type device) +reserve_pmu(enum arm_pmu_type type) { return ERR_PTR(-ENODEV); } static inline int -release_pmu(struct platform_device *pdev) +release_pmu(enum arm_pmu_type type) { return -ENODEV; } static inline int -init_pmu(enum arm_pmu_type device) +init_pmu(enum arm_pmu_type type) { return -ENODEV; } diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index 11b8708..6f65ca8 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -16,11 +16,6 @@ #include <asm/setup.h> #include <asm/irq.h> -static inline void irq_dispose_mapping(unsigned int virq) -{ - return; -} - extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); extern void arm_dt_memblock_reserve(void); diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h index 250a4dd..91f4021 100644 --- a/arch/arm/include/asm/vga.h +++ b/arch/arm/include/asm/vga.h @@ -2,9 +2,10 @@ #define ASMARM_VGA_H #include <linux/io.h> -#include <mach/hardware.h> -#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x)) +extern unsigned long vga_base; + +#define VGA_MAP_MEM(x,s) (vga_base + (x)) #define vga_readb(x) (*((volatile unsigned char *)x)) #define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index acca35a..aeef960 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -112,9 +112,6 @@ EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); #endif - /* crypto hash */ -EXPORT_SYMBOL(sha_transform); - /* gcc lib functions */ EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index e4ee050..d6df359 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -476,7 +476,7 @@ static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin) /* * Map a slot/pin to an IRQ. */ -static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_sys_data *sys = dev->sysdata; int irq = -1; diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 80f7896..9943e9e 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -178,7 +178,7 @@ CALL(sys_ni_syscall) /* vm86 */ CALL(sys_ni_syscall) /* was sys_query_module */ CALL(sys_poll) - CALL(sys_nfsservctl) + CALL(sys_ni_syscall) /* was nfsservctl */ /* 170 */ CALL(sys_setresgid16) CALL(sys_getresgid16) CALL(sys_prctl) diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 0cdd7b4..1a33e9d 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -132,17 +132,3 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) return mdesc_best; } - -/** - * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# - * - * Currently the mapping mechanism is trivial; simple flat hwirq numbers are - * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not - * supported. - */ -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - return intspec[0]; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 0f928a1..de3dcab8 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -67,12 +67,12 @@ int arch_show_interrupts(struct seq_file *p, int prec) } /* - * do_IRQ handles all hardware IRQ's. Decoded IRQs should not - * come via this function. Instead, they should provide their - * own 'handler' + * handle_IRQ handles all hardware IRQ's. Decoded IRQs should + * not come via this function. Instead, they should provide their + * own 'handler'. Used by platform code implementing C-based 1st + * level decoding. */ -asmlinkage void __exception_irq_entry -asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +void handle_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); @@ -97,6 +97,15 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs) set_irq_regs(old_regs); } +/* + * asm_do_IRQ is the interface to be used from assembly code. + */ +asmlinkage void __exception_irq_entry +asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +{ + handle_IRQ(irq, regs); +} + void set_irq_flags(unsigned int irq, unsigned int iflags) { unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index 7fa3bb0..a087838 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -195,10 +195,10 @@ ENTRY(iwmmxt_task_disable) @ enable access to CP0 and CP1 XSC(mrc p15, 0, r4, c15, c1, 0) - XSC(orr r4, r4, #0xf) + XSC(orr r4, r4, #0x3) XSC(mcr p15, 0, r4, c15, c1, 0) PJ4(mrc p15, 0, r4, c1, c0, 2) - PJ4(orr r4, r4, #0x3) + PJ4(orr r4, r4, #0xf) PJ4(mcr p15, 0, r4, c1, c0, 2) mov r0, #0 @ nothing to load @@ -313,7 +313,7 @@ ENTRY(iwmmxt_task_switch) teq r2, r3 @ next task owns it? movne pc, lr @ no: leave Concan disabled -1: @ flip Conan access +1: @ flip Concan access XSC(eor r1, r1, #0x3) XSC(mcr p15, 0, r1, c15, c1, 0) PJ4(eor r1, r1, #0xf) diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 05b3776..cc2020c 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -323,7 +323,11 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, #endif s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); if (s && !is_smp()) +#ifdef CONFIG_SMP_ON_UP fixup_smp((void *)s->sh_addr, s->sh_size); +#else + return -EINVAL; +#endif return 0; } diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index 2b70709..c53474f 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -31,7 +31,7 @@ static int __devinit pmu_register(struct platform_device *pdev, { if (type < 0 || type >= ARM_NUM_PMU_DEVICES) { pr_warning("received registration request for unknown " - "device %d\n", type); + "PMU device type %d\n", type); return -EINVAL; } @@ -112,17 +112,17 @@ static int __init register_pmu_driver(void) device_initcall(register_pmu_driver); struct platform_device * -reserve_pmu(enum arm_pmu_type device) +reserve_pmu(enum arm_pmu_type type) { struct platform_device *pdev; - if (test_and_set_bit_lock(device, &pmu_lock)) { + if (test_and_set_bit_lock(type, &pmu_lock)) { pdev = ERR_PTR(-EBUSY); - } else if (pmu_devices[device] == NULL) { - clear_bit_unlock(device, &pmu_lock); + } else if (pmu_devices[type] == NULL) { + clear_bit_unlock(type, &pmu_lock); pdev = ERR_PTR(-ENODEV); } else { - pdev = pmu_devices[device]; + pdev = pmu_devices[type]; } return pdev; @@ -130,11 +130,11 @@ reserve_pmu(enum arm_pmu_type device) EXPORT_SYMBOL_GPL(reserve_pmu); int -release_pmu(enum arm_pmu_type device) +release_pmu(enum arm_pmu_type type) { - if (WARN_ON(!pmu_devices[device])) + if (WARN_ON(!pmu_devices[type])) return -EINVAL; - clear_bit_unlock(device, &pmu_lock); + clear_bit_unlock(type, &pmu_lock); return 0; } EXPORT_SYMBOL_GPL(release_pmu); @@ -182,17 +182,17 @@ init_cpu_pmu(void) } int -init_pmu(enum arm_pmu_type device) +init_pmu(enum arm_pmu_type type) { int err = 0; - switch (device) { + switch (type) { case ARM_PMU_DEVICE_CPU: err = init_cpu_pmu(); break; default: - pr_warning("attempt to initialise unknown device %d\n", - device); + pr_warning("attempt to initialise PMU of unknown " + "type %d\n", type); err = -EINVAL; } diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 5e1e541..1a347f4 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -30,6 +30,7 @@ #include <linux/uaccess.h> #include <linux/random.h> #include <linux/hw_breakpoint.h> +#include <linux/cpuidle.h> #include <asm/cacheflush.h> #include <asm/leds.h> @@ -196,7 +197,8 @@ void cpu_idle(void) cpu_relax(); } else { stop_critical_timings(); - pm_idle(); + if (cpuidle_idle_call()) + pm_idle(); start_critical_timings(); /* * This will eventually be removed - pm_idle diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 9cf4cbf..d0cdedf 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -57,7 +57,8 @@ relocate_new_kernel: mov r0,#0 ldr r1,kexec_mach_type ldr r2,kexec_boot_atags - mov pc,lr + ARM( mov pc, lr ) + THUMB( bx lr ) .align diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 70bca64..e514c76 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -280,18 +280,19 @@ static void __init cacheid_init(void) if (arch >= CPU_ARCH_ARMv6) { if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ + arch = CPU_ARCH_ARMv7; cacheid = CACHEID_VIPT_NONALIASING; if ((cachetype & (3 << 14)) == 1 << 14) cacheid |= CACHEID_ASID_TAGGED; - else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7)) - cacheid |= CACHEID_VIPT_I_ALIASING; - } else if (cachetype & (1 << 23)) { - cacheid = CACHEID_VIPT_ALIASING; } else { - cacheid = CACHEID_VIPT_NONALIASING; - if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6)) - cacheid |= CACHEID_VIPT_I_ALIASING; + arch = CPU_ARCH_ARMv6; + if (cachetype & (1 << 23)) + cacheid = CACHEID_VIPT_ALIASING; + else + cacheid = CACHEID_VIPT_NONALIASING; } + if (cpu_has_aliasing_icache(arch)) + cacheid |= CACHEID_VIPT_I_ALIASING; } else { cacheid = CACHEID_VIVT; } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 167e3cb..d88ff02 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -27,7 +27,7 @@ #include <linux/clockchips.h> #include <linux/completion.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/cpu.h> #include <asm/cputype.h> diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 2c277d4..01c1862 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); clk->min_delta_ns = clockevent_delta2ns(0xf, clk); + clockevents_register_device(clk); + /* Make sure our local interrupt controller has this enabled */ gic_enable_ppi(clk->irq); - - clockevents_register_device(clk); } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2d3436e..bc9f9da 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -25,7 +25,7 @@ #include <linux/init.h> #include <linux/sched.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/system.h> #include <asm/unistd.h> diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 59ff42d..cf73a7f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -12,7 +12,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o lib1funcs.o div64.o sha1.o \ + ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o mmu-y := clear_user.o copy_page.o getuser.o putuser.o diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S index 8678eb2..e6057fa 100644 --- a/arch/arm/lib/ecard.S +++ b/arch/arm/lib/ecard.S @@ -12,7 +12,6 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/hardware.h> #define CPSR2SPSR(rt) \ mrs rt, cpsr; \ diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S index 9aaf7c7..88487c8 100644 --- a/arch/arm/lib/io-readsw-armv3.S +++ b/arch/arm/lib/io-readsw-armv3.S @@ -9,7 +9,6 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/hardware.h> .Linsw_bad_alignment: adr r0, .Linsw_bad_align_msg diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S index cd34503..49b8004 100644 --- a/arch/arm/lib/io-writesw-armv3.S +++ b/arch/arm/lib/io-writesw-armv3.S @@ -9,7 +9,6 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/hardware.h> .Loutsw_bad_alignment: adr r0, .Loutsw_bad_align_msg diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S deleted file mode 100644 index eb0edb8..0000000 --- a/arch/arm/lib/sha1.S +++ /dev/null @@ -1,211 +0,0 @@ -/* - * linux/arch/arm/lib/sha1.S - * - * SHA transform optimized for ARM - * - * Copyright: (C) 2005 by Nicolas Pitre <nico@fluxnic.net> - * Created: September 17, 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * The reference implementation for this code is linux/lib/sha1.c - */ - -#include <linux/linkage.h> - - .text - - -/* - * void sha_transform(__u32 *digest, const char *in, __u32 *W) - * - * Note: the "in" ptr may be unaligned. - */ - -ENTRY(sha_transform) - - stmfd sp!, {r4 - r8, lr} - - @ for (i = 0; i < 16; i++) - @ W[i] = be32_to_cpu(in[i]); - -#ifdef __ARMEB__ - mov r4, r0 - mov r0, r2 - mov r2, #64 - bl memcpy - mov r2, r0 - mov r0, r4 -#else - mov r3, r2 - mov lr, #16 -1: ldrb r4, [r1], #1 - ldrb r5, [r1], #1 - ldrb r6, [r1], #1 - ldrb r7, [r1], #1 - subs lr, lr, #1 - orr r5, r5, r4, lsl #8 - orr r6, r6, r5, lsl #8 - orr r7, r7, r6, lsl #8 - str r7, [r3], #4 - bne 1b -#endif - - @ for (i = 0; i < 64; i++) - @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31); - - sub r3, r2, #4 - mov lr, #64 -2: ldr r4, [r3, #4]! - subs lr, lr, #1 - ldr r5, [r3, #8] - ldr r6, [r3, #32] - ldr r7, [r3, #52] - eor r4, r4, r5 - eor r4, r4, r6 - eor r4, r4, r7 - mov r4, r4, ror #31 - str r4, [r3, #64] - bne 2b - - /* - * The SHA functions are: - * - * f1(B,C,D) = (D ^ (B & (C ^ D))) - * f2(B,C,D) = (B ^ C ^ D) - * f3(B,C,D) = ((B & C) | (D & (B | C))) - * - * Then the sub-blocks are processed as follows: - * - * A' = ror(A, 27) + f(B,C,D) + E + K + *W++ - * B' = A - * C' = ror(B, 2) - * D' = C - * E' = D - * - * We therefore unroll each loop 5 times to avoid register shuffling. - * Also the ror for C (and also D and E which are successivelyderived - * from it) is applied in place to cut on an additional mov insn for - * each round. - */ - - .macro sha_f1, A, B, C, D, E - ldr r3, [r2], #4 - eor ip, \C, \D - add \E, r1, \E, ror #2 - and ip, \B, ip, ror #2 - add \E, \E, \A, ror #27 - eor ip, ip, \D, ror #2 - add \E, \E, r3 - add \E, \E, ip - .endm - - .macro sha_f2, A, B, C, D, E - ldr r3, [r2], #4 - add \E, r1, \E, ror #2 - eor ip, \B, \C, ror #2 - add \E, \E, \A, ror #27 - eor ip, ip, \D, ror #2 - add \E, \E, r3 - add \E, \E, ip - .endm - - .macro sha_f3, A, B, C, D, E - ldr r3, [r2], #4 - add \E, r1, \E, ror #2 - orr ip, \B, \C, ror #2 - add \E, \E, \A, ror #27 - and ip, ip, \D, ror #2 - add \E, \E, r3 - and r3, \B, \C, ror #2 - orr ip, ip, r3 - add \E, \E, ip - .endm - - ldmia r0, {r4 - r8} - - mov lr, #4 - ldr r1, .L_sha_K + 0 - - /* adjust initial values */ - mov r6, r6, ror #30 - mov r7, r7, ror #30 - mov r8, r8, ror #30 - -3: subs lr, lr, #1 - sha_f1 r4, r5, r6, r7, r8 - sha_f1 r8, r4, r5, r6, r7 - sha_f1 r7, r8, r4, r5, r6 - sha_f1 r6, r7, r8, r4, r5 - sha_f1 r5, r6, r7, r8, r4 - bne 3b - - ldr r1, .L_sha_K + 4 - mov lr, #4 - -4: subs lr, lr, #1 - sha_f2 r4, r5, r6, r7, r8 - sha_f2 r8, r4, r5, r6, r7 - sha_f2 r7, r8, r4, r5, r6 - sha_f2 r6, r7, r8, r4, r5 - sha_f2 r5, r6, r7, r8, r4 - bne 4b - - ldr r1, .L_sha_K + 8 - mov lr, #4 - -5: subs lr, lr, #1 - sha_f3 r4, r5, r6, r7, r8 - sha_f3 r8, r4, r5, r6, r7 - sha_f3 r7, r8, r4, r5, r6 - sha_f3 r6, r7, r8, r4, r5 - sha_f3 r5, r6, r7, r8, r4 - bne 5b - - ldr r1, .L_sha_K + 12 - mov lr, #4 - -6: subs lr, lr, #1 - sha_f2 r4, r5, r6, r7, r8 - sha_f2 r8, r4, r5, r6, r7 - sha_f2 r7, r8, r4, r5, r6 - sha_f2 r6, r7, r8, r4, r5 - sha_f2 r5, r6, r7, r8, r4 - bne 6b - - ldmia r0, {r1, r2, r3, ip, lr} - add r4, r1, r4 - add r5, r2, r5 - add r6, r3, r6, ror #2 - add r7, ip, r7, ror #2 - add r8, lr, r8, ror #2 - stmia r0, {r4 - r8} - - ldmfd sp!, {r4 - r8, pc} - -ENDPROC(sha_transform) - - .align 2 -.L_sha_K: - .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 - - -/* - * void sha_init(__u32 *buf) - */ - - .align 2 -.L_sha_initial_digest: - .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - -ENTRY(sha_init) - - str lr, [sp, #-4]! - adr r1, .L_sha_initial_digest - ldmia r1, {r1, r2, r3, ip, lr} - stmia r0, {r1, r2, r3, ip, lr} - ldr pc, [sp], #4 - -ENDPROC(sha_init) diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 9696623..bf57e8b 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := irq.o gpio.o +obj-y := irq.o gpio.o setup.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index f1013d0..bfc6844 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -25,23 +25,10 @@ #include <mach/at91_rstc.h> #include <mach/at91_shdwc.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91cap9_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE, - .pfn = __phys_to_pfn(AT91CAP9_SRAM_BASE), - .length = AT91CAP9_SRAM_SIZE, - .type = MT_DEVICE, - }, -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -339,24 +326,17 @@ static void at91cap9_poweroff(void) * AT91CAP9 processor initialization * -------------------------------------------------------------------- */ -void __init at91cap9_map_io(void) +static void __init at91cap9_map_io(void) { - /* Map peripherals */ - iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc)); + at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); } -void __init at91cap9_initialize(unsigned long main_clock) +static void __init at91cap9_initialize(void) { at91_arch_reset = at91cap9_reset; pm_power_off = at91cap9_poweroff; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91cap9_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91cap9_gpio, 4); @@ -409,14 +389,9 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ1) */ }; -void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91cap9_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91cap9_soc = { + .map_io = at91cap9_map_io, + .default_irq_priority = at91cap9_default_irq_priority, + .register_clocks = at91cap9_register_clocks, + .init = at91cap9_initialize, +}; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 83a1a3f..f73302d 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -20,25 +20,16 @@ #include <mach/at91_st.h> #include <mach/cpu.h> +#include "soc.h" #include "generic.h" #include "clock.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_4K, - .type = MT_DEVICE, - }, { .virtual = AT91_VA_BASE_EMAC, .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, - .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), - .length = AT91RM9200_SRAM_SIZE, - .type = MT_DEVICE, }, }; @@ -304,24 +295,17 @@ static void at91rm9200_reset(void) at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); } -int rm9200_type; -EXPORT_SYMBOL(rm9200_type); - -void __init at91rm9200_set_type(int type) -{ - rm9200_type = type; -} - /* -------------------------------------------------------------------- * AT91RM9200 processor initialization * -------------------------------------------------------------------- */ -void __init at91rm9200_map_io(void) +static void __init at91rm9200_map_io(void) { /* Map peripherals */ + at91_init_sram(0, AT91RM9200_SRAM_BASE, AT91RM9200_SRAM_SIZE); iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); } -void __init at91rm9200_initialize(unsigned long main_clock) +static void __init at91rm9200_initialize(void) { at91_arch_reset = at91rm9200_reset; at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) @@ -329,12 +313,6 @@ void __init at91rm9200_initialize(unsigned long main_clock) | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) | (1 << AT91RM9200_ID_IRQ6); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91rm9200_register_clocks(); - /* Initialize GPIO subsystem */ at91_gpio_init(at91rm9200_gpio, cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP); @@ -383,14 +361,9 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91rm9200_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91rm9200_soc = { + .map_io = at91rm9200_map_io, + .default_irq_priority = at91rm9200_default_irq_priority, + .register_clocks = at91rm9200_register_clocks, + .init = at91rm9200_initialize, +}; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 7d606b0..cb397be 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -17,58 +17,16 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/cpu.h> +#include <mach/at91_dbgu.h> #include <mach/at91sam9260.h> #include <mach/at91_pmc.h> #include <mach/at91_rstc.h> #include <mach/at91_shdwc.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91sam9260_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - } -}; - -static struct map_desc at91sam9260_sram_desc[] __initdata = { - { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, - .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), - .length = AT91SAM9260_SRAM0_SIZE, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, - .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), - .length = AT91SAM9260_SRAM1_SIZE, - .type = MT_DEVICE, - } -}; - -static struct map_desc at91sam9g20_sram_desc[] __initdata = { - { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE, - .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE), - .length = AT91SAM9G20_SRAM0_SIZE, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE, - .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE), - .length = AT91SAM9G20_SRAM1_SIZE, - .type = MT_DEVICE, - } -}; - -static struct map_desc at91sam9xe_sram_desc[] __initdata = { - { - .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), - .type = MT_DEVICE, - } -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -330,11 +288,9 @@ static void at91sam9260_poweroff(void) static void __init at91sam9xe_map_io(void) { - unsigned long cidr, sram_size; - - cidr = at91_sys_read(AT91_DBGU_CIDR); + unsigned long sram_size; - switch (cidr & AT91_CIDR_SRAMSIZ) { + switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) { case AT91_CIDR_SRAMSIZ_32K: sram_size = 2 * SZ_16K; break; @@ -343,38 +299,29 @@ static void __init at91sam9xe_map_io(void) sram_size = SZ_16K; } - at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; - at91sam9xe_sram_desc->length = sram_size; - - iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); + at91_init_sram(0, AT91SAM9XE_SRAM_BASE, sram_size); } -void __init at91sam9260_map_io(void) +static void __init at91sam9260_map_io(void) { - /* Map peripherals */ - iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); - - if (cpu_is_at91sam9xe()) + if (cpu_is_at91sam9xe()) { at91sam9xe_map_io(); - else if (cpu_is_at91sam9g20()) - iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); - else - iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); + } else if (cpu_is_at91sam9g20()) { + at91_init_sram(0, AT91SAM9G20_SRAM0_BASE, AT91SAM9G20_SRAM0_SIZE); + at91_init_sram(1, AT91SAM9G20_SRAM1_BASE, AT91SAM9G20_SRAM1_SIZE); + } else { + at91_init_sram(0, AT91SAM9260_SRAM0_BASE, AT91SAM9260_SRAM0_SIZE); + at91_init_sram(1, AT91SAM9260_SRAM1_BASE, AT91SAM9260_SRAM1_SIZE); + } } -void __init at91sam9260_initialize(unsigned long main_clock) +static void __init at91sam9260_initialize(void) { at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91sam9260_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91sam9260_gpio, 3); } @@ -421,14 +368,9 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91sam9260_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91sam9260_soc = { + .map_io = at91sam9260_map_io, + .default_irq_priority = at91sam9260_default_irq_priority, + .register_clocks = at91sam9260_register_clocks, + .init = at91sam9260_initialize, +}; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index c148316..6c8e3b5 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -22,36 +22,10 @@ #include <mach/at91_rstc.h> #include <mach/at91_shdwc.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91sam9261_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - }, -}; - -static struct map_desc at91sam9261_sram_desc[] __initdata = { - { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, - .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), - .length = AT91SAM9261_SRAM_SIZE, - .type = MT_DEVICE, - }, -}; - -static struct map_desc at91sam9g10_sram_desc[] __initdata = { - { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE, - .pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE), - .length = AT91SAM9G10_SRAM_SIZE, - .type = MT_DEVICE, - }, -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -183,7 +157,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), - CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), @@ -302,30 +276,21 @@ static void at91sam9261_poweroff(void) * AT91SAM9261 processor initialization * -------------------------------------------------------------------- */ -void __init at91sam9261_map_io(void) +static void __init at91sam9261_map_io(void) { - /* Map peripherals */ - iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); - if (cpu_is_at91sam9g10()) - iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc)); + at91_init_sram(0, AT91SAM9G10_SRAM_BASE, AT91SAM9G10_SRAM_SIZE); else - iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc)); + at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE); } -void __init at91sam9261_initialize(unsigned long main_clock) +static void __init at91sam9261_initialize(void) { at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91sam9261_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91sam9261_gpio, 3); } @@ -372,14 +337,9 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91sam9261_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91sam9261_soc = { + .map_io = at91sam9261_map_io, + .default_irq_priority = at91sam9261_default_irq_priority, + .register_clocks = at91sam9261_register_clocks, + .init = at91sam9261_initialize, +}; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index dc28477..044f3c9 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -21,28 +21,10 @@ #include <mach/at91_rstc.h> #include <mach/at91_shdwc.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91sam9263_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE, - .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE), - .length = AT91SAM9263_SRAM0_SIZE, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE, - .pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE), - .length = AT91SAM9263_SRAM1_SIZE, - .type = MT_DEVICE, - }, -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -313,24 +295,18 @@ static void at91sam9263_poweroff(void) * AT91SAM9263 processor initialization * -------------------------------------------------------------------- */ -void __init at91sam9263_map_io(void) +static void __init at91sam9263_map_io(void) { - /* Map peripherals */ - iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc)); + at91_init_sram(0, AT91SAM9263_SRAM0_BASE, AT91SAM9263_SRAM0_SIZE); + at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE); } -void __init at91sam9263_initialize(unsigned long main_clock) +static void __init at91sam9263_initialize(void) { at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9263_poweroff; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91sam9263_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91sam9263_gpio, 5); } @@ -377,14 +353,9 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ1) */ }; -void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91sam9263_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91sam9263_soc = { + .map_io = at91sam9263_map_io, + .default_irq_priority = at91sam9263_default_irq_priority, + .register_clocks = at91sam9263_register_clocks, + .init = at91sam9263_initialize, +}; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 11e2141..e04c5fb 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -22,23 +22,10 @@ #include <mach/at91_shdwc.h> #include <mach/cpu.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91sam9g45_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE, - .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE), - .length = AT91SAM9G45_SRAM_SIZE, - .type = MT_DEVICE, - } -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -329,24 +316,17 @@ static void at91sam9g45_poweroff(void) * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ -void __init at91sam9g45_map_io(void) +static void __init at91sam9g45_map_io(void) { - /* Map peripherals */ - iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); + at91_init_sram(0, AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE); } -void __init at91sam9g45_initialize(unsigned long main_clock) +static void __init at91sam9g45_initialize(void) { at91_arch_reset = at91sam9g45_reset; pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91sam9g45_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91sam9g45_gpio, 5); } @@ -393,14 +373,9 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ0) */ }; -void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91sam9g45_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91sam9g45_soc = { + .map_io = at91sam9g45_map_io, + .default_irq_priority = at91sam9g45_default_irq_priority, + .register_clocks = at91sam9g45_register_clocks, + .init = at91sam9g45_initialize, +}; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 29dff18..a238105 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -16,30 +16,16 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/cpu.h> +#include <mach/at91_dbgu.h> #include <mach/at91sam9rl.h> #include <mach/at91_pmc.h> #include <mach/at91_rstc.h> #include <mach/at91_shdwc.h> +#include "soc.h" #include "generic.h" #include "clock.h" -static struct map_desc at91sam9rl_io_desc[] __initdata = { - { - .virtual = AT91_VA_BASE_SYS, - .pfn = __phys_to_pfn(AT91_BASE_SYS), - .length = SZ_16K, - .type = MT_DEVICE, - }, -}; - -static struct map_desc at91sam9rl_sram_desc[] __initdata = { - { - .pfn = __phys_to_pfn(AT91SAM9RL_SRAM_BASE), - .type = MT_DEVICE, - } -}; - /* -------------------------------------------------------------------- * Clocks * -------------------------------------------------------------------- */ @@ -287,16 +273,11 @@ static void at91sam9rl_poweroff(void) * AT91SAM9RL processor initialization * -------------------------------------------------------------------- */ -void __init at91sam9rl_map_io(void) +static void __init at91sam9rl_map_io(void) { - unsigned long cidr, sram_size; - - /* Map peripherals */ - iotable_init(at91sam9rl_io_desc, ARRAY_SIZE(at91sam9rl_io_desc)); - - cidr = at91_sys_read(AT91_DBGU_CIDR); + unsigned long sram_size; - switch (cidr & AT91_CIDR_SRAMSIZ) { + switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) { case AT91_CIDR_SRAMSIZ_32K: sram_size = 2 * SZ_16K; break; @@ -305,25 +286,16 @@ void __init at91sam9rl_map_io(void) sram_size = SZ_16K; } - at91sam9rl_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; - at91sam9rl_sram_desc->length = sram_size; - /* Map SRAM */ - iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc)); + at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size); } -void __init at91sam9rl_initialize(unsigned long main_clock) +static void __init at91sam9rl_initialize(void) { at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91sam9rl_register_clocks(); - /* Register GPIO subsystem */ at91_gpio_init(at91sam9rl_gpio, 4); } @@ -370,14 +342,9 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS]) -{ - if (!priority) - priority = at91sam9rl_default_irq_priority; - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -} +struct at91_init_soc __initdata at91sam9rl_soc = { + .map_io = at91sam9rl_map_io, + .default_irq_priority = at91sam9rl_default_irq_priority, + .register_clocks = at91sam9rl_register_clocks, + .init = at91sam9rl_initialize, +}; diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index ab1d463..5aa5885 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -46,7 +46,7 @@ static void __init onearm_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -63,11 +63,6 @@ static void __init onearm_init_early(void) at91_set_serial_console(0); } -static void __init onearm_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata onearm_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -97,8 +92,8 @@ static void __init onearm_board_init(void) MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = onearm_init_early, - .init_irq = onearm_init_irq, + .init_irq = at91_init_irq_default, .init_machine = onearm_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index a4924de..b0c796d 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -51,7 +51,7 @@ static void __init afeb9260_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -70,12 +70,6 @@ static void __init afeb9260_init_early(void) at91_set_serial_console(0); } -static void __init afeb9260_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -219,9 +213,9 @@ static void __init afeb9260_board_init(void) MACHINE_START(AFEB9260, "Custom afeb9260 board") /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = afeb9260_init_early, - .init_irq = afeb9260_init_irq, + .init_irq = at91_init_irq_default, .init_machine = afeb9260_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index 148fccb..d1abd58 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -48,7 +48,7 @@ static void __init cam60_init_early(void) { /* Initialize processor: 10 MHz crystal */ - at91sam9260_initialize(10000000); + at91_initialize(10000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -57,12 +57,6 @@ static void __init cam60_init_early(void) at91_set_serial_console(0); } -static void __init cam60_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host */ @@ -199,8 +193,8 @@ static void __init cam60_board_init(void) MACHINE_START(CAM60, "KwikByte CAM60") /* Maintainer: KwikByte */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = cam60_init_early, - .init_irq = cam60_init_irq, + .init_irq = at91_init_irq_default, .init_machine = cam60_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index cdb65d4..679b0b7 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -53,7 +53,7 @@ static void __init cap9adk_init_early(void) { /* Initialize processor: 12 MHz crystal */ - at91cap9_initialize(12000000); + at91_initialize(12000000); /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */ at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11); @@ -65,12 +65,6 @@ static void __init cap9adk_init_early(void) at91_set_serial_console(0); } -static void __init cap9adk_init_irq(void) -{ - at91cap9_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -397,8 +391,8 @@ static void __init cap9adk_board_init(void) MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ .timer = &at91sam926x_timer, - .map_io = at91cap9_map_io, + .map_io = at91_map_io, .init_early = cap9adk_init_early, - .init_irq = cap9adk_init_irq, + .init_irq = at91_init_irq_default, .init_machine = cap9adk_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index f36b186..c578c5d90 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -43,7 +43,7 @@ static void __init carmeva_init_early(void) { /* Initialize processor: 20.000 MHz crystal */ - at91rm9200_initialize(20000000); + at91_initialize(20000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -57,11 +57,6 @@ static void __init carmeva_init_early(void) at91_set_serial_console(0); } -static void __init carmeva_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -163,8 +158,8 @@ static void __init carmeva_board_init(void) MACHINE_START(CARMEVA, "Carmeva") /* Maintainer: Conitec Datasystems */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = carmeva_init_early, - .init_irq = carmeva_init_irq, + .init_irq = at91_init_irq_default, .init_machine = carmeva_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 9805110..f4da8a1 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -50,7 +50,7 @@ static void __init cpu9krea_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DGBU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -81,11 +81,6 @@ static void __init cpu9krea_init_early(void) at91_set_serial_console(0); } -static void __init cpu9krea_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - /* * USB Host port */ @@ -376,8 +371,8 @@ MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") #endif /* Maintainer: Eric Benard - EUKREA Electromatique */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = cpu9krea_init_early, - .init_irq = cpu9krea_init_irq, + .init_irq = at91_init_irq_default, .init_machine = cpu9krea_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 6daabe3..2d919f5 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -57,7 +57,7 @@ static void __init cpuat91_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -82,11 +82,6 @@ static void __init cpuat91_init_early(void) at91_set_serial_console(0); } -static void __init cpuat91_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata cpuat91_eth_data = { .is_rmii = 1, }; @@ -180,8 +175,8 @@ static void __init cpuat91_board_init(void) MACHINE_START(CPUAT91, "Eukrea") /* Maintainer: Eric Benard - EUKREA Electromatique */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = cpuat91_init_early, - .init_irq = cpuat91_init_irq, + .init_irq = at91_init_irq_default, .init_machine = cpuat91_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index d98bcec..17654d5 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -46,7 +46,7 @@ static void __init csb337_init_early(void) { /* Initialize processor: 3.6864 MHz crystal */ - at91rm9200_initialize(3686400); + at91_initialize(3686400); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); @@ -58,11 +58,6 @@ static void __init csb337_init_early(void) at91_set_serial_console(0); } -static void __init csb337_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata csb337_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 0, @@ -258,8 +253,8 @@ static void __init csb337_board_init(void) MACHINE_START(CSB337, "Cogent CSB337") /* Maintainer: Bill Gatliff */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = csb337_init_early, - .init_irq = csb337_init_irq, + .init_irq = at91_init_irq_default, .init_machine = csb337_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index 019aab4..72b5567 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -43,7 +43,7 @@ static void __init csb637_init_early(void) { /* Initialize processor: 3.6864 MHz crystal */ - at91rm9200_initialize(3686400); + at91_initialize(3686400); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -52,11 +52,6 @@ static void __init csb637_init_early(void) at91_set_serial_console(0); } -static void __init csb637_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata csb637_eth_data = { .phy_irq_pin = AT91_PIN_PC0, .is_rmii = 0, @@ -139,8 +134,8 @@ static void __init csb637_board_init(void) MACHINE_START(CSB637, "Cogent CSB637") /* Maintainer: Bill Gatliff */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = csb637_init_early, - .init_irq = csb637_init_irq, + .init_irq = at91_init_irq_default, .init_machine = csb637_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index e948453..01170a2 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c @@ -43,7 +43,7 @@ static void __init eb9200_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -60,11 +60,6 @@ static void __init eb9200_init_early(void) at91_set_serial_console(0); } -static void __init eb9200_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata eb9200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -121,8 +116,8 @@ static void __init eb9200_board_init(void) MACHINE_START(ATEB9200, "Embest ATEB9200") .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = eb9200_init_early, - .init_irq = eb9200_init_irq, + .init_irq = at91_init_irq_default, .init_machine = eb9200_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index a6f57fa..7c0313c 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -49,7 +49,7 @@ static void __init ecb_at91init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); @@ -64,11 +64,6 @@ static void __init ecb_at91init_early(void) at91_set_serial_console(0); } -static void __init ecb_at91init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata ecb_at91eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, @@ -173,8 +168,8 @@ static void __init ecb_at91board_init(void) MACHINE_START(ECBAT91, "emQbit's ECB_AT91") /* Maintainer: emQbit.com */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = ecb_at91init_early, - .init_irq = ecb_at91init_irq, + .init_irq = at91_init_irq_default, .init_machine = ecb_at91board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index bfc0062..8252c72 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -35,7 +35,7 @@ static void __init eco920_init_early(void) /* Set cpu type: PQFP */ at91rm9200_set_type(ARCH_REVISON_9200_PQFP); - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); @@ -47,11 +47,6 @@ static void __init eco920_init_early(void) at91_set_serial_console(0); } -static void __init eco920_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata eco920_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 1, @@ -135,8 +130,8 @@ static void __init eco920_board_init(void) MACHINE_START(ECO920, "eco920") /* Maintainer: Sascha Hauer */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = eco920_init_early, - .init_irq = eco920_init_irq, + .init_irq = at91_init_irq_default, .init_machine = eco920_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index 466c063..4c3f65d 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -40,7 +40,7 @@ static void __init flexibity_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -49,11 +49,6 @@ static void __init flexibity_init_early(void) at91_set_serial_console(0); } -static void __init flexibity_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - /* USB Host port */ static struct at91_usbh_data __initdata flexibity_usbh_data = { .ports = 2, @@ -155,8 +150,8 @@ static void __init flexibity_board_init(void) MACHINE_START(FLEXIBITY, "Flexibity Connect") /* Maintainer: Maxim Osipov */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = flexibity_init_early, - .init_irq = flexibity_init_irq, + .init_irq = at91_init_irq_default, .init_machine = flexibity_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index e2d1dc9..f27d1a7 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -60,7 +60,7 @@ static void __init foxg20_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -101,12 +101,6 @@ static void __init foxg20_init_early(void) } -static void __init foxg20_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -267,8 +261,8 @@ static void __init foxg20_board_init(void) MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20") /* Maintainer: Sergio Tanzilli */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = foxg20_init_early, - .init_irq = foxg20_init_irq, + .init_irq = at91_init_irq_default, .init_machine = foxg20_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index 1d4f36b..2e95949 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -75,11 +75,6 @@ static void __init gsia18s_init_early(void) at91_register_uart(AT91SAM9260_ID_US4, 5, 0); } -static void __init init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - /* * Two USB Host ports */ @@ -577,8 +572,8 @@ static void __init gsia18s_board_init(void) MACHINE_START(GSIA18S, "GS_IA18_S") .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = gsia18s_init_early, - .init_irq = init_irq, + .init_irq = at91_init_irq_default, .init_machine = gsia18s_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index 9b003ff..4a17089 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c @@ -46,7 +46,7 @@ static void __init kafa_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); @@ -61,11 +61,6 @@ static void __init kafa_init_early(void) at91_set_serial_console(0); } -static void __init kafa_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata kafa_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, @@ -99,8 +94,8 @@ static void __init kafa_board_init(void) MACHINE_START(KAFA, "Sperry-Sun KAFA") /* Maintainer: Sergei Sharonov */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = kafa_init_early, - .init_irq = kafa_init_irq, + .init_irq = at91_init_irq_default, .init_machine = kafa_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index a813a74..9dc8d49 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -48,7 +48,7 @@ static void __init kb9202_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 10 MHz crystal */ - at91rm9200_initialize(10000000); + at91_initialize(10000000); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); @@ -69,11 +69,6 @@ static void __init kb9202_init_early(void) at91_set_serial_console(0); } -static void __init kb9202_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata kb9202_eth_data = { .phy_irq_pin = AT91_PIN_PB29, .is_rmii = 0, @@ -140,8 +135,8 @@ static void __init kb9202_board_init(void) MACHINE_START(KB9200, "KB920x") /* Maintainer: KwikByte, Inc. */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = kb9202_init_early, - .init_irq = kb9202_init_irq, + .init_irq = at91_init_irq_default, .init_machine = kb9202_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index 961e805..9bc6ab3 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -54,7 +54,7 @@ static void __init neocore926_init_early(void) { /* Initialize processor: 20 MHz crystal */ - at91sam9263_initialize(20000000); + at91_initialize(20000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -66,12 +66,6 @@ static void __init neocore926_init_early(void) at91_set_serial_console(0); } -static void __init neocore926_init_irq(void) -{ - at91sam9263_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -388,8 +382,8 @@ static void __init neocore926_board_init(void) MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926") /* Maintainer: ADENEO */ .timer = &at91sam926x_timer, - .map_io = at91sam9263_map_io, + .map_io = at91_map_io, .init_early = neocore926_init_early, - .init_irq = neocore926_init_irq, + .init_irq = at91_init_irq_default, .init_machine = neocore926_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 21a21af..49e3f69 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -53,13 +53,6 @@ static void __init pcontrol_g20_init_early(void) at91_register_uart(AT91SAM9260_ID_US4, 3, 0); } - -static void __init init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { .ncs_read_setup = 16, .nrd_setup = 18, @@ -223,8 +216,8 @@ static void __init pcontrol_g20_board_init(void) MACHINE_START(PCONTROL_G20, "PControl G20") /* Maintainer: pgsellmann@portner-elektronik.at */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = pcontrol_g20_init_early, - .init_irq = init_irq, + .init_irq = at91_init_irq_default, .init_machine = pcontrol_g20_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index 756cc2a..b7b8390 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -46,7 +46,7 @@ static void __init picotux200_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -60,11 +60,6 @@ static void __init picotux200_init_early(void) at91_set_serial_console(0); } -static void __init picotux200_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata picotux200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -124,8 +119,8 @@ static void __init picotux200_board_init(void) MACHINE_START(PICOTUX2XX, "picotux 200") /* Maintainer: Kleinhenz Elektronik GmbH */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = picotux200_init_early, - .init_irq = picotux200_init_irq, + .init_irq = at91_init_irq_default, .init_machine = picotux200_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index d1a6001..81f9110 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -51,7 +51,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ - at91sam9260_initialize(12000000); + at91_initialize(12000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -72,12 +72,6 @@ static void __init ek_init_early(void) } -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -269,8 +263,8 @@ static void __init ek_board_init(void) MACHINE_START(QIL_A9260, "CALAO QIL_A9260") /* Maintainer: calao-systems */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index aef9627..6f08faa 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -48,7 +48,7 @@ static void __init dk_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -65,11 +65,6 @@ static void __init dk_init_early(void) at91_set_serial_console(0); } -static void __init dk_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata dk_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -228,8 +223,8 @@ static void __init dk_board_init(void) MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") /* Maintainer: SAN People/Atmel */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = dk_init_early, - .init_irq = dk_init_irq, + .init_irq = at91_init_irq_default, .init_machine = dk_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 015a021..85bcccd 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -48,7 +48,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); @@ -65,11 +65,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata ek_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -194,8 +189,8 @@ static void __init ek_board_init(void) MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") /* Maintainer: SAN People/Atmel */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index aaf1bf0..4d3a02f 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -47,7 +47,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6); @@ -67,12 +67,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -213,8 +207,8 @@ static void __init ek_board_init(void) MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") /* Maintainer: Olimex */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 5c24074..8a50c3e 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -53,7 +53,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -70,12 +70,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -354,8 +348,8 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index b60c22b..5096a0e 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -57,7 +57,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9261_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14); @@ -69,12 +69,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9261_init_interrupts(NULL); -} - - /* * DM9000 ethernet device */ @@ -621,8 +615,8 @@ MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") #endif /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9261_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 9bbdc92..ea8f185 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -56,7 +56,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 16.367 MHz crystal */ - at91sam9263_initialize(16367660); + at91_initialize(16367660); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -68,12 +68,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9263_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -452,8 +446,8 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9263_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 1325a50..817f59d 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -64,7 +64,7 @@ static int inline ek_have_2mmc(void) static void __init ek_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -81,12 +81,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -404,17 +398,17 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 33eaa13..ad234cc 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -50,7 +50,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ - at91sam9g45_initialize(12000000); + at91_initialize(12000000); /* DGBU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -63,12 +63,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9g45_init_interrupts(NULL); -} - - /* * USB HS Host port (common to OHCI & EHCI) */ @@ -422,8 +416,8 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9g45_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index effb399..4f14b54 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -41,7 +41,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ - at91sam9rl_initialize(12000000); + at91_initialize(12000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -53,12 +53,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9rl_init_interrupts(NULL); -} - - /* * USB HS Device port */ @@ -330,8 +324,8 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, - .map_io = at91sam9rl_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 6010ce1..c73d25e 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -42,7 +42,7 @@ static void __init snapper9260_init_early(void) { - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* Debug on ttyS0 */ at91_register_uart(0, 0, 0); @@ -55,11 +55,6 @@ static void __init snapper9260_init_early(void) at91_register_uart(AT91SAM9260_ID_US2, 3, 0); } -static void __init snapper9260_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - static struct at91_usbh_data __initdata snapper9260_usbh_data = { .ports = 2, }; @@ -179,9 +174,9 @@ static void __init snapper9260_board_init(void) MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = snapper9260_init_early, - .init_irq = snapper9260_init_irq, + .init_irq = at91_init_irq_default, .init_machine = snapper9260_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 5e5c856..936e5fd 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -35,7 +35,7 @@ void __init stamp9g20_init_early(void) { /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); + at91_initialize(18432000); /* DGBU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -76,12 +76,6 @@ static void __init portuxg20_init_early(void) at91_register_uart(AT91SAM9260_ID_US5, 6, 0); } -static void __init init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * NAND flash */ @@ -299,17 +293,17 @@ static void __init stamp9g20evb_board_init(void) MACHINE_START(PORTUXG20, "taskit PortuxG20") /* Maintainer: taskit GmbH */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = portuxg20_init_early, - .init_irq = init_irq, + .init_irq = at91_init_irq_default, .init_machine = portuxg20_board_init, MACHINE_END MACHINE_START(STAMP9G20, "taskit Stamp9G20") /* Maintainer: taskit GmbH */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = stamp9g20evb_init_early, - .init_irq = init_irq, + .init_irq = at91_init_irq_default, .init_machine = stamp9g20evb_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c index 0e784e6..8c4c1a0 100644 --- a/arch/arm/mach-at91/board-usb-a9260.c +++ b/arch/arm/mach-at91/board-usb-a9260.c @@ -51,7 +51,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ - at91sam9260_initialize(12000000); + at91_initialize(12000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -60,12 +60,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -229,8 +223,8 @@ static void __init ek_board_init(void) MACHINE_START(USB_A9260, "CALAO USB_A9260") /* Maintainer: calao-systems */ .timer = &at91sam926x_timer, - .map_io = at91sam9260_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c index cf626dd..25e7937 100644 --- a/arch/arm/mach-at91/board-usb-a9263.c +++ b/arch/arm/mach-at91/board-usb-a9263.c @@ -50,7 +50,7 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.00 MHz crystal */ - at91sam9263_initialize(12000000); + at91_initialize(12000000); /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -59,12 +59,6 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static void __init ek_init_irq(void) -{ - at91sam9263_init_interrupts(NULL); -} - - /* * USB Host port */ @@ -245,8 +239,8 @@ static void __init ek_board_init(void) MACHINE_START(USB_A9263, "CALAO USB_A9263") /* Maintainer: calao-systems */ .timer = &at91sam926x_timer, - .map_io = at91sam9263_map_io, + .map_io = at91_map_io, .init_early = ek_init_early, - .init_irq = ek_init_irq, + .init_irq = at91_init_irq_default, .init_machine = ek_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index c208cc3..95edcbd 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -56,7 +56,7 @@ static void __init yl9200_init_early(void) at91rm9200_set_type(ARCH_REVISON_9200_PQFP); /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000); + at91_initialize(18432000); /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); @@ -79,12 +79,6 @@ static void __init yl9200_init_early(void) at91_set_serial_console(0); } -static void __init yl9200_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - - /* * LEDs */ @@ -599,8 +593,8 @@ static void __init yl9200_board_init(void) MACHINE_START(YL9200, "uCdragon YL-9200") /* Maintainer: S.Birtles */ .timer = &at91rm9200_timer, - .map_io = at91rm9200_map_io, + .map_io = at91_map_io, .init_early = yl9200_init_early, - .init_irq = yl9200_init_irq, + .init_irq = at91_init_irq_default, .init_machine = yl9200_board_init, MACHINE_END diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 8ff3418..938b34f 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -11,35 +11,19 @@ #include <linux/clkdev.h> /* Map io */ -extern void __init at91rm9200_map_io(void); -extern void __init at91sam9260_map_io(void); -extern void __init at91sam9261_map_io(void); -extern void __init at91sam9263_map_io(void); -extern void __init at91sam9rl_map_io(void); -extern void __init at91sam9g45_map_io(void); -extern void __init at91x40_map_io(void); -extern void __init at91cap9_map_io(void); +extern void __init at91_map_io(void); +extern void __init at91_init_sram(int bank, unsigned long base, + unsigned int length); /* Processors */ extern void __init at91rm9200_set_type(int type); -extern void __init at91rm9200_initialize(unsigned long main_clock); -extern void __init at91sam9260_initialize(unsigned long main_clock); -extern void __init at91sam9261_initialize(unsigned long main_clock); -extern void __init at91sam9263_initialize(unsigned long main_clock); -extern void __init at91sam9rl_initialize(unsigned long main_clock); -extern void __init at91sam9g45_initialize(unsigned long main_clock); +extern void __init at91_initialize(unsigned long main_clock); extern void __init at91x40_initialize(unsigned long main_clock); -extern void __init at91cap9_initialize(unsigned long main_clock); /* Interrupts */ -extern void __init at91rm9200_init_interrupts(unsigned int priority[]); -extern void __init at91sam9260_init_interrupts(unsigned int priority[]); -extern void __init at91sam9261_init_interrupts(unsigned int priority[]); -extern void __init at91sam9263_init_interrupts(unsigned int priority[]); -extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); -extern void __init at91sam9g45_init_interrupts(unsigned int priority[]); +extern void __init at91_init_irq_default(void); +extern void __init at91_init_interrupts(unsigned int priority[]); extern void __init at91x40_init_interrupts(unsigned int priority[]); -extern void __init at91cap9_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ @@ -49,7 +33,6 @@ extern struct sys_timer at91sam926x_timer; extern struct sys_timer at91x40_timer; /* Clocks */ -extern int __init at91_clock_init(unsigned long main_clock); /* * function to specify the clock of the default console. As we do not * use the device/driver bus, the dev_name is not intialize. So we need @@ -62,6 +45,11 @@ extern void __init at91sam9263_set_console_clock(int id); extern void __init at91sam9rl_set_console_clock(int id); extern void __init at91sam9g45_set_console_clock(int id); extern void __init at91cap9_set_console_clock(int id); +#ifdef CONFIG_AT91_PMC_UNIT +extern int __init at91_clock_init(unsigned long main_clock); +#else +static int inline at91_clock_init(unsigned long main_clock) { return 0; } +#endif struct device; /* Power Management */ diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h index 6dcaa77..dbfe455a 100644 --- a/arch/arm/mach-at91/include/mach/at91_dbgu.h +++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h @@ -16,22 +16,25 @@ #ifndef AT91_DBGU_H #define AT91_DBGU_H +#define dbgu_readl(dbgu, field) \ + __raw_readl(AT91_VA_BASE_SYS + dbgu + AT91_DBGU_ ## field) + #ifdef AT91_DBGU -#define AT91_DBGU_CR (AT91_DBGU + 0x00) /* Control Register */ -#define AT91_DBGU_MR (AT91_DBGU + 0x04) /* Mode Register */ -#define AT91_DBGU_IER (AT91_DBGU + 0x08) /* Interrupt Enable Register */ +#define AT91_DBGU_CR (0x00) /* Control Register */ +#define AT91_DBGU_MR (0x04) /* Mode Register */ +#define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ #define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */ #define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */ -#define AT91_DBGU_IDR (AT91_DBGU + 0x0c) /* Interrupt Disable Register */ -#define AT91_DBGU_IMR (AT91_DBGU + 0x10) /* Interrupt Mask Register */ -#define AT91_DBGU_SR (AT91_DBGU + 0x14) /* Status Register */ -#define AT91_DBGU_RHR (AT91_DBGU + 0x18) /* Receiver Holding Register */ -#define AT91_DBGU_THR (AT91_DBGU + 0x1c) /* Transmitter Holding Register */ -#define AT91_DBGU_BRGR (AT91_DBGU + 0x20) /* Baud Rate Generator Register */ +#define AT91_DBGU_IDR (0x0c) /* Interrupt Disable Register */ +#define AT91_DBGU_IMR (0x10) /* Interrupt Mask Register */ +#define AT91_DBGU_SR (0x14) /* Status Register */ +#define AT91_DBGU_RHR (0x18) /* Receiver Holding Register */ +#define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ +#define AT91_DBGU_BRGR (0x20) /* Baud Rate Generator Register */ -#define AT91_DBGU_CIDR (AT91_DBGU + 0x40) /* Chip ID Register */ -#define AT91_DBGU_EXID (AT91_DBGU + 0x44) /* Chip ID Extension Register */ -#define AT91_DBGU_FNR (AT91_DBGU + 0x48) /* Force NTRST Register [SAM9 only] */ +#define AT91_DBGU_CIDR (0x40) /* Chip ID Register */ +#define AT91_DBGU_EXID (0x44) /* Chip ID Extension Register */ +#define AT91_DBGU_FNR (0x48) /* Force NTRST Register [SAM9 only] */ #define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */ #endif /* AT91_DBGU */ diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h deleted file mode 100644 index fecc2e9..0000000 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91_wdt.h - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Watchdog Timer (WDT) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * 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. - */ - -#ifndef AT91_WDT_H -#define AT91_WDT_H - -#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ -#define AT91_WDT_WDRSTT (1 << 0) /* Restart */ -#define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ - -#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ -#define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ -#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ -#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ -#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */ -#define AT91_WDT_WDDIS (1 << 15) /* Watchdog Disable */ -#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */ -#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ -#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ - -#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */ -#define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */ -#define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */ - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 6659938..c5df1e8 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -75,7 +75,6 @@ #define AT91CAP9_BASE_EMAC 0xfffbc000 #define AT91CAP9_BASE_ADC 0xfffc0000 #define AT91CAP9_BASE_ISI 0xfffc4000 -#define AT91_BASE_SYS 0xffffe200 /* * System Peripherals (offset from AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 99e0f8d..e4037b5 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -74,7 +74,6 @@ #define AT91RM9200_BASE_SSC1 0xfffd4000 #define AT91RM9200_BASE_SSC2 0xfffd8000 #define AT91RM9200_BASE_SPI 0xfffe0000 -#define AT91_BASE_SYS 0xfffff000 /* diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 8b6bf83..9a79116 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -76,7 +76,6 @@ #define AT91SAM9260_BASE_TC4 0xfffdc040 #define AT91SAM9260_BASE_TC5 0xfffdc080 #define AT91SAM9260_BASE_ADC 0xfffe0000 -#define AT91_BASE_SYS 0xffffe800 /* * System Peripherals (offset from AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index eafbdda..ce59620 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -60,7 +60,6 @@ #define AT91SAM9261_BASE_SSC2 0xfffc4000 #define AT91SAM9261_BASE_SPI0 0xfffc8000 #define AT91SAM9261_BASE_SPI1 0xfffcc000 -#define AT91_BASE_SYS 0xffffea00 /* diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index e2d3482..f1b9296 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -70,7 +70,6 @@ #define AT91SAM9263_BASE_EMAC 0xfffbc000 #define AT91SAM9263_BASE_ISI 0xfffc4000 #define AT91SAM9263_BASE_2DGE 0xfffc8000 -#define AT91_BASE_SYS 0xffffe000 /* * System Peripherals (offset from AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 659304a..2c611b9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -82,7 +82,6 @@ #define AT91SAM9G45_BASE_TC3 0xfffd4000 #define AT91SAM9G45_BASE_TC4 0xfffd4040 #define AT91SAM9G45_BASE_TC5 0xfffd4080 -#define AT91_BASE_SYS 0xffffe200 /* * System Peripherals (offset from AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 41dbbe6..1aabacd 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -64,7 +64,6 @@ #define AT91SAM9RL_BASE_TSC 0xfffd0000 #define AT91SAM9RL_BASE_UDPHS 0xfffd4000 #define AT91SAM9RL_BASE_AC97C 0xfffd8000 -#define AT91_BASE_SYS 0xffffc000 /* diff --git a/arch/arm/mach-at91/include/mach/clkdev.h b/arch/arm/mach-at91/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-at91/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index df966c2..f6ce936 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -1,7 +1,8 @@ /* * arch/arm/mach-at91/include/mach/cpu.h * - * Copyright (C) 2006 SAN People + * Copyright (C) 2006 SAN People + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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 @@ -10,12 +11,8 @@ * */ -#ifndef __ASM_ARCH_CPU_H -#define __ASM_ARCH_CPU_H - -#include <mach/hardware.h> -#include <mach/at91_dbgu.h> - +#ifndef __MACH_CPU_H__ +#define __MACH_CPU_H__ #define ARCH_ID_AT91RM9200 0x09290780 #define ARCH_ID_AT91SAM9260 0x019803a0 @@ -39,16 +36,6 @@ #define ARCH_ID_AT91M40807 0x14080745 #define ARCH_ID_AT91R40008 0x44000840 -static inline unsigned long at91_cpu_identify(void) -{ - return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); -} - -static inline unsigned long at91_cpu_fully_identify(void) -{ - return at91_sys_read(AT91_DBGU_CIDR); -} - #define ARCH_EXID_AT91SAM9M11 0x00000001 #define ARCH_EXID_AT91SAM9M10 0x00000002 #define ARCH_EXID_AT91SAM9G46 0x00000003 @@ -60,40 +47,80 @@ static inline unsigned long at91_cpu_fully_identify(void) #define ARCH_EXID_AT91SAM9G25 0x00000003 #define ARCH_EXID_AT91SAM9X25 0x00000004 -static inline unsigned long at91_exid_identify(void) -{ - return at91_sys_read(AT91_DBGU_EXID); -} - - #define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 -static inline unsigned long at91_arch_identify(void) -{ - return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH); -} - -#ifdef CONFIG_ARCH_AT91CAP9 -#include <mach/at91_pmc.h> - +/* PMC revision */ #define ARCH_REVISION_CAP9_B 0x399 #define ARCH_REVISION_CAP9_C 0x601 -static inline unsigned long at91cap9_rev_identify(void) +/* RM9200 type */ +#define ARCH_REVISON_9200_BGA (0 << 0) +#define ARCH_REVISON_9200_PQFP (1 << 0) + +enum at91_soc_type { + /* 920T */ + AT91_SOC_RM9200, + + /* CAP */ + AT91_SOC_CAP9, + + /* SAM92xx */ + AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263, + + /* SAM9Gxx */ + AT91_SOC_SAM9G10, AT91_SOC_SAM9G20, AT91_SOC_SAM9G45, + + /* SAM9RL */ + AT91_SOC_SAM9RL, + + /* SAM9X5 */ + AT91_SOC_SAM9X5, + + /* Unknown type */ + AT91_SOC_NONE +}; + +enum at91_soc_subtype { + /* RM9200 */ + AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP, + + /* CAP9 */ + AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C, + + /* SAM9260 */ + AT91_SOC_SAM9XE, + + /* SAM9G45 */ + AT91_SOC_SAM9G45ES, AT91_SOC_SAM9M10, AT91_SOC_SAM9G46, AT91_SOC_SAM9M11, + + /* SAM9X5 */ + AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35, + AT91_SOC_SAM9G25, AT91_SOC_SAM9X25, + + /* Unknown subtype */ + AT91_SOC_SUBTYPE_NONE +}; + +struct at91_socinfo { + unsigned int type, subtype; + unsigned int cidr, exid; +}; + +extern struct at91_socinfo at91_soc_initdata; +const char *at91_get_soc_type(struct at91_socinfo *c); +const char *at91_get_soc_subtype(struct at91_socinfo *c); + +static inline int at91_soc_is_detected(void) { - return (at91_sys_read(AT91_PMC_VER)); + return at91_soc_initdata.type != AT91_SOC_NONE; } -#endif #ifdef CONFIG_ARCH_AT91RM9200 -extern int rm9200_type; -#define ARCH_REVISON_9200_BGA (0 << 0) -#define ARCH_REVISON_9200_PQFP (1 << 0) -#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200) -#define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp()) -#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP) +#define cpu_is_at91rm9200() (at91_soc_initdata.type == AT91_SOC_RM9200) +#define cpu_is_at91rm9200_bga() (at91_soc_initdata.subtype == AT91_SOC_RM9200_BGA) +#define cpu_is_at91rm9200_pqfp() (at91_soc_initdata.subtype == AT91_SOC_RM9200_PQFP) #else #define cpu_is_at91rm9200() (0) #define cpu_is_at91rm9200_bga() (0) @@ -101,52 +128,49 @@ extern int rm9200_type; #endif #ifdef CONFIG_ARCH_AT91SAM9260 -#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE) -#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe()) +#define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE) +#define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260) #else #define cpu_is_at91sam9xe() (0) #define cpu_is_at91sam9260() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9G20 -#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20) +#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20) #else #define cpu_is_at91sam9g20() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9261 -#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261) +#define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261) #else #define cpu_is_at91sam9261() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9G10 -#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) +#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10) #else #define cpu_is_at91sam9g10() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9263 -#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) +#define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263) #else #define cpu_is_at91sam9263() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9RL -#define cpu_is_at91sam9rl() (at91_cpu_identify() == ARCH_ID_AT91SAM9RL64) +#define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL) #else #define cpu_is_at91sam9rl() (0) #endif #ifdef CONFIG_ARCH_AT91SAM9G45 -#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) -#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES) -#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9M10)) -#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9G46)) -#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9M11)) +#define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45) +#define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES) +#define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10) +#define cpu_is_at91sam9g46() (at91_soc_initdata.subtype == AT91_SOC_SAM9G46) +#define cpu_is_at91sam9m11() (at91_soc_initdata.subtype == AT91_SOC_SAM9M11) #else #define cpu_is_at91sam9g45() (0) #define cpu_is_at91sam9g45es() (0) @@ -156,17 +180,12 @@ extern int rm9200_type; #endif #ifdef CONFIG_ARCH_AT91SAM9X5 -#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5) -#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9G15)) -#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9G35)) -#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9X35)) -#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9G25)) -#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ - (at91_exid_identify() == ARCH_EXID_AT91SAM9X25)) +#define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5) +#define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15) +#define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35) +#define cpu_is_at91sam9x35() (at91_soc_initdata.subtype == AT91_SOC_SAM9X35) +#define cpu_is_at91sam9g25() (at91_soc_initdata.subtype == AT91_SOC_SAM9G25) +#define cpu_is_at91sam9x25() (at91_soc_initdata.subtype == AT91_SOC_SAM9X25) #else #define cpu_is_at91sam9x5() (0) #define cpu_is_at91sam9g15() (0) @@ -177,9 +196,9 @@ extern int rm9200_type; #endif #ifdef CONFIG_ARCH_AT91CAP9 -#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) -#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) -#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C) +#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9) +#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B) +#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C) #else #define cpu_is_at91cap9() (0) #define cpu_is_at91cap9_revB() (0) @@ -192,4 +211,4 @@ extern int rm9200_type; */ #define cpu_is_at32ap7000() (0) -#endif +#endif /* __MACH_CPU_H__ */ diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S index 0f959fa..bc1e0b2 100644 --- a/arch/arm/mach-at91/include/mach/debug-macro.S +++ b/arch/arm/mach-at91/include/mach/debug-macro.S @@ -15,23 +15,23 @@ #include <mach/at91_dbgu.h> .macro addruart, rp, rv - ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) - ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) + ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) + ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) .endm .macro senduart,rd,rx - strb \rd, [\rx, #(AT91_DBGU_THR - AT91_DBGU)] @ Write to Transmitter Holding Register + strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register .endm .macro waituart,rd,rx -1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register - tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit +1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register + tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit beq 1001b .endm .macro busyuart,rd,rx -1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register - tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete +1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register + tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete beq 1001b .endm diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 1008b9f..483478d 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -36,6 +36,20 @@ #error "Unsupported AT91 processor" #endif +#if !defined(CONFIG_ARCH_AT91X40) +/* + * On all at91 except rm9200 and x40 have the System Controller starts + * at address 0xffffc000 and has a size of 16KiB. + * + * On rm9200 it's start at 0xfffe4000 of 111KiB with non reserved data starting + * at 0xfffff000 + * + * Removes the individual definitions of AT91_BASE_SYS and + * replaces them with a common version at base 0xfffffc000 and size 16KiB + * and map the same memory space + */ +#define AT91_BASE_SYS 0xffffc000 +#endif /* * Peripheral identifiers/interrupts. diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h index 0b0cccc..4298e78 100644 --- a/arch/arm/mach-at91/include/mach/io.h +++ b/arch/arm/mach-at91/include/mach/io.h @@ -21,14 +21,23 @@ #ifndef __ASM_ARCH_IO_H #define __ASM_ARCH_IO_H +#include <mach/hardware.h> + #define IO_SPACE_LIMIT 0xFFFFFFFF #define __io(a) __typesafe_io(a) #define __mem_pci(a) (a) - #ifndef __ASSEMBLY__ +#ifndef CONFIG_ARCH_AT91X40 +#define __arch_ioremap at91_ioremap +#define __arch_iounmap at91_iounmap +#endif + +void __iomem *at91_ioremap(unsigned long phys, size_t size, unsigned int type); +void at91_iounmap(volatile void __iomem *addr); + static inline unsigned int at91_sys_read(unsigned int reg_offset) { void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ea53f4d..4159eca 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -20,7 +20,7 @@ #include <linux/io.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c new file mode 100644 index 0000000..aa64294 --- /dev/null +++ b/arch/arm/mach-at91/setup.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <linux/module.h> +#include <linux/io.h> +#include <linux/mm.h> + +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/cpu.h> +#include <mach/at91_dbgu.h> +#include <mach/at91_pmc.h> + +#include "soc.h" +#include "generic.h" + +struct at91_init_soc __initdata at91_boot_soc; + +struct at91_socinfo at91_soc_initdata; +EXPORT_SYMBOL(at91_soc_initdata); + +void __init at91rm9200_set_type(int type) +{ + if (type == ARCH_REVISON_9200_PQFP) + at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; + else + at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; +} + +void __init at91_init_irq_default(void) +{ + at91_init_interrupts(at91_boot_soc.default_irq_priority); +} + +void __init at91_init_interrupts(unsigned int *priority) +{ + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} + +static struct map_desc sram_desc[2] __initdata; + +void __init at91_init_sram(int bank, unsigned long base, unsigned int length) +{ + struct map_desc *desc = &sram_desc[bank]; + + desc->virtual = AT91_IO_VIRT_BASE - length; + if (bank > 0) + desc->virtual -= sram_desc[bank - 1].length; + + desc->pfn = __phys_to_pfn(base); + desc->length = length; + desc->type = MT_DEVICE; + + pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", + base, length, desc->virtual); + + iotable_init(desc, 1); +} + +static struct map_desc at91_io_desc __initdata = { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, +}; + +void __iomem *at91_ioremap(unsigned long p, size_t size, unsigned int type) +{ + if (p >= AT91_BASE_SYS && p <= (AT91_BASE_SYS + SZ_16K - 1)) + return (void __iomem *)AT91_IO_P2V(p); + + return __arm_ioremap_caller(p, size, type, __builtin_return_address(0)); +} +EXPORT_SYMBOL(at91_ioremap); + +void at91_iounmap(volatile void __iomem *addr) +{ + unsigned long virt = (unsigned long)addr; + + if (virt >= VMALLOC_START && virt < VMALLOC_END) + __iounmap(addr); +} +EXPORT_SYMBOL(at91_iounmap); + +#define AT91_DBGU0 0xfffff200 +#define AT91_DBGU1 0xffffee00 + +static void __init soc_detect(u32 dbgu_base) +{ + u32 cidr, socid; + + cidr = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_CIDR); + socid = cidr & ~AT91_CIDR_VERSION; + + switch (socid) { + case ARCH_ID_AT91CAP9: { +#ifdef CONFIG_AT91_PMC_UNIT + u32 pmc_ver = at91_sys_read(AT91_PMC_VER); + + if (pmc_ver == ARCH_REVISION_CAP9_B) + at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B; + else if (pmc_ver == ARCH_REVISION_CAP9_C) + at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C; +#endif + at91_soc_initdata.type = AT91_SOC_CAP9; + at91_boot_soc = at91cap9_soc; + break; + } + + case ARCH_ID_AT91RM9200: + at91_soc_initdata.type = AT91_SOC_RM9200; + at91_boot_soc = at91rm9200_soc; + break; + + case ARCH_ID_AT91SAM9260: + at91_soc_initdata.type = AT91_SOC_SAM9260; + at91_boot_soc = at91sam9260_soc; + break; + + case ARCH_ID_AT91SAM9261: + at91_soc_initdata.type = AT91_SOC_SAM9261; + at91_boot_soc = at91sam9261_soc; + break; + + case ARCH_ID_AT91SAM9263: + at91_soc_initdata.type = AT91_SOC_SAM9263; + at91_boot_soc = at91sam9263_soc; + break; + + case ARCH_ID_AT91SAM9G20: + at91_soc_initdata.type = AT91_SOC_SAM9G20; + at91_boot_soc = at91sam9260_soc; + break; + + case ARCH_ID_AT91SAM9G45: + at91_soc_initdata.type = AT91_SOC_SAM9G45; + if (cidr == ARCH_ID_AT91SAM9G45ES) + at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES; + at91_boot_soc = at91sam9g45_soc; + break; + + case ARCH_ID_AT91SAM9RL64: + at91_soc_initdata.type = AT91_SOC_SAM9RL; + at91_boot_soc = at91sam9rl_soc; + break; + + case ARCH_ID_AT91SAM9X5: + at91_soc_initdata.type = AT91_SOC_SAM9X5; + at91_boot_soc = at91sam9x5_soc; + break; + } + + /* at91sam9g10 */ + if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { + at91_soc_initdata.type = AT91_SOC_SAM9G10; + at91_boot_soc = at91sam9261_soc; + } + /* at91sam9xe */ + else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) { + at91_soc_initdata.type = AT91_SOC_SAM9260; + at91_soc_initdata.subtype = AT91_SOC_SAM9XE; + at91_boot_soc = at91sam9260_soc; + } + + if (!at91_soc_is_detected()) + return; + + at91_soc_initdata.cidr = cidr; + + /* sub version of soc */ + at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID); + + if (at91_soc_initdata.type == AT91_SOC_SAM9G45) { + switch (at91_soc_initdata.exid) { + case ARCH_EXID_AT91SAM9M10: + at91_soc_initdata.subtype = AT91_SOC_SAM9M10; + break; + case ARCH_EXID_AT91SAM9G46: + at91_soc_initdata.subtype = AT91_SOC_SAM9G46; + break; + case ARCH_EXID_AT91SAM9M11: + at91_soc_initdata.subtype = AT91_SOC_SAM9M11; + break; + } + } + + if (at91_soc_initdata.type == AT91_SOC_SAM9X5) { + switch (at91_soc_initdata.exid) { + case ARCH_EXID_AT91SAM9G15: + at91_soc_initdata.subtype = AT91_SOC_SAM9G15; + break; + case ARCH_EXID_AT91SAM9G35: + at91_soc_initdata.subtype = AT91_SOC_SAM9G35; + break; + case ARCH_EXID_AT91SAM9X35: + at91_soc_initdata.subtype = AT91_SOC_SAM9X35; + break; + case ARCH_EXID_AT91SAM9G25: + at91_soc_initdata.subtype = AT91_SOC_SAM9G25; + break; + case ARCH_EXID_AT91SAM9X25: + at91_soc_initdata.subtype = AT91_SOC_SAM9X25; + break; + } + } +} + +static const char *soc_name[] = { + [AT91_SOC_RM9200] = "at91rm9200", + [AT91_SOC_CAP9] = "at91cap9", + [AT91_SOC_SAM9260] = "at91sam9260", + [AT91_SOC_SAM9261] = "at91sam9261", + [AT91_SOC_SAM9263] = "at91sam9263", + [AT91_SOC_SAM9G10] = "at91sam9g10", + [AT91_SOC_SAM9G20] = "at91sam9g20", + [AT91_SOC_SAM9G45] = "at91sam9g45", + [AT91_SOC_SAM9RL] = "at91sam9rl", + [AT91_SOC_SAM9X5] = "at91sam9x5", + [AT91_SOC_NONE] = "Unknown" +}; + +const char *at91_get_soc_type(struct at91_socinfo *c) +{ + return soc_name[c->type]; +} +EXPORT_SYMBOL(at91_get_soc_type); + +static const char *soc_subtype_name[] = { + [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA", + [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP", + [AT91_SOC_CAP9_REV_B] = "at91cap9 revB", + [AT91_SOC_CAP9_REV_C] = "at91cap9 revC", + [AT91_SOC_SAM9XE] = "at91sam9xe", + [AT91_SOC_SAM9G45ES] = "at91sam9g45es", + [AT91_SOC_SAM9M10] = "at91sam9m10", + [AT91_SOC_SAM9G46] = "at91sam9g46", + [AT91_SOC_SAM9M11] = "at91sam9m11", + [AT91_SOC_SAM9G15] = "at91sam9g15", + [AT91_SOC_SAM9G35] = "at91sam9g35", + [AT91_SOC_SAM9X35] = "at91sam9x35", + [AT91_SOC_SAM9G25] = "at91sam9g25", + [AT91_SOC_SAM9X25] = "at91sam9x25", + [AT91_SOC_SUBTYPE_NONE] = "Unknown" +}; + +const char *at91_get_soc_subtype(struct at91_socinfo *c) +{ + return soc_subtype_name[c->subtype]; +} +EXPORT_SYMBOL(at91_get_soc_subtype); + +void __init at91_map_io(void) +{ + /* Map peripherals */ + iotable_init(&at91_io_desc, 1); + + at91_soc_initdata.type = AT91_SOC_NONE; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; + + soc_detect(AT91_DBGU0); + if (!at91_soc_is_detected()) + soc_detect(AT91_DBGU1); + + if (!at91_soc_is_detected()) + panic("AT91: Impossible to detect the SOC type"); + + pr_info("AT91: Detected soc type: %s\n", + at91_get_soc_type(&at91_soc_initdata)); + pr_info("AT91: Detected soc subtype: %s\n", + at91_get_soc_subtype(&at91_soc_initdata)); + + if (!at91_soc_is_enabled()) + panic("AT91: Soc not enabled"); + + if (at91_boot_soc.map_io) + at91_boot_soc.map_io(); +} + +void __init at91_initialize(unsigned long main_clock) +{ + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91_boot_soc.register_clocks(); + + at91_boot_soc.init(); +} diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h new file mode 100644 index 0000000..21ed881 --- /dev/null +++ b/arch/arm/mach-at91/soc.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +struct at91_init_soc { + unsigned int *default_irq_priority; + void (*map_io)(void); + void (*register_clocks)(void); + void (*init)(void); +}; + +extern struct at91_init_soc at91_boot_soc; +extern struct at91_init_soc at91cap9_soc; +extern struct at91_init_soc at91rm9200_soc; +extern struct at91_init_soc at91sam9260_soc; +extern struct at91_init_soc at91sam9261_soc; +extern struct at91_init_soc at91sam9263_soc; +extern struct at91_init_soc at91sam9g45_soc; +extern struct at91_init_soc at91sam9rl_soc; +extern struct at91_init_soc at91sam9x5_soc; + +static inline int at91_soc_is_enabled(void) +{ + return at91_boot_soc.init != NULL; +} + +#if !defined(CONFIG_ARCH_AT91CAP9) +#define at91cap9_soc at91_boot_soc +#endif + +#if !defined(CONFIG_ARCH_AT91RM9200) +#define at91rm9200_soc at91_boot_soc +#endif + +#if !(defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)) +#define at91sam9260_soc at91_boot_soc +#endif + +#if !(defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)) +#define at91sam9261_soc at91_boot_soc +#endif + +#if !defined(CONFIG_ARCH_AT91SAM9263) +#define at91sam9263_soc at91_boot_soc +#endif + +#if !defined(CONFIG_ARCH_AT91SAM9G45) +#define at91sam9g45_soc at91_boot_soc +#endif + +#if !defined(CONFIG_ARCH_AT91SAM9RL) +#define at91sam9rl_soc at91_boot_soc +#endif + +#if !defined(CONFIG_ARCH_AT91SAM9X5) +#define at91sam9x5_soc at91_boot_soc +#endif diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 9f2a948..0ca0005 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -34,7 +34,7 @@ #include <linux/mm.h> #include <linux/pfn.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <mach/dma.h> /* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */ diff --git a/arch/arm/mach-bcmring/include/mach/clkdev.h b/arch/arm/mach-bcmring/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-bcmring/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h index 8bf3564..ed78aab 100644 --- a/arch/arm/mach-bcmring/include/mach/hardware.h +++ b/arch/arm/mach-bcmring/include/mach/hardware.h @@ -36,8 +36,6 @@ #define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED) #define RAM_BASE PAGE_OFFSET -#define pcibios_assign_all_busses() 1 - /* Macros to make managing spinlocks a bit more controlled in terms of naming. */ /* See reg_gpio.h, reg_irq.h, arch.c, gpio.c for example usage. */ #if defined(__KERNEL__) diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 08e5c87..3e7d149 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -29,7 +29,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> -#include <mach/hardware.h> #include <mach/cns3xxx.h> #include <mach/irqs.h> #include "core.h" @@ -170,6 +169,8 @@ static struct platform_device *cns3420_pdevs[] __initdata = { static void __init cns3420_init(void) { + cns3xxx_l2x0_init(); + platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs)); cns3xxx_ahci_init(); diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c index da30078..941a308 100644 --- a/arch/arm/mach-cns3xxx/core.c +++ b/arch/arm/mach-cns3xxx/core.c @@ -16,6 +16,7 @@ #include <asm/mach/time.h> #include <asm/mach/irq.h> #include <asm/hardware/gic.h> +#include <asm/hardware/cache-l2x0.h> #include <mach/cns3xxx.h> #include "core.h" @@ -244,3 +245,45 @@ static void __init cns3xxx_timer_init(void) struct sys_timer cns3xxx_timer = { .init = cns3xxx_timer_init, }; + +#ifdef CONFIG_CACHE_L2X0 + +void __init cns3xxx_l2x0_init(void) +{ + void __iomem *base = ioremap(CNS3XXX_L2C_BASE, SZ_4K); + u32 val; + + if (WARN_ON(!base)) + return; + + /* + * Tag RAM Control register + * + * bit[10:8] - 1 cycle of write accesses latency + * bit[6:4] - 1 cycle of read accesses latency + * bit[3:0] - 1 cycle of setup latency + * + * 1 cycle of latency for setup, read and write accesses + */ + val = readl(base + L2X0_TAG_LATENCY_CTRL); + val &= 0xfffff888; + writel(val, base + L2X0_TAG_LATENCY_CTRL); + + /* + * Data RAM Control register + * + * bit[10:8] - 1 cycles of write accesses latency + * bit[6:4] - 1 cycles of read accesses latency + * bit[3:0] - 1 cycle of setup latency + * + * 1 cycle of latency for setup, read and write accesses + */ + val = readl(base + L2X0_DATA_LATENCY_CTRL); + val &= 0xfffff888; + writel(val, base + L2X0_DATA_LATENCY_CTRL); + + /* 32 KiB, 8-way, parity disable */ + l2x0_init(base, 0x00540000, 0xfe000fff); +} + +#endif /* CONFIG_CACHE_L2X0 */ diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h index ffeb3a8..fcd2253 100644 --- a/arch/arm/mach-cns3xxx/core.h +++ b/arch/arm/mach-cns3xxx/core.h @@ -13,6 +13,12 @@ extern struct sys_timer cns3xxx_timer; +#ifdef CONFIG_CACHE_L2X0 +void __init cns3xxx_l2x0_init(void); +#else +static inline void cns3xxx_l2x0_init(void) {} +#endif /* CONFIG_CACHE_L2X0 */ + void __init cns3xxx_map_io(void); void __init cns3xxx_init_irq(void); void cns3xxx_power_off(void); diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S index 6bd83ed..d87bfc3 100644 --- a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S +++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S @@ -8,7 +8,6 @@ * published by the Free Software Foundation. */ -#include <mach/hardware.h> #include <asm/hardware/entry-macro-gic.S> .macro disable_fiq diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h deleted file mode 100644 index 57e0983..0000000 --- a/arch/arm/mach-cns3xxx/include/mach/hardware.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file contains the hardware definitions of the Cavium Networks boards. - * - * Copyright 2003 ARM Limited. - * Copyright 2008 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. - */ - -#ifndef __MACH_HARDWARE_H -#define __MACH_HARDWARE_H - -#include <asm/sizes.h> - -/* macro to get at IO space when running virtually */ -#define PCIBIOS_MIN_IO 0x00000000 -#define PCIBIOS_MIN_MEM 0x00000000 -#define pcibios_assign_all_busses() 1 - -#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/pm.h b/arch/arm/mach-cns3xxx/include/mach/pm.h index 6eae7f7..c2588cc 100644 --- a/arch/arm/mach-cns3xxx/include/mach/pm.h +++ b/arch/arm/mach-cns3xxx/include/mach/pm.h @@ -11,7 +11,7 @@ #ifndef __CNS3XXX_PM_H #define __CNS3XXX_PM_H -#include <asm/atomic.h> +#include <linux/atomic.h> void cns3xxx_pwr_clk_en(unsigned int block); void cns3xxx_pwr_clk_dis(unsigned int block); diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h index 58bb03a..4f16c9b 100644 --- a/arch/arm/mach-cns3xxx/include/mach/system.h +++ b/arch/arm/mach-cns3xxx/include/mach/system.h @@ -13,7 +13,6 @@ #include <linux/io.h> #include <asm/proc-fns.h> -#include <mach/hardware.h> static inline void arch_idle(void) { diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h index de8ead9..a91b605 100644 --- a/arch/arm/mach-cns3xxx/include/mach/uncompress.h +++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h @@ -8,7 +8,6 @@ */ #include <asm/mach-types.h> -#include <mach/hardware.h> #include <mach/cns3xxx.h> #define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00)) diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 78defd7..0f8fca4 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -49,7 +49,7 @@ static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata) return &cns3xxx_pcie[root->domain]; } -static struct cns3xxx_pcie *pdev_to_cnspci(struct pci_dev *dev) +static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev) { return sysdata_to_cnspci(dev->sysdata); } @@ -172,7 +172,7 @@ static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys) return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys); } -static int cns3xxx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev); int irq = cnspci->irqs[slot]; @@ -369,6 +369,9 @@ static int __init cns3xxx_pcie_init(void) { int i; + pcibios_min_io = 0; + pcibios_min_mem = 0; + hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0, "imprecise external abort"); diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c index 5e57955..0c04678 100644 --- a/arch/arm/mach-cns3xxx/pm.c +++ b/arch/arm/mach-cns3xxx/pm.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/delay.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <mach/system.h> #include <mach/cns3xxx.h> #include <mach/pm.h> diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 29671ef..008d514 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -115,6 +115,32 @@ static struct spi_board_info da850evm_spi_info[] = { }, }; +#ifdef CONFIG_MTD +static void da850_evm_m25p80_notify_add(struct mtd_info *mtd) +{ + char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; + size_t retlen; + + if (!strcmp(mtd->name, "MAC-Address")) { + mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr); + if (retlen == ETH_ALEN) + pr_info("Read MAC addr from SPI Flash: %pM\n", + mac_addr); + } +} + +static struct mtd_notifier da850evm_spi_notifier = { + .add = da850_evm_m25p80_notify_add, +}; + +static void da850_evm_setup_mac_addr(void) +{ + register_mtd_user(&da850evm_spi_notifier); +} +#else +static void da850_evm_setup_mac_addr(void) { } +#endif + static struct mtd_partition da850_evm_norflash_partition[] = { { .name = "bootloaders + env", @@ -1117,6 +1143,8 @@ static __init int da850_evm_init_cpufreq(void) static __init int da850_evm_init_cpufreq(void) { return 0; } #endif +#define DA850EVM_SATA_REFCLKPN_RATE (100 * 1000 * 1000) + static __init void da850_evm_init(void) { int ret; @@ -1237,6 +1265,13 @@ static __init void da850_evm_init(void) if (ret) pr_warning("da850_evm_init: spi 1 registration failed: %d\n", ret); + + ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE); + if (ret) + pr_warning("da850_evm_init: sata registration failed: %d\n", + ret); + + da850_evm_setup_mac_addr(); } #ifdef CONFIG_SERIAL_8250_CONSOLE diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index ae65319..0086113 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, - PSC_STATE_ENABLE); + true, clk->flags); } static void __clk_disable(struct clk *clk) @@ -54,8 +54,7 @@ static void __clk_disable(struct clk *clk) if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, - (clk->flags & PSC_SWRSTDISABLE) ? - PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); + false, clk->flags); if (clk->parent) __clk_disable(clk->parent); } @@ -239,8 +238,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, - (ck->flags & PSC_SWRSTDISABLE) ? - PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); + false, ck->flags); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 50b2482..a705f36 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -111,6 +111,7 @@ struct clk { #define CLK_PLL BIT(4) /* PLL-derived clock */ #define PRE_PLL BIT(5) /* source is before PLL mult/div */ #define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(7) /* Force module state transtition */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 133aac4..935dbed 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -58,6 +58,7 @@ static struct pll_data pll0_data = { static struct clk ref_clk = { .name = "ref_clk", .rate = DA850_REF_FREQ, + .set_rate = davinci_simple_set_rate, }; static struct clk pll0_clk = { @@ -373,6 +374,14 @@ static struct clk spi1_clk = { .flags = DA850_CLK_ASYNC3, }; +static struct clk sata_clk = { + .name = "sata", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_SATA, + .gpsc = 1, + .flags = PSC_FORCE, +}; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -419,6 +428,7 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "usb20", &usb20_clk), CLK("spi_davinci.0", NULL, &spi0_clk), CLK("spi_davinci.1", NULL, &spi1_clk), + CLK("ahci", NULL, &sata_clk), CLK(NULL, NULL, NULL), }; diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index fc4e98e..2f7e719 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -14,6 +14,8 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/serial_8250.h> +#include <linux/ahci_platform.h> +#include <linux/clk.h> #include <mach/cputype.h> #include <mach/common.h> @@ -33,6 +35,7 @@ #define DA8XX_SPI0_BASE 0x01c41000 #define DA830_SPI1_BASE 0x01e12000 #define DA8XX_LCD_CNTRL_BASE 0x01e13000 +#define DA850_SATA_BASE 0x01e18000 #define DA850_MMCSD1_BASE 0x01e1b000 #define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000 #define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000 @@ -842,3 +845,126 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info, return platform_device_register(&da8xx_spi_device[instance]); } + +#ifdef CONFIG_ARCH_DAVINCI_DA850 + +static struct resource da850_sata_resources[] = { + { + .start = DA850_SATA_BASE, + .end = DA850_SATA_BASE + 0x1fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA850_SATAINT, + .flags = IORESOURCE_IRQ, + }, +}; + +/* SATA PHY Control Register offset from AHCI base */ +#define SATA_P0PHYCR_REG 0x178 + +#define SATA_PHY_MPY(x) ((x) << 0) +#define SATA_PHY_LOS(x) ((x) << 6) +#define SATA_PHY_RXCDR(x) ((x) << 10) +#define SATA_PHY_RXEQ(x) ((x) << 13) +#define SATA_PHY_TXSWING(x) ((x) << 19) +#define SATA_PHY_ENPLL(x) ((x) << 31) + +static struct clk *da850_sata_clk; +static unsigned long da850_sata_refclkpn; + +/* Supported DA850 SATA crystal frequencies */ +#define KHZ_TO_HZ(freq) ((freq) * 1000) +static unsigned long da850_sata_xtal[] = { + KHZ_TO_HZ(300000), + KHZ_TO_HZ(250000), + 0, /* Reserved */ + KHZ_TO_HZ(187500), + KHZ_TO_HZ(150000), + KHZ_TO_HZ(125000), + KHZ_TO_HZ(120000), + KHZ_TO_HZ(100000), + KHZ_TO_HZ(75000), + KHZ_TO_HZ(60000), +}; + +static int da850_sata_init(struct device *dev, void __iomem *addr) +{ + int i, ret; + unsigned int val; + + da850_sata_clk = clk_get(dev, NULL); + if (IS_ERR(da850_sata_clk)) + return PTR_ERR(da850_sata_clk); + + ret = clk_enable(da850_sata_clk); + if (ret) + goto err0; + + /* Enable SATA clock receiver */ + val = __raw_readl(DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); + val &= ~BIT(0); + __raw_writel(val, DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); + + /* Get the multiplier needed for 1.5GHz PLL output */ + for (i = 0; i < ARRAY_SIZE(da850_sata_xtal); i++) + if (da850_sata_xtal[i] == da850_sata_refclkpn) + break; + + if (i == ARRAY_SIZE(da850_sata_xtal)) { + ret = -EINVAL; + goto err1; + } + + val = SATA_PHY_MPY(i + 1) | + SATA_PHY_LOS(1) | + SATA_PHY_RXCDR(4) | + SATA_PHY_RXEQ(1) | + SATA_PHY_TXSWING(3) | + SATA_PHY_ENPLL(1); + + __raw_writel(val, addr + SATA_P0PHYCR_REG); + + return 0; + +err1: + clk_disable(da850_sata_clk); +err0: + clk_put(da850_sata_clk); + return ret; +} + +static void da850_sata_exit(struct device *dev) +{ + clk_disable(da850_sata_clk); + clk_put(da850_sata_clk); +} + +static struct ahci_platform_data da850_sata_pdata = { + .init = da850_sata_init, + .exit = da850_sata_exit, +}; + +static u64 da850_sata_dmamask = DMA_BIT_MASK(32); + +static struct platform_device da850_sata_device = { + .name = "ahci", + .id = -1, + .dev = { + .platform_data = &da850_sata_pdata, + .dma_mask = &da850_sata_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(da850_sata_resources), + .resource = da850_sata_resources, +}; + +int __init da850_register_sata(unsigned long refclkpn) +{ + da850_sata_refclkpn = refclkpn; + if (!da850_sata_refclkpn) + return -EINVAL; + + return platform_device_register(&da850_sata_device); +} +#endif diff --git a/arch/arm/mach-davinci/include/mach/clkdev.h b/arch/arm/mach-davinci/include/mach/clkdev.h deleted file mode 100644 index 14a5048..0000000 --- a/arch/arm/mach-davinci/include/mach/clkdev.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -struct clk; - -static inline int __clk_get(struct clk *clk) -{ - return 1; -} - -static inline void __clk_put(struct clk *clk) -{ -} - -#endif diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index ad64da7..eaca7d8 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -57,6 +57,7 @@ extern unsigned int da850_max_speed; #define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000) #define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x)) #define DA8XX_DEEPSLEEP_REG 0x8 +#define DA8XX_PWRDN_REG 0x18 #define DA8XX_PSC0_BASE 0x01c10000 #define DA8XX_PLL0_BASE 0x01c11000 @@ -89,6 +90,7 @@ int da850_register_cpufreq(char *async_clk); int da8xx_register_cpuidle(void); void __iomem * __init da8xx_get_mem_ctlr(void); int da850_register_pm(struct platform_device *pdev); +int __init da850_register_sata(unsigned long refclkpn); extern struct platform_device da8xx_serial_device; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 1110fdd..fa59c09 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -243,13 +243,14 @@ #define PSC_STATE_DISABLE 2 #define PSC_STATE_ENABLE 3 -#define MDSTAT_STATE_MASK 0x1f +#define MDSTAT_STATE_MASK 0x3f +#define MDCTL_FORCE BIT(31) #ifndef __ASSEMBLER__ extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id); extern void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, u32 next_state); + unsigned int id, bool enable, u32 flags); #endif diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index a415804..1fb6bdf 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -25,6 +25,8 @@ #include <mach/cputype.h> #include <mach/psc.h> +#include "clock.h" + /* Return nonzero iff the domain's clock is active */ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) { @@ -48,11 +50,12 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) /* Enable or disable a PSC domain */ void davinci_psc_config(unsigned int domain, unsigned int ctlr, - unsigned int id, u32 next_state) + unsigned int id, bool enable, u32 flags) { u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; + u32 next_state = PSC_STATE_ENABLE; if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) { pr_warning("PSC: Bad psc data: 0x%x[%d]\n", @@ -62,9 +65,18 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K); + if (!enable) { + if (flags & PSC_SWRSTDISABLE) + next_state = PSC_STATE_SWRSTDISABLE; + else + next_state = PSC_STATE_DISABLE; + } + mdctl = __raw_readl(psc_base + MDCTL + 4 * id); mdctl &= ~MDSTAT_STATE_MASK; mdctl |= next_state; + if (flags & PSC_FORCE) + mdctl |= MDCTL_FORCE; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); pdstat = __raw_readl(psc_base + PDSTAT); diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index fb5e72b..5f1e045 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -217,7 +217,11 @@ ddr2clk_stop_done: ENDPROC(davinci_ddr_psc_config) CACHE_FLUSH: - .word arm926_flush_kern_cache_all +#ifdef CONFIG_CPU_V6 + .word v6_flush_kern_cache_all +#else + .word arm926_flush_kern_cache_all +#endif ENTRY(davinci_cpu_suspend_sz) .word . - davinci_cpu_suspend diff --git a/arch/arm/mach-dove/include/mach/hardware.h b/arch/arm/mach-dove/include/mach/hardware.h index 32b0826..f1368b9 100644 --- a/arch/arm/mach-dove/include/mach/hardware.h +++ b/arch/arm/mach-dove/include/mach/hardware.h @@ -11,13 +11,6 @@ #include "dove.h" -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x1000 -#define PCIBIOS_MIN_MEM 0x01000000 -#define PCIMEM_BASE DOVE_PCIE0_MEM_PHYS_BASE - - /* Macros below are required for compatibility with PXA AC'97 driver. */ #define __REG(x) (*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \ DOVE_SB_REGS_VIRT_BASE))) diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 502d1ca..aa2b3a0 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/mbus.h> +#include <video/vga.h> #include <asm/mach/pci.h> #include <asm/mach/arch.h> #include <asm/setup.h> @@ -192,7 +193,7 @@ dove_pcie_scan_bus(int nr, struct pci_sys_data *sys) return bus; } -static int __init dove_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pcie_port *pp = bus_to_port(dev->bus->number); @@ -228,6 +229,8 @@ static void __init add_pcie_port(int index, unsigned long base) void __init dove_pcie_init(int init_port0, int init_port1) { + vga_base = DOVE_PCIE0_MEM_PHYS_BASE; + if (init_port0) add_pcie_port(0, DOVE_PCIE0_VIRT_BASE); diff --git a/arch/arm/mach-ep93xx/include/mach/clkdev.h b/arch/arm/mach-ep93xx/include/mach/clkdev.h deleted file mode 100644 index 50cb991..0000000 --- a/arch/arm/mach-ep93xx/include/mach/clkdev.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/clkdev.h - */ - -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 5a3ce02..4df8428 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -8,8 +8,6 @@ #include <mach/ep93xx-regs.h> #include <mach/platform.h> -#define pcibios_assign_all_busses() 0 - /* * The EP93xx has two external crystal oscillators. To generate the * required high-frequency clocks, the processor uses two phase-locked- diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 0eabec6..f1397a1 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -6,7 +6,7 @@ * TS72xx memory map: * * virt phys size - * febff000 22000000 4K model number register + * febff000 22000000 4K model number register (bits 0-2) * febfe000 22400000 4K options register * febfd000 22800000 4K options register #2 * febf9000 10800000 4K TS-5620 RTC index register @@ -20,6 +20,9 @@ #define TS72XX_MODEL_TS7200 0x00 #define TS72XX_MODEL_TS7250 0x01 #define TS72XX_MODEL_TS7260 0x02 +#define TS72XX_MODEL_TS7300 0x03 +#define TS72XX_MODEL_TS7400 0x04 +#define TS72XX_MODEL_MASK 0x07 #define TS72XX_OPTIONS_PHYS_BASE 0x22400000 @@ -51,19 +54,34 @@ #ifndef __ASSEMBLY__ +static inline int ts72xx_model(void) +{ + return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK; +} + static inline int board_is_ts7200(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200; + return ts72xx_model() == TS72XX_MODEL_TS7200; } static inline int board_is_ts7250(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250; + return ts72xx_model() == TS72XX_MODEL_TS7250; } static inline int board_is_ts7260(void) { - return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260; + return ts72xx_model() == TS72XX_MODEL_TS7260; +} + +static inline int board_is_ts7300(void) +{ + return ts72xx_model() == TS72XX_MODEL_TS7300; +} + +static inline int board_is_ts7400(void) +{ + return ts72xx_model() == TS72XX_MODEL_TS7400; } static inline int is_max197_installed(void) diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index ae433a0..0c77ab9 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -16,7 +16,8 @@ config CPU_EXYNOS4210 Enable EXYNOS4210 CPU support config EXYNOS4_MCT - bool "Kernel timer support by MCT" + bool + default y help Use MCT (Multi Core Timer) as kernel timers @@ -25,6 +26,11 @@ config EXYNOS4_DEV_AHCI help Compile in platform device definitions for AHCI +config EXYNOS4_SETUP_FIMD0 + bool + help + Common setup code for FIMD0. + config EXYNOS4_DEV_PD bool help @@ -35,6 +41,11 @@ config EXYNOS4_DEV_SYSMMU help Common setup code for SYSTEM MMU in EXYNOS4 +config EXYNOS4_DEV_DWMCI + bool + help + Compile in platform device definitions for DWMCI + config EXYNOS4_SETUP_I2C1 bool help @@ -103,6 +114,7 @@ menu "EXYNOS4 Machines" config MACH_SMDKC210 bool "SMDKC210" select CPU_EXYNOS4210 + select S5P_DEV_FIMD0 select S3C_DEV_RTC select S3C_DEV_WDT select S3C_DEV_I2C1 @@ -114,6 +126,7 @@ config MACH_SMDKC210 select SAMSUNG_DEV_BACKLIGHT select EXYNOS4_DEV_PD select EXYNOS4_DEV_SYSMMU + select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_SDHCI help @@ -122,6 +135,7 @@ config MACH_SMDKC210 config MACH_SMDKV310 bool "SMDKV310" select CPU_EXYNOS4210 + select S5P_DEV_FIMD0 select S3C_DEV_RTC select S3C_DEV_WDT select S3C_DEV_I2C1 @@ -130,10 +144,12 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 select SAMSUNG_DEV_BACKLIGHT + select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD select EXYNOS4_DEV_PD select SAMSUNG_DEV_PWM select EXYNOS4_DEV_SYSMMU + select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_KEYPAD select EXYNOS4_SETUP_SDHCI @@ -157,13 +173,22 @@ config MACH_ARMLEX4210 config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CPU_EXYNOS4210 + select S5P_GPIO_INT + select S5P_DEV_FIMC0 + select S5P_DEV_FIMC1 + select S5P_DEV_FIMC2 + select S5P_DEV_FIMC3 select S3C_DEV_HSMMC select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 select S3C_DEV_I2C1 + select S3C_DEV_I2C3 select S3C_DEV_I2C5 + select S5P_DEV_MFC select S5P_DEV_ONENAND + select EXYNOS4_DEV_PD select EXYNOS4_SETUP_I2C1 + select EXYNOS4_SETUP_I2C3 select EXYNOS4_SETUP_I2C5 select EXYNOS4_SETUP_SDHCI help @@ -180,13 +205,16 @@ config MACH_NURI select S3C_DEV_I2C1 select S3C_DEV_I2C3 select S3C_DEV_I2C5 + select S5P_DEV_MFC select S5P_DEV_USB_EHCI + select EXYNOS4_DEV_PD select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C3 select EXYNOS4_SETUP_I2C5 select EXYNOS4_SETUP_SDHCI select EXYNOS4_SETUP_USB_PHY select SAMSUNG_DEV_PWM + select SAMSUNG_DEV_ADC help Machine support for Samsung Mobile NURI Board. diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index 1366995..b7fe1d7 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -13,18 +13,13 @@ obj- := # Core support for EXYNOS4 system obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o -obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o +obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o pmu.o obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o -ifeq ($(CONFIG_EXYNOS4_MCT),y) -obj-y += mct.o -else -obj-y += time.o -obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o -endif +obj-$(CONFIG_EXYNOS4_MCT) += mct.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o @@ -42,8 +37,10 @@ obj-y += dev-audio.o obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o +obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o +obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 66494f2..1561b03 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -520,7 +520,7 @@ static struct clk init_clocks_off[] = { .ctrlbit = (1 << 21), }, { .name = "ac97", - .id = -1, + .devname = "samsung-ac97", .enable = exynos4_clk_ip_peril_ctrl, .ctrlbit = (1 << 27), }, { @@ -528,6 +528,11 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_image_ctrl, .ctrlbit = (1 << 0), }, { + .name = "mfc", + .devname = "s5p-mfc", + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 0), + }, { .name = "i2c", .devname = "s3c2440-i2c.0", .parent = &clk_aclk_100.clk, @@ -731,6 +736,52 @@ static struct clksrc_sources clkset_mout_g2d = { .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list), }; +static struct clk *clkset_mout_mfc0_list[] = { + [0] = &clk_mout_mpll.clk, + [1] = &clk_sclk_apll.clk, +}; + +static struct clksrc_sources clkset_mout_mfc0 = { + .sources = clkset_mout_mfc0_list, + .nr_sources = ARRAY_SIZE(clkset_mout_mfc0_list), +}; + +static struct clksrc_clk clk_mout_mfc0 = { + .clk = { + .name = "mout_mfc0", + }, + .sources = &clkset_mout_mfc0, + .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 }, +}; + +static struct clk *clkset_mout_mfc1_list[] = { + [0] = &clk_mout_epll.clk, + [1] = &clk_sclk_vpll.clk, +}; + +static struct clksrc_sources clkset_mout_mfc1 = { + .sources = clkset_mout_mfc1_list, + .nr_sources = ARRAY_SIZE(clkset_mout_mfc1_list), +}; + +static struct clksrc_clk clk_mout_mfc1 = { + .clk = { + .name = "mout_mfc1", + }, + .sources = &clkset_mout_mfc1, + .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 }, +}; + +static struct clk *clkset_mout_mfc_list[] = { + [0] = &clk_mout_mfc0.clk, + [1] = &clk_mout_mfc1.clk, +}; + +static struct clksrc_sources clkset_mout_mfc = { + .sources = clkset_mout_mfc_list, + .nr_sources = ARRAY_SIZE(clkset_mout_mfc_list), +}; + static struct clksrc_clk clk_dout_mmc0 = { .clk = { .name = "dout_mmc0", @@ -974,6 +1025,14 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 }, }, { .clk = { + .name = "sclk_mfc", + .devname = "s5p-mfc", + }, + .sources = &clkset_mout_mfc, + .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 }, + .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 }, + }, { + .clk = { .name = "sclk_mmc", .devname = "s3c-sdhci.0", .parent = &clk_dout_mmc0.clk, @@ -1049,6 +1108,8 @@ static struct clksrc_clk *sysclks[] = { &clk_dout_mmc2, &clk_dout_mmc3, &clk_dout_mmc4, + &clk_mout_mfc0, + &clk_mout_mfc1, }; static int xtal_rate; diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index bfd6214..746d6fc 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -16,16 +16,21 @@ #include <asm/proc-fns.h> #include <asm/hardware/cache-l2x0.h> +#include <asm/hardware/gic.h> #include <plat/cpu.h> #include <plat/clock.h> +#include <plat/devs.h> #include <plat/exynos4.h> +#include <plat/adc-core.h> #include <plat/sdhci.h> -#include <plat/devs.h> +#include <plat/fb-core.h> #include <plat/fimc-core.h> #include <plat/iic-core.h> +#include <plat/reset.h> #include <mach/regs-irq.h> +#include <mach/regs-pmu.h> extern int combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start); @@ -103,7 +108,17 @@ static struct map_desc exynos4_iodesc[] __initdata = { .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), .length = SZ_4K, .type = MT_DEVICE, - } + }, { + .virtual = (unsigned long)S5P_VA_GIC_CPU, + .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GIC_DIST, + .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST), + .length = SZ_64K, + .type = MT_DEVICE, + }, }; static void exynos4_idle(void) @@ -114,6 +129,11 @@ static void exynos4_idle(void) local_irq_enable(); } +static void exynos4_sw_reset(void) +{ + __raw_writel(0x1, S5P_SWRESET); +} + /* * exynos4_map_io * @@ -129,6 +149,8 @@ void __init exynos4_map_io(void) exynos4_default_sdhci2(); exynos4_default_sdhci3(); + s3c_adc_setname("samsung-adc-v3"); + s3c_fimc_setname(0, "exynos4-fimc"); s3c_fimc_setname(1, "exynos4-fimc"); s3c_fimc_setname(2, "exynos4-fimc"); @@ -138,6 +160,8 @@ void __init exynos4_map_io(void) s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); s3c_i2c2_setname("s3c2440-i2c"); + + s5p_fb_setname(0, "exynos4-fb"); } void __init exynos4_init_clocks(int xtal) @@ -150,22 +174,23 @@ void __init exynos4_init_clocks(int xtal) exynos4_setup_clocks(); } +static void exynos4_gic_irq_eoi(struct irq_data *d) +{ + struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); + + gic_data->cpu_base = S5P_VA_GIC_CPU + + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); +} + void __init exynos4_init_irq(void) { int irq; - gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + gic_init(0, IRQ_SPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + gic_arch_extn.irq_eoi = exynos4_gic_irq_eoi; for (irq = 0; irq < MAX_COMBINER_NR; irq++) { - /* - * From SPI(0) to SPI(39) and SPI(51), SPI(53) are - * connected to the interrupt combiner. These irqs - * should be initialized to support cascade interrupt. - */ - if ((irq >= 40) && !(irq == 51) && !(irq == 53)) - continue; - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), COMBINER_IRQ(irq, 0)); combiner_cascade_irq(irq, IRQ_SPI(irq)); @@ -222,5 +247,8 @@ int __init exynos4_init(void) /* set idle function */ pm_idle = exynos4_idle; + /* set sw_reset function */ + s5p_reset_hook = exynos4_sw_reset; + return sysdev_register(&exynos4_sysdev); } diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c index 983069a..5a9f9c2e 100644 --- a/arch/arm/mach-exynos4/dev-audio.c +++ b/arch/arm/mach-exynos4/dev-audio.c @@ -21,6 +21,7 @@ #include <mach/map.h> #include <mach/dma.h> #include <mach/irqs.h> +#include <mach/regs-audss.h> static const char *rclksrc[] = { [0] = "busclk", @@ -55,6 +56,7 @@ static struct s3c_audio_pdata i2sv5_pdata = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, .src_clk = rclksrc, + .idma_addr = EXYNOS4_AUDSS_INT_MEM, }, }, }; diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-exynos4/dev-dwmci.c new file mode 100644 index 0000000..b025db4 --- /dev/null +++ b/arch/arm/mach-exynos4/dev-dwmci.c @@ -0,0 +1,82 @@ +/* + * linux/arch/arm/mach-exynos4/dev-dwmci.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Platform device for Synopsys DesignWare Mobile Storage IP + * + * 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/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/mmc/dw_mmc.h> + +#include <plat/devs.h> + +#include <mach/map.h> + +static int exynos4_dwmci_get_bus_wd(u32 slot_id) +{ + return 4; +} + +static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data) +{ + return 0; +} + +static struct resource exynos4_dwmci_resource[] = { + [0] = { + .start = EXYNOS4_PA_DWMCI, + .end = EXYNOS4_PA_DWMCI + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DWMCI, + .end = IRQ_DWMCI, + .flags = IORESOURCE_IRQ, + } +}; + +static struct dw_mci_board exynos4_dwci_pdata = { + .num_slots = 1, + .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION, + .bus_hz = 80 * 1000 * 1000, + .detect_delay_ms = 200, + .init = exynos4_dwmci_init, + .get_bus_wd = exynos4_dwmci_get_bus_wd, +}; + +static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32); + +struct platform_device exynos4_device_dwmci = { + .name = "dw_mmc", + .id = -1, + .num_resources = ARRAY_SIZE(exynos4_dwmci_resource), + .resource = exynos4_dwmci_resource, + .dev = { + .dma_mask = &exynos4_dwmci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &exynos4_dwci_pdata, + }, +}; + +void __init exynos4_dwmci_set_platdata(struct dw_mci_board *pd) +{ + struct dw_mci_board *npd; + + npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board), + &exynos4_device_dwmci); + + if (!npd->init) + npd->init = exynos4_dwmci_init; + if (!npd->get_bus_wd) + npd->get_bus_wd = exynos4_dwmci_get_bus_wd; +} diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c index 2b5909e..7490789 100644 --- a/arch/arm/mach-exynos4/hotplug.c +++ b/arch/arm/mach-exynos4/hotplug.c @@ -13,9 +13,12 @@ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/smp.h> +#include <linux/io.h> #include <asm/cacheflush.h> +#include <mach/regs-pmu.h> + extern volatile int pen_release; static inline void cpu_enter_lowpower(void) @@ -58,12 +61,12 @@ static inline void cpu_leave_lowpower(void) static inline void platform_do_lowpower(unsigned int cpu, int *spurious) { - /* - * there is no power-control hardware on this platform, so all - * we can do is put the core into WFI; this is safe as the calling - * code will have already disabled interrupts - */ for (;;) { + + /* make cpu1 to be turned off at next WFI command */ + if (cpu == 1) + __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION); + /* * here's the WFI */ diff --git a/arch/arm/mach-exynos4/include/mach/dwmci.h b/arch/arm/mach-exynos4/include/mach/dwmci.h new file mode 100644 index 0000000..7ce6574 --- /dev/null +++ b/arch/arm/mach-exynos4/include/mach/dwmci.h @@ -0,0 +1,20 @@ +/* linux/arch/arm/mach-exynos4/include/mach/dwmci.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Synopsys DesignWare Mobile Storage for EXYNOS4210 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_ARCH_DWMCI_H +#define __ASM_ARM_ARCH_DWMCI_H __FILE__ + +#include <linux/mmc/dw_mmc.h> + +extern void exynos4_dwmci_set_platdata(struct dw_mci_board *pd); + +#endif /* __ASM_ARM_ARCH_DWMCI_H */ diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index d8f38c2..d7a1e28 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S @@ -10,6 +10,7 @@ */ #include <mach/hardware.h> +#include <mach/map.h> #include <asm/hardware/gic.h> .macro disable_fiq @@ -18,6 +19,10 @@ .macro get_irqnr_preamble, base, tmp ldr \base, =gic_cpu_base_addr ldr \base, [\base] + mrc p15, 0, \tmp, c0, c0, 5 + and \tmp, \tmp, #3 + cmp \tmp, #1 + addeq \base, \base, #EXYNOS4_GIC_BANK_OFFSET .endm .macro arch_ret_to_user, tmp1, tmp2 @@ -75,10 +80,4 @@ /* As above, this assumes that irqstat and base are preserved.. */ .macro test_for_ltirq, irqnr, irqstat, base, tmp - bic \irqnr, \irqstat, #0x1c00 - mov \tmp, #0 - cmp \irqnr, #29 - moveq \tmp, #1 - streq \irqstat, [\base, #GIC_CPU_EOI] - cmp \tmp, #0 .endm diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h index 5d03730..f8952f8 100644 --- a/arch/arm/mach-exynos4/include/mach/irqs.h +++ b/arch/arm/mach-exynos4/include/mach/irqs.h @@ -19,40 +19,104 @@ #define IRQ_PPI(x) S5P_IRQ(x+16) -#define IRQ_LOCALTIMER IRQ_PPI(13) - /* SPI: Shared Peripheral Interrupt */ #define IRQ_SPI(x) S5P_IRQ(x+32) -#define IRQ_MCT1 IRQ_SPI(35) - -#define IRQ_EINT0 IRQ_SPI(40) -#define IRQ_EINT1 IRQ_SPI(41) -#define IRQ_EINT2 IRQ_SPI(42) -#define IRQ_EINT3 IRQ_SPI(43) -#define IRQ_USB_HSOTG IRQ_SPI(44) -#define IRQ_USB_HOST IRQ_SPI(45) -#define IRQ_MODEM_IF IRQ_SPI(46) -#define IRQ_ROTATOR IRQ_SPI(47) -#define IRQ_JPEG IRQ_SPI(48) -#define IRQ_2D IRQ_SPI(49) -#define IRQ_PCIE IRQ_SPI(50) -#define IRQ_MCT0 IRQ_SPI(51) -#define IRQ_MFC IRQ_SPI(52) -#define IRQ_AUDIO_SS IRQ_SPI(54) -#define IRQ_AC97 IRQ_SPI(55) -#define IRQ_SPDIF IRQ_SPI(56) -#define IRQ_KEYPAD IRQ_SPI(57) -#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(58) -#define IRQ_SLIMBUS IRQ_SPI(59) -#define IRQ_PMU IRQ_SPI(60) -#define IRQ_TSI IRQ_SPI(61) -#define IRQ_SATA IRQ_SPI(62) -#define IRQ_GPS IRQ_SPI(63) +#define IRQ_EINT0 IRQ_SPI(16) +#define IRQ_EINT1 IRQ_SPI(17) +#define IRQ_EINT2 IRQ_SPI(18) +#define IRQ_EINT3 IRQ_SPI(19) +#define IRQ_EINT4 IRQ_SPI(20) +#define IRQ_EINT5 IRQ_SPI(21) +#define IRQ_EINT6 IRQ_SPI(22) +#define IRQ_EINT7 IRQ_SPI(23) +#define IRQ_EINT8 IRQ_SPI(24) +#define IRQ_EINT9 IRQ_SPI(25) +#define IRQ_EINT10 IRQ_SPI(26) +#define IRQ_EINT11 IRQ_SPI(27) +#define IRQ_EINT12 IRQ_SPI(28) +#define IRQ_EINT13 IRQ_SPI(29) +#define IRQ_EINT14 IRQ_SPI(30) +#define IRQ_EINT15 IRQ_SPI(31) +#define IRQ_EINT16_31 IRQ_SPI(32) + +#define IRQ_PDMA0 IRQ_SPI(35) +#define IRQ_PDMA1 IRQ_SPI(36) +#define IRQ_TIMER0_VIC IRQ_SPI(37) +#define IRQ_TIMER1_VIC IRQ_SPI(38) +#define IRQ_TIMER2_VIC IRQ_SPI(39) +#define IRQ_TIMER3_VIC IRQ_SPI(40) +#define IRQ_TIMER4_VIC IRQ_SPI(41) +#define IRQ_MCT_L0 IRQ_SPI(42) +#define IRQ_WDT IRQ_SPI(43) +#define IRQ_RTC_ALARM IRQ_SPI(44) +#define IRQ_RTC_TIC IRQ_SPI(45) +#define IRQ_GPIO_XB IRQ_SPI(46) +#define IRQ_GPIO_XA IRQ_SPI(47) +#define IRQ_MCT_L1 IRQ_SPI(48) + +#define IRQ_UART0 IRQ_SPI(52) +#define IRQ_UART1 IRQ_SPI(53) +#define IRQ_UART2 IRQ_SPI(54) +#define IRQ_UART3 IRQ_SPI(55) +#define IRQ_UART4 IRQ_SPI(56) +#define IRQ_MCT_G0 IRQ_SPI(57) +#define IRQ_IIC IRQ_SPI(58) +#define IRQ_IIC1 IRQ_SPI(59) +#define IRQ_IIC2 IRQ_SPI(60) +#define IRQ_IIC3 IRQ_SPI(61) +#define IRQ_IIC4 IRQ_SPI(62) +#define IRQ_IIC5 IRQ_SPI(63) +#define IRQ_IIC6 IRQ_SPI(64) +#define IRQ_IIC7 IRQ_SPI(65) + +#define IRQ_USB_HOST IRQ_SPI(70) +#define IRQ_USB_HSOTG IRQ_SPI(71) +#define IRQ_MODEM_IF IRQ_SPI(72) +#define IRQ_HSMMC0 IRQ_SPI(73) +#define IRQ_HSMMC1 IRQ_SPI(74) +#define IRQ_HSMMC2 IRQ_SPI(75) +#define IRQ_HSMMC3 IRQ_SPI(76) +#define IRQ_DWMCI IRQ_SPI(77) + +#define IRQ_MIPI_CSIS0 IRQ_SPI(78) +#define IRQ_MIPI_CSIS1 IRQ_SPI(80) + +#define IRQ_ONENAND_AUDI IRQ_SPI(82) +#define IRQ_ROTATOR IRQ_SPI(83) +#define IRQ_FIMC0 IRQ_SPI(84) +#define IRQ_FIMC1 IRQ_SPI(85) +#define IRQ_FIMC2 IRQ_SPI(86) +#define IRQ_FIMC3 IRQ_SPI(87) +#define IRQ_JPEG IRQ_SPI(88) +#define IRQ_2D IRQ_SPI(89) +#define IRQ_PCIE IRQ_SPI(90) + +#define IRQ_MFC IRQ_SPI(94) + +#define IRQ_AUDIO_SS IRQ_SPI(96) +#define IRQ_I2S0 IRQ_SPI(97) +#define IRQ_I2S1 IRQ_SPI(98) +#define IRQ_I2S2 IRQ_SPI(99) +#define IRQ_AC97 IRQ_SPI(100) + +#define IRQ_SPDIF IRQ_SPI(104) +#define IRQ_ADC0 IRQ_SPI(105) +#define IRQ_PEN0 IRQ_SPI(106) +#define IRQ_ADC1 IRQ_SPI(107) +#define IRQ_PEN1 IRQ_SPI(108) +#define IRQ_KEYPAD IRQ_SPI(109) +#define IRQ_PMU IRQ_SPI(110) +#define IRQ_GPS IRQ_SPI(111) +#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) +#define IRQ_SLIMBUS IRQ_SPI(113) + +#define IRQ_TSI IRQ_SPI(115) +#define IRQ_SATA IRQ_SPI(116) #define MAX_IRQ_IN_COMBINER 8 -#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) +#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128)) #define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) #define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0) @@ -73,75 +137,14 @@ #define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6) #define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7) -#define IRQ_PDMA0 COMBINER_IRQ(21, 0) -#define IRQ_PDMA1 COMBINER_IRQ(21, 1) - -#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) -#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) -#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) -#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3) -#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4) - -#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0) -#define IRQ_RTC_TIC COMBINER_IRQ(23, 1) - -#define IRQ_GPIO_XB COMBINER_IRQ(24, 0) -#define IRQ_GPIO_XA COMBINER_IRQ(24, 1) - -#define IRQ_UART0 COMBINER_IRQ(26, 0) -#define IRQ_UART1 COMBINER_IRQ(26, 1) -#define IRQ_UART2 COMBINER_IRQ(26, 2) -#define IRQ_UART3 COMBINER_IRQ(26, 3) -#define IRQ_UART4 COMBINER_IRQ(26, 4) - -#define IRQ_IIC COMBINER_IRQ(27, 0) -#define IRQ_IIC1 COMBINER_IRQ(27, 1) -#define IRQ_IIC2 COMBINER_IRQ(27, 2) -#define IRQ_IIC3 COMBINER_IRQ(27, 3) -#define IRQ_IIC4 COMBINER_IRQ(27, 4) -#define IRQ_IIC5 COMBINER_IRQ(27, 5) -#define IRQ_IIC6 COMBINER_IRQ(27, 6) -#define IRQ_IIC7 COMBINER_IRQ(27, 7) - -#define IRQ_HSMMC0 COMBINER_IRQ(29, 0) -#define IRQ_HSMMC1 COMBINER_IRQ(29, 1) -#define IRQ_HSMMC2 COMBINER_IRQ(29, 2) -#define IRQ_HSMMC3 COMBINER_IRQ(29, 3) - -#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0) -#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1) - -#define IRQ_FIMC0 COMBINER_IRQ(32, 0) -#define IRQ_FIMC1 COMBINER_IRQ(32, 1) -#define IRQ_FIMC2 COMBINER_IRQ(33, 0) -#define IRQ_FIMC3 COMBINER_IRQ(33, 1) - -#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) - -#define IRQ_MCT_L1 COMBINER_IRQ(35, 3) - -#define IRQ_EINT4 COMBINER_IRQ(37, 0) -#define IRQ_EINT5 COMBINER_IRQ(37, 1) -#define IRQ_EINT6 COMBINER_IRQ(37, 2) -#define IRQ_EINT7 COMBINER_IRQ(37, 3) -#define IRQ_EINT8 COMBINER_IRQ(38, 0) - -#define IRQ_EINT9 COMBINER_IRQ(38, 1) -#define IRQ_EINT10 COMBINER_IRQ(38, 2) -#define IRQ_EINT11 COMBINER_IRQ(38, 3) -#define IRQ_EINT12 COMBINER_IRQ(38, 4) -#define IRQ_EINT13 COMBINER_IRQ(38, 5) -#define IRQ_EINT14 COMBINER_IRQ(38, 6) -#define IRQ_EINT15 COMBINER_IRQ(38, 7) - -#define IRQ_EINT16_31 COMBINER_IRQ(39, 0) - -#define IRQ_MCT_L0 COMBINER_IRQ(51, 0) +#define IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0) +#define IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) +#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) -#define IRQ_WDT COMBINER_IRQ(53, 0) -#define IRQ_MCT_G0 COMBINER_IRQ(53, 4) +#define MAX_COMBINER_NR 16 -#define MAX_COMBINER_NR 54 +#define IRQ_ADC IRQ_ADC0 +#define IRQ_TC IRQ_PEN0 #define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) @@ -155,6 +158,6 @@ #define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) /* Set the default NR_IRQS */ -#define NR_IRQS (IRQ_GPIO_END) +#define NR_IRQS (IRQ_GPIO_END + 64) #endif /* __ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 0009e77..d32296d 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -57,12 +57,14 @@ #define EXYNOS4_PA_DMC0 0x10400000 -#define EXYNOS4_PA_COMBINER 0x10448000 +#define EXYNOS4_PA_COMBINER 0x10440000 + +#define EXYNOS4_PA_GIC_CPU 0x10480000 +#define EXYNOS4_PA_GIC_DIST 0x10490000 +#define EXYNOS4_GIC_BANK_OFFSET 0x8000 #define EXYNOS4_PA_COREPERI 0x10500000 -#define EXYNOS4_PA_GIC_CPU 0x10500100 #define EXYNOS4_PA_TWD 0x10500600 -#define EXYNOS4_PA_GIC_DIST 0x10501000 #define EXYNOS4_PA_L2CC 0x10502000 #define EXYNOS4_PA_MDMA 0x10810000 @@ -93,7 +95,10 @@ #define EXYNOS4_PA_MIPI_CSIS0 0x11880000 #define EXYNOS4_PA_MIPI_CSIS1 0x11890000 +#define EXYNOS4_PA_FIMD0 0x11C00000 + #define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) +#define EXYNOS4_PA_DWMCI 0x12550000 #define EXYNOS4_PA_SATA 0x12560000 #define EXYNOS4_PA_SATAPHY 0x125D0000 @@ -103,11 +108,15 @@ #define EXYNOS4_PA_EHCI 0x12580000 #define EXYNOS4_PA_HSPHY 0x125B0000 +#define EXYNOS4_PA_MFC 0x13400000 #define EXYNOS4_PA_UART 0x13800000 #define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) +#define EXYNOS4_PA_ADC 0x13910000 +#define EXYNOS4_PA_ADC1 0x13911000 + #define EXYNOS4_PA_AC97 0x139A0000 #define EXYNOS4_PA_SPDIF 0x139B0000 @@ -130,6 +139,8 @@ #define S3C_PA_IIC5 EXYNOS4_PA_IIC(5) #define S3C_PA_IIC6 EXYNOS4_PA_IIC(6) #define S3C_PA_IIC7 EXYNOS4_PA_IIC(7) +#define SAMSUNG_PA_ADC EXYNOS4_PA_ADC +#define SAMSUNG_PA_ADC1 EXYNOS4_PA_ADC1 #define S3C_PA_RTC EXYNOS4_PA_RTC #define S3C_PA_WDT EXYNOS4_PA_WATCHDOG @@ -140,10 +151,12 @@ #define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 #define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0 #define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1 +#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 #define S5P_PA_ONENAND EXYNOS4_PA_ONENAND #define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA #define S5P_PA_SDRAM EXYNOS4_PA_SDRAM #define S5P_PA_SROMC EXYNOS4_PA_SROMC +#define S5P_PA_MFC EXYNOS4_PA_MFC #define S5P_PA_SYSCON EXYNOS4_PA_SYSCON #define S5P_PA_TIMER EXYNOS4_PA_TIMER #define S5P_PA_EHCI EXYNOS4_PA_EHCI diff --git a/arch/arm/mach-exynos4/include/mach/pm-core.h b/arch/arm/mach-exynos4/include/mach/pm-core.h index f26e46b..1df3b81 100644 --- a/arch/arm/mach-exynos4/include/mach/pm-core.h +++ b/arch/arm/mach-exynos4/include/mach/pm-core.h @@ -47,3 +47,13 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs, { /* nothing here yet */ } + +static inline void s3c_pm_restored_gpios(void) +{ + /* nothing here yet */ +} + +static inline void s3c_pm_saved_gpios(void) +{ + /* nothing here yet */ +} diff --git a/arch/arm/mach-exynos4/include/mach/pmu.h b/arch/arm/mach-exynos4/include/mach/pmu.h new file mode 100644 index 0000000..a952904 --- /dev/null +++ b/arch/arm/mach-exynos4/include/mach/pmu.h @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-exynos4/include/mach/pmu.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * EXYNOS4210 - PMU(Power Management Unit) support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_PMU_H +#define __ASM_ARCH_PMU_H __FILE__ + +enum sys_powerdown { + SYS_AFTR, + SYS_LPA, + SYS_SLEEP, + NUM_SYS_POWERDOWN, +}; + +extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); + +#endif /* __ASM_ARCH_PMU_H */ diff --git a/arch/arm/mach-exynos4/include/mach/regs-audss.h b/arch/arm/mach-exynos4/include/mach/regs-audss.h new file mode 100644 index 0000000..ca5a8b6 --- /dev/null +++ b/arch/arm/mach-exynos4/include/mach/regs-audss.h @@ -0,0 +1,18 @@ +/* arch/arm/mach-exynos4/include/mach/regs-audss.h + * + * Copyright (c) 2011 Samsung Electronics + * http://www.samsung.com + * + * Exynos4 Audio SubSystem clock register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __PLAT_REGS_AUDSS_H +#define __PLAT_REGS_AUDSS_H __FILE__ + +#define EXYNOS4_AUDSS_INT_MEM (0x03000000) + +#endif /* _PLAT_REGS_AUDSS_H */ diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h index 6e311c1..d493fdb 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h @@ -25,6 +25,9 @@ #define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600) #define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800) +#define S5P_EPLL_LOCK S5P_CLKREG(0x0C010) +#define S5P_VPLL_LOCK S5P_CLKREG(0x0C020) + #define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) #define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) #define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) @@ -33,7 +36,9 @@ #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) #define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220) +#define S5P_CLKSRC_TV S5P_CLKREG(0x0C224) #define S5P_CLKSRC_MFC S5P_CLKREG(0x0C228) +#define S5P_CLKSRC_G3D S5P_CLKREG(0x0C22C) #define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230) #define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234) #define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238) @@ -61,6 +66,7 @@ #define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C) #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) +#define S5P_CLKDIV2_RATIO S5P_CLKREG(0x0C580) #define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310) #define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320) @@ -120,6 +126,12 @@ #define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) #define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) +#define S5P_EPLLCON0_ENABLE_SHIFT (31) +#define S5P_EPLLCON0_LOCKED_SHIFT (29) + +#define S5P_VPLLCON0_ENABLE_SHIFT (31) +#define S5P_VPLLCON0_LOCKED_SHIFT (29) + #define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16) #define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT) diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h index a964337..cdf9b47 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h @@ -29,6 +29,8 @@ #define S5P_USE_STANDBY_WFE1 (1 << 25) #define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24)) +#define S5P_SWRESET S5P_PMUREG(0x0400) + #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) @@ -158,6 +160,7 @@ #define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0) #define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 +#define S5P_CORE_LOCAL_PWR_EN 0x3 #define S5P_INT_LOCAL_PWR_EN 0x7 #define S5P_CHECK_SLEEP 0x00000BAD diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos4/irq-eint.c index 9d87d2a..badb8c6 100644 --- a/arch/arm/mach-exynos4/irq-eint.c +++ b/arch/arm/mach-exynos4/irq-eint.c @@ -23,6 +23,8 @@ #include <mach/regs-gpio.h> +#include <asm/mach/irq.h> + static DEFINE_SPINLOCK(eint_lock); static unsigned int eint0_15_data[16]; @@ -184,8 +186,11 @@ static inline void exynos4_irq_demux_eint(unsigned int start) static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) { + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); exynos4_irq_demux_eint(IRQ_EINT(16)); exynos4_irq_demux_eint(IRQ_EINT(24)); + chained_irq_exit(chip, desc); } static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) @@ -193,6 +198,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) u32 *irq_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); chip->irq_mask(&desc->irq_data); if (chip->irq_ack) @@ -201,6 +207,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) generic_handle_irq(*irq_data); chip->irq_unmask(&desc->irq_data); + chained_irq_exit(chip, desc); } int __init exynos4_init_irq_eint(void) diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c deleted file mode 100644 index 6bf3d0a..0000000 --- a/arch/arm/mach-exynos4/localtimer.c +++ /dev/null @@ -1,26 +0,0 @@ -/* linux/arch/arm/mach-exynos4/localtimer.c - * - * Cloned from linux/arch/arm/mach-realview/localtimer.c - * - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/clockchips.h> - -#include <asm/irq.h> -#include <asm/localtimer.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - evt->irq = IRQ_LOCALTIMER; - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c index 642702b..43be71b 100644 --- a/arch/arm/mach-exynos4/mach-nuri.c +++ b/arch/arm/mach-exynos4/mach-nuri.c @@ -13,10 +13,15 @@ #include <linux/input.h> #include <linux/i2c.h> #include <linux/i2c/atmel_mxt_ts.h> +#include <linux/i2c-gpio.h> #include <linux/gpio_keys.h> #include <linux/gpio.h> +#include <linux/power/max8903_charger.h> +#include <linux/power/max17042_battery.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> +#include <linux/mfd/max8997.h> +#include <linux/mfd/max8997-private.h> #include <linux/mmc/host.h> #include <linux/fb.h> #include <linux/pwm_backlight.h> @@ -26,6 +31,7 @@ #include <asm/mach/arch.h> #include <asm/mach-types.h> +#include <plat/adc.h> #include <plat/regs-serial.h> #include <plat/exynos4.h> #include <plat/cpu.h> @@ -35,6 +41,8 @@ #include <plat/clock.h> #include <plat/gpio-cfg.h> #include <plat/iic.h> +#include <plat/mfc.h> +#include <plat/pd.h> #include <mach/map.h> @@ -54,6 +62,7 @@ enum fixed_regulator_id { FIXED_REG_ID_MMC = 0, + FIXED_REG_ID_MAX8903, }; static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = { @@ -344,10 +353,730 @@ static void __init nuri_tsp_init(void) s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); } +static struct regulator_consumer_supply __initdata max8997_ldo1_[] = { + REGULATOR_SUPPLY("vdd", "s5p-adc"), /* Used by CPU's ADC drv */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo3_[] = { + REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo4_[] = { + REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo5_[] = { + REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo7_[] = { + REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo8_[] = { + REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */ + REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo11_[] = { + REGULATOR_SUPPLY("vcc", "platform-lcd"), /* U804 LVDS */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo12_[] = { + REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo13_[] = { + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo14_[] = { + REGULATOR_SUPPLY("inmotor", "max8997-haptic"), +}; +static struct regulator_consumer_supply __initdata max8997_ldo15_[] = { + REGULATOR_SUPPLY("avdd", "3-004a"), /* Touch Screen */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo16_[] = { + REGULATOR_SUPPLY("d_sensor", "0-001f"), /* HDC803 */ +}; +static struct regulator_consumer_supply __initdata max8997_ldo18_[] = { + REGULATOR_SUPPLY("vdd", "3-004a"), /* Touch Screen */ +}; +static struct regulator_consumer_supply __initdata max8997_buck1_[] = { + REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */ +}; +static struct regulator_consumer_supply __initdata max8997_buck2_[] = { + REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */ +}; +static struct regulator_consumer_supply __initdata max8997_buck3_[] = { + REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */ +}; +static struct regulator_consumer_supply __initdata max8997_buck4_[] = { + REGULATOR_SUPPLY("core", "0-001f"), /* HDC803 */ +}; +static struct regulator_consumer_supply __initdata max8997_buck6_[] = { + REGULATOR_SUPPLY("dig_28", "0-001f"), /* pin "7" of HDC803 */ +}; +static struct regulator_consumer_supply __initdata max8997_esafeout1_[] = { + REGULATOR_SUPPLY("usb_vbus", NULL), /* CPU's USB OTG */ +}; +static struct regulator_consumer_supply __initdata max8997_esafeout2_[] = { + REGULATOR_SUPPLY("usb_vbus", "modemctl"), /* VBUS of Modem */ +}; + +static struct regulator_consumer_supply __initdata max8997_charger_[] = { + REGULATOR_SUPPLY("vinchg1", "charger-manager.0"), +}; +static struct regulator_consumer_supply __initdata max8997_chg_toff_[] = { + REGULATOR_SUPPLY("vinchg_stop", NULL), /* for jack interrupt handlers */ +}; + +static struct regulator_consumer_supply __initdata max8997_32khz_ap_[] = { + REGULATOR_SUPPLY("gps_clk", "bcm4751"), + REGULATOR_SUPPLY("bt_clk", "bcm4330-b1"), + REGULATOR_SUPPLY("wifi_clk", "bcm433-b1"), +}; + +static struct regulator_init_data __initdata max8997_ldo1_data = { + .constraints = { + .name = "VADC_3.3V_C210", + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo1_), + .consumer_supplies = max8997_ldo1_, +}; + +static struct regulator_init_data __initdata max8997_ldo2_data = { + .constraints = { + .name = "VALIVE_1.1V_C210", + .min_uV = 1100000, + .max_uV = 1100000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_ldo3_data = { + .constraints = { + .name = "VUSB_1.1V_C210", + .min_uV = 1100000, + .max_uV = 1100000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo3_), + .consumer_supplies = max8997_ldo3_, +}; + +static struct regulator_init_data __initdata max8997_ldo4_data = { + .constraints = { + .name = "VMIPI_1.8V", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo4_), + .consumer_supplies = max8997_ldo4_, +}; + +static struct regulator_init_data __initdata max8997_ldo5_data = { + .constraints = { + .name = "VHSIC_1.2V_C210", + .min_uV = 1200000, + .max_uV = 1200000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo5_), + .consumer_supplies = max8997_ldo5_, +}; + +static struct regulator_init_data __initdata max8997_ldo6_data = { + .constraints = { + .name = "VCC_1.8V_PDA", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_ldo7_data = { + .constraints = { + .name = "CAM_ISP_1.8V", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo7_), + .consumer_supplies = max8997_ldo7_, +}; + +static struct regulator_init_data __initdata max8997_ldo8_data = { + .constraints = { + .name = "VUSB/VDAC_3.3V_C210", + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo8_), + .consumer_supplies = max8997_ldo8_, +}; + +static struct regulator_init_data __initdata max8997_ldo9_data = { + .constraints = { + .name = "VCC_2.8V_PDA", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_ldo10_data = { + .constraints = { + .name = "VPLL_1.1V_C210", + .min_uV = 1100000, + .max_uV = 1100000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_ldo11_data = { + .constraints = { + .name = "LVDS_VDD3.3V", + .min_uV = 3300000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .boot_on = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo11_), + .consumer_supplies = max8997_ldo11_, +}; + +static struct regulator_init_data __initdata max8997_ldo12_data = { + .constraints = { + .name = "VT_CAM_1.8V", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo12_), + .consumer_supplies = max8997_ldo12_, +}; + +static struct regulator_init_data __initdata max8997_ldo13_data = { + .constraints = { + .name = "VTF_2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo13_), + .consumer_supplies = max8997_ldo13_, +}; + +static struct regulator_init_data __initdata max8997_ldo14_data = { + .constraints = { + .name = "VCC_3.0V_MOTOR", + .min_uV = 3000000, + .max_uV = 3000000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo14_), + .consumer_supplies = max8997_ldo14_, +}; + +static struct regulator_init_data __initdata max8997_ldo15_data = { + .constraints = { + .name = "VTOUCH_ADVV2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo15_), + .consumer_supplies = max8997_ldo15_, +}; + +static struct regulator_init_data __initdata max8997_ldo16_data = { + .constraints = { + .name = "CAM_SENSOR_IO_1.8V", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo16_), + .consumer_supplies = max8997_ldo16_, +}; + +static struct regulator_init_data __initdata max8997_ldo18_data = { + .constraints = { + .name = "VTOUCH_VDD2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_ldo18_), + .consumer_supplies = max8997_ldo18_, +}; + +static struct regulator_init_data __initdata max8997_ldo21_data = { + .constraints = { + .name = "VDDQ_M1M2_1.2V", + .min_uV = 1200000, + .max_uV = 1200000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_buck1_data = { + .constraints = { + .name = "VARM_1.2V_C210", + .min_uV = 900000, + .max_uV = 1350000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_buck1_), + .consumer_supplies = max8997_buck1_, +}; + +static struct regulator_init_data __initdata max8997_buck2_data = { + .constraints = { + .name = "VINT_1.1V_C210", + .min_uV = 900000, + .max_uV = 1100000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_buck2_), + .consumer_supplies = max8997_buck2_, +}; + +static struct regulator_init_data __initdata max8997_buck3_data = { + .constraints = { + .name = "VG3D_1.1V_C210", + .min_uV = 900000, + .max_uV = 1100000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_buck3_), + .consumer_supplies = max8997_buck3_, +}; + +static struct regulator_init_data __initdata max8997_buck4_data = { + .constraints = { + .name = "CAM_ISP_CORE_1.2V", + .min_uV = 1200000, + .max_uV = 1200000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_buck4_), + .consumer_supplies = max8997_buck4_, +}; + +static struct regulator_init_data __initdata max8997_buck5_data = { + .constraints = { + .name = "VMEM_1.2V_C210", + .min_uV = 1200000, + .max_uV = 1200000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_buck6_data = { + .constraints = { + .name = "CAM_AF_2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_buck6_), + .consumer_supplies = max8997_buck6_, +}; + +static struct regulator_init_data __initdata max8997_buck7_data = { + .constraints = { + .name = "VCC_SUB_2.0V", + .min_uV = 2000000, + .max_uV = 2000000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_32khz_ap_data = { + .constraints = { + .name = "32KHz AP", + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_32khz_ap_), + .consumer_supplies = max8997_32khz_ap_, +}; + +static struct regulator_init_data __initdata max8997_32khz_cp_data = { + .constraints = { + .name = "32KHz CP", + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_vichg_data = { + .constraints = { + .name = "VICHG", + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data __initdata max8997_esafeout1_data = { + .constraints = { + .name = "SAFEOUT1", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_esafeout1_), + .consumer_supplies = max8997_esafeout1_, +}; + +static struct regulator_init_data __initdata max8997_esafeout2_data = { + .constraints = { + .name = "SAFEOUT2", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_esafeout2_), + .consumer_supplies = max8997_esafeout2_, +}; + +static struct regulator_init_data __initdata max8997_charger_cv_data = { + .constraints = { + .name = "CHARGER_CV", + .min_uV = 4200000, + .max_uV = 4200000, + .apply_uV = 1, + }, +}; + +static struct regulator_init_data __initdata max8997_charger_data = { + .constraints = { + .name = "CHARGER", + .min_uA = 200000, + .max_uA = 950000, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | + REGULATOR_CHANGE_CURRENT, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_charger_), + .consumer_supplies = max8997_charger_, +}; + +static struct regulator_init_data __initdata max8997_charger_topoff_data = { + .constraints = { + .name = "CHARGER TOPOFF", + .min_uA = 50000, + .max_uA = 200000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT, + }, + .num_consumer_supplies = ARRAY_SIZE(max8997_chg_toff_), + .consumer_supplies = max8997_chg_toff_, +}; + +static struct max8997_regulator_data __initdata nuri_max8997_regulators[] = { + { MAX8997_LDO1, &max8997_ldo1_data }, + { MAX8997_LDO2, &max8997_ldo2_data }, + { MAX8997_LDO3, &max8997_ldo3_data }, + { MAX8997_LDO4, &max8997_ldo4_data }, + { MAX8997_LDO5, &max8997_ldo5_data }, + { MAX8997_LDO6, &max8997_ldo6_data }, + { MAX8997_LDO7, &max8997_ldo7_data }, + { MAX8997_LDO8, &max8997_ldo8_data }, + { MAX8997_LDO9, &max8997_ldo9_data }, + { MAX8997_LDO10, &max8997_ldo10_data }, + { MAX8997_LDO11, &max8997_ldo11_data }, + { MAX8997_LDO12, &max8997_ldo12_data }, + { MAX8997_LDO13, &max8997_ldo13_data }, + { MAX8997_LDO14, &max8997_ldo14_data }, + { MAX8997_LDO15, &max8997_ldo15_data }, + { MAX8997_LDO16, &max8997_ldo16_data }, + + { MAX8997_LDO18, &max8997_ldo18_data }, + { MAX8997_LDO21, &max8997_ldo21_data }, + + { MAX8997_BUCK1, &max8997_buck1_data }, + { MAX8997_BUCK2, &max8997_buck2_data }, + { MAX8997_BUCK3, &max8997_buck3_data }, + { MAX8997_BUCK4, &max8997_buck4_data }, + { MAX8997_BUCK5, &max8997_buck5_data }, + { MAX8997_BUCK6, &max8997_buck6_data }, + { MAX8997_BUCK7, &max8997_buck7_data }, + + { MAX8997_EN32KHZ_AP, &max8997_32khz_ap_data }, + { MAX8997_EN32KHZ_CP, &max8997_32khz_cp_data }, + + { MAX8997_ENVICHG, &max8997_vichg_data }, + { MAX8997_ESAFEOUT1, &max8997_esafeout1_data }, + { MAX8997_ESAFEOUT2, &max8997_esafeout2_data }, + { MAX8997_CHARGER_CV, &max8997_charger_cv_data }, + { MAX8997_CHARGER, &max8997_charger_data }, + { MAX8997_CHARGER_TOPOFF, &max8997_charger_topoff_data }, +}; + +static struct max8997_platform_data __initdata nuri_max8997_pdata = { + .wakeup = 1, + + .num_regulators = ARRAY_SIZE(nuri_max8997_regulators), + .regulators = nuri_max8997_regulators, + + .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) }, + .buck2_gpiodvs = true, + + .buck1_voltage[0] = 1350000, /* 1.35V */ + .buck1_voltage[1] = 1300000, /* 1.3V */ + .buck1_voltage[2] = 1250000, /* 1.25V */ + .buck1_voltage[3] = 1200000, /* 1.2V */ + .buck1_voltage[4] = 1150000, /* 1.15V */ + .buck1_voltage[5] = 1100000, /* 1.1V */ + .buck1_voltage[6] = 1000000, /* 1.0V */ + .buck1_voltage[7] = 950000, /* 0.95V */ + + .buck2_voltage[0] = 1100000, /* 1.1V */ + .buck2_voltage[1] = 1000000, /* 1.0V */ + .buck2_voltage[2] = 950000, /* 0.95V */ + .buck2_voltage[3] = 900000, /* 0.9V */ + .buck2_voltage[4] = 1100000, /* 1.1V */ + .buck2_voltage[5] = 1000000, /* 1.0V */ + .buck2_voltage[6] = 950000, /* 0.95V */ + .buck2_voltage[7] = 900000, /* 0.9V */ + + .buck5_voltage[0] = 1200000, /* 1.2V */ + .buck5_voltage[1] = 1200000, /* 1.2V */ + .buck5_voltage[2] = 1200000, /* 1.2V */ + .buck5_voltage[3] = 1200000, /* 1.2V */ + .buck5_voltage[4] = 1200000, /* 1.2V */ + .buck5_voltage[5] = 1200000, /* 1.2V */ + .buck5_voltage[6] = 1200000, /* 1.2V */ + .buck5_voltage[7] = 1200000, /* 1.2V */ +}; + /* GPIO I2C 5 (PMIC) */ +enum { I2C5_MAX8997 }; static struct i2c_board_info i2c5_devs[] __initdata = { - /* max8997, To be updated */ + [I2C5_MAX8997] = { + I2C_BOARD_INFO("max8997", 0xCC >> 1), + .platform_data = &nuri_max8997_pdata, + }, +}; + +static struct max17042_platform_data nuri_battery_platform_data = { +}; + +/* GPIO I2C 9 (Fuel Gauge) */ +static struct i2c_gpio_platform_data i2c9_gpio_data = { + .sda_pin = EXYNOS4_GPY4(0), /* XM0ADDR_8 */ + .scl_pin = EXYNOS4_GPY4(1), /* XM0ADDR_9 */ +}; +static struct platform_device i2c9_gpio = { + .name = "i2c-gpio", + .id = 9, + .dev = { + .platform_data = &i2c9_gpio_data, + }, }; +enum { I2C9_MAX17042}; +static struct i2c_board_info i2c9_devs[] __initdata = { + [I2C9_MAX17042] = { + I2C_BOARD_INFO("max17042", 0x36), + .platform_data = &nuri_battery_platform_data, + }, +}; + +/* MAX8903 Secondary Charger */ +static struct regulator_consumer_supply supplies_max8903[] = { + REGULATOR_SUPPLY("vinchg2", "charger-manager.0"), +}; + +static struct regulator_init_data max8903_charger_en_data = { + .constraints = { + .name = "VOUT_CHARGER", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(supplies_max8903), + .consumer_supplies = supplies_max8903, +}; + +static struct fixed_voltage_config max8903_charger_en = { + .supply_name = "VOUT_CHARGER", + .microvolts = 5000000, /* Assume 5VDC */ + .gpio = EXYNOS4_GPY4(5), /* TA_EN negaged */ + .enable_high = 0, /* Enable = Low */ + .enabled_at_boot = 1, + .init_data = &max8903_charger_en_data, +}; + +static struct platform_device max8903_fixed_reg_dev = { + .name = "reg-fixed-voltage", + .id = FIXED_REG_ID_MAX8903, + .dev = { .platform_data = &max8903_charger_en }, +}; + +static struct max8903_pdata nuri_max8903 = { + /* + * cen: don't control with the driver, let it be + * controlled by regulator above + */ + .dok = EXYNOS4_GPX1(4), /* TA_nCONNECTED */ + /* uok, usus: not connected */ + .chg = EXYNOS4_GPE2(0), /* TA_nCHG */ + /* flt: vcc_1.8V_pda */ + .dcm = EXYNOS4_GPL0(1), /* CURR_ADJ */ + + .dc_valid = true, + .usb_valid = false, /* USB is not wired to MAX8903 */ +}; + +static struct platform_device nuri_max8903_device = { + .name = "max8903-charger", + .dev = { + .platform_data = &nuri_max8903, + }, +}; + +static struct device *nuri_cm_devices[] = { + &s3c_device_i2c5.dev, + &s3c_device_adc.dev, + NULL, /* Reserved for UART */ + NULL, +}; + +static void __init nuri_power_init(void) +{ + int gpio; + int irq_base = IRQ_GPIO_END + 1; + int ta_en = 0; + + nuri_max8997_pdata.irq_base = irq_base; + irq_base += MAX8997_IRQ_NR; + + gpio = EXYNOS4_GPX0(7); + gpio_request(gpio, "AP_PMIC_IRQ"); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + + gpio = EXYNOS4_GPX2(3); + gpio_request(gpio, "FUEL_ALERT"); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + + gpio = nuri_max8903.dok; + gpio_request(gpio, "TA_nCONNECTED"); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + ta_en = gpio_get_value(gpio) ? 0 : 1; + + gpio = nuri_max8903.chg; + gpio_request(gpio, "TA_nCHG"); + gpio_direction_input(gpio); + + gpio = nuri_max8903.dcm; + gpio_request(gpio, "CURR_ADJ"); + gpio_direction_output(gpio, ta_en); +} /* USB EHCI */ static struct s5p_ehci_platdata nuri_ehci_pdata; @@ -361,6 +1090,7 @@ static void __init nuri_ehci_init(void) static struct platform_device *nuri_devices[] __initdata = { /* Samsung Platform Devices */ + &s3c_device_i2c5, /* PMIC should initialize first */ &emmc_fixed_voltage, &s3c_device_hsmmc0, &s3c_device_hsmmc2, @@ -369,11 +1099,20 @@ static struct platform_device *nuri_devices[] __initdata = { &s3c_device_timer[0], &s5p_device_ehci, &s3c_device_i2c3, + &i2c9_gpio, + &s3c_device_adc, + &s3c_device_rtc, + &s5p_device_mfc, + &s5p_device_mfc_l, + &s5p_device_mfc_r, + &exynos4_device_pd[PD_MFC], /* NURI Devices */ &nuri_gpio_keys, &nuri_lcd_device, &nuri_backlight_device, + &max8903_fixed_reg_dev, + &nuri_max8903_device, }; static void __init nuri_map_io(void) @@ -383,21 +1122,32 @@ static void __init nuri_map_io(void) s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); } +static void __init nuri_reserve(void) +{ + s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); +} + static void __init nuri_machine_init(void) { nuri_sdhci_init(); nuri_tsp_init(); + nuri_power_init(); i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); s3c_i2c3_set_platdata(&i2c3_data); i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs)); + s3c_i2c5_set_platdata(NULL); + i2c5_devs[I2C5_MAX8997].irq = gpio_to_irq(EXYNOS4_GPX0(7)); i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); + i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3)); + i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs)); nuri_ehci_init(); clk_xusbxti.rate = 24000000; /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); + s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev; } MACHINE_START(NURI, "NURI") @@ -407,4 +1157,5 @@ MACHINE_START(NURI, "NURI") .map_io = nuri_map_io, .init_machine = nuri_machine_init, .timer = &exynos4_timer, + .reserve = &nuri_reserve, MACHINE_END diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c index f606ea75..a7c65e0 100644 --- a/arch/arm/mach-exynos4/mach-smdkc210.c +++ b/arch/arm/mach-exynos4/mach-smdkc210.c @@ -9,7 +9,9 @@ */ #include <linux/serial_core.h> +#include <linux/delay.h> #include <linux/gpio.h> +#include <linux/lcd.h> #include <linux/mmc/host.h> #include <linux/platform_device.h> #include <linux/smsc911x.h> @@ -20,11 +22,15 @@ #include <asm/mach/arch.h> #include <asm/mach-types.h> +#include <video/platform_lcd.h> + #include <plat/regs-serial.h> #include <plat/regs-srom.h> +#include <plat/regs-fb-v4.h> #include <plat/exynos4.h> #include <plat/cpu.h> #include <plat/devs.h> +#include <plat/fb.h> #include <plat/sdhci.h> #include <plat/iic.h> #include <plat/pd.h> @@ -114,6 +120,67 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = { .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; +static void lcd_lte480wv_set_power(struct plat_lcd_data *pd, + unsigned int power) +{ + if (power) { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + /* fire nRESET on power up */ + gpio_request(EXYNOS4_GPX0(6), "GPX0"); + + gpio_direction_output(EXYNOS4_GPX0(6), 1); + mdelay(100); + + gpio_set_value(EXYNOS4_GPX0(6), 0); + mdelay(10); + + gpio_set_value(EXYNOS4_GPX0(6), 1); + mdelay(10); + + gpio_free(EXYNOS4_GPX0(6)); + } else { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + } +} + +static struct plat_lcd_data smdkc210_lcd_lte480wv_data = { + .set_power = lcd_lte480wv_set_power, +}; + +static struct platform_device smdkc210_lcd_lte480wv = { + .name = "platform-lcd", + .dev.parent = &s5p_device_fimd0.dev, + .dev.platform_data = &smdkc210_lcd_lte480wv_data, +}; + +static struct s3c_fb_pd_win smdkc210_fb_win0 = { + .win_mode = { + .left_margin = 13, + .right_margin = 8, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, + }, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = { + .win[0] = &smdkc210_fb_win0, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, + .setup_gpio = exynos4_fimd0_gpio_setup_24bpp, +}; + static struct resource smdkc210_smsc911x_resources[] = { [0] = { .start = EXYNOS4_PA_SROM_BANK(1), @@ -168,6 +235,8 @@ static struct platform_device *smdkc210_devices[] __initdata = { &exynos4_device_pd[PD_GPS], &exynos4_device_sysmmu, &samsung_asoc_dma, + &s5p_device_fimd0, + &smdkc210_lcd_lte480wv, &smdkc210_smsc911x, }; @@ -225,6 +294,7 @@ static void __init smdkc210_machine_init(void) s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata); samsung_bl_set(&smdkc210_bl_gpio_info, &smdkc210_bl_data); + s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata); platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices)); } diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index df11078..ea41495 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -184,9 +184,12 @@ static struct platform_device *smdkv310_devices[] __initdata = { &exynos4_device_pd[PD_CAM], &exynos4_device_pd[PD_TV], &exynos4_device_pd[PD_GPS], + &exynos4_device_spdif, &exynos4_device_sysmmu, &samsung_asoc_dma, + &samsung_asoc_idma, &smdkv310_smsc911x, + &exynos4_device_ahci, }; static void __init smdkv310_smsc911x_init(void) diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c index 97d329f..b3b5d89 100644 --- a/arch/arm/mach-exynos4/mach-universal_c210.c +++ b/arch/arm/mach-exynos4/mach-universal_c210.c @@ -18,6 +18,9 @@ #include <linux/regulator/fixed.h> #include <linux/regulator/max8952.h> #include <linux/mmc/host.h> +#include <linux/i2c-gpio.h> +#include <linux/i2c/mcs.h> +#include <linux/i2c/atmel_mxt_ts.h> #include <asm/mach/arch.h> #include <asm/mach-types.h> @@ -27,7 +30,10 @@ #include <plat/cpu.h> #include <plat/devs.h> #include <plat/iic.h> +#include <plat/gpio-cfg.h> +#include <plat/mfc.h> #include <plat/sdhci.h> +#include <plat/pd.h> #include <mach/map.h> @@ -73,7 +79,7 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = { }; static struct regulator_consumer_supply max8952_consumer = - REGULATOR_SUPPLY("vddarm", NULL); + REGULATOR_SUPPLY("vdd_arm", NULL); static struct max8952_platform_data universal_max8952_pdata __initdata = { .gpio_vid0 = EXYNOS4_GPX0(3), @@ -99,7 +105,7 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = { }; static struct regulator_consumer_supply lp3974_buck1_consumer = - REGULATOR_SUPPLY("vddint", NULL); + REGULATOR_SUPPLY("vdd_int", NULL); static struct regulator_consumer_supply lp3974_buck2_consumer = REGULATOR_SUPPLY("vddg3d", NULL); @@ -477,6 +483,96 @@ static struct i2c_board_info i2c5_devs[] __initdata = { }, }; +/* I2C3 (TSP) */ +static struct mxt_platform_data qt602240_platform_data = { + .x_line = 19, + .y_line = 11, + .x_size = 800, + .y_size = 480, + .blen = 0x11, + .threshold = 0x28, + .voltage = 2800000, /* 2.8V */ + .orient = MXT_DIAGONAL, +}; + +static struct i2c_board_info i2c3_devs[] __initdata = { + { + I2C_BOARD_INFO("qt602240_ts", 0x4a), + .platform_data = &qt602240_platform_data, + }, +}; + +static void __init universal_tsp_init(void) +{ + int gpio; + + /* TSP_LDO_ON: XMDMADDR_11 */ + gpio = EXYNOS4_GPE2(3); + gpio_request(gpio, "TSP_LDO_ON"); + gpio_direction_output(gpio, 1); + gpio_export(gpio, 0); + + /* TSP_INT: XMDMADDR_7 */ + gpio = EXYNOS4_GPE1(7); + gpio_request(gpio, "TSP_INT"); + + s5p_register_gpio_interrupt(gpio); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); + i2c3_devs[0].irq = gpio_to_irq(gpio); +} + + +/* GPIO I2C 12 (3 Touchkey) */ +static uint32_t touchkey_keymap[] = { + /* MCS_KEY_MAP(value, keycode) */ + MCS_KEY_MAP(0, KEY_MENU), /* KEY_SEND */ + MCS_KEY_MAP(1, KEY_BACK), /* KEY_END */ +}; + +static struct mcs_platform_data touchkey_data = { + .keymap = touchkey_keymap, + .keymap_size = ARRAY_SIZE(touchkey_keymap), + .key_maxval = 2, +}; + +/* GPIO I2C 3_TOUCH 2.8V */ +#define I2C_GPIO_BUS_12 12 +static struct i2c_gpio_platform_data i2c_gpio12_data = { + .sda_pin = EXYNOS4_GPE4(0), /* XMDMDATA_8 */ + .scl_pin = EXYNOS4_GPE4(1), /* XMDMDATA_9 */ +}; + +static struct platform_device i2c_gpio12 = { + .name = "i2c-gpio", + .id = I2C_GPIO_BUS_12, + .dev = { + .platform_data = &i2c_gpio12_data, + }, +}; + +static struct i2c_board_info i2c_gpio12_devs[] __initdata = { + { + I2C_BOARD_INFO("mcs5080_touchkey", 0x20), + .platform_data = &touchkey_data, + }, +}; + +static void __init universal_touchkey_init(void) +{ + int gpio; + + gpio = EXYNOS4_GPE3(7); /* XMDMDATA_7 */ + gpio_request(gpio, "3_TOUCH_INT"); + s5p_register_gpio_interrupt(gpio); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); + i2c_gpio12_devs[0].irq = gpio_to_irq(gpio); + + gpio = EXYNOS4_GPE3(3); /* XMDMDATA_3 */ + gpio_request(gpio, "3_TOUCH_EN"); + gpio_direction_output(gpio, 1); +} + /* GPIO KEYS */ static struct gpio_keys_button universal_gpio_keys_tables[] = { { @@ -608,15 +704,25 @@ static struct i2c_board_info i2c1_devs[] __initdata = { static struct platform_device *universal_devices[] __initdata = { /* Samsung Platform Devices */ + &s5p_device_fimc0, + &s5p_device_fimc1, + &s5p_device_fimc2, + &s5p_device_fimc3, &mmc0_fixed_voltage, &s3c_device_hsmmc0, &s3c_device_hsmmc2, &s3c_device_hsmmc3, + &s3c_device_i2c3, &s3c_device_i2c5, /* Universal Devices */ + &i2c_gpio12, &universal_gpio_keys, &s5p_device_onenand, + &s5p_device_mfc, + &s5p_device_mfc_l, + &s5p_device_mfc_r, + &exynos4_device_pd[PD_MFC], }; static void __init universal_map_io(void) @@ -626,6 +732,11 @@ static void __init universal_map_io(void) s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); } +static void __init universal_reserve(void) +{ + s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); +} + static void __init universal_machine_init(void) { universal_sdhci_init(); @@ -633,11 +744,20 @@ static void __init universal_machine_init(void) i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); + universal_tsp_init(); + s3c_i2c3_set_platdata(NULL); + i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs)); + s3c_i2c5_set_platdata(NULL); i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); + universal_touchkey_init(); + i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs, + ARRAY_SIZE(i2c_gpio12_devs)); + /* Last */ platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices)); + s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev; } MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") @@ -647,4 +767,5 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .init_machine = universal_machine_init, .timer = &exynos4_timer, + .reserve = &universal_reserve, MACHINE_END diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index 14ac10b..1ae059b 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -383,8 +383,8 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); } else { mct_tick1_event_irq.dev_id = &mct_tick[cpu]; - irq_set_affinity(IRQ_MCT1, cpumask_of(1)); setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); + irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); } } diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index b68d5bd..7c2282c 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c @@ -28,9 +28,12 @@ #include <mach/hardware.h> #include <mach/regs-clock.h> +#include <mach/regs-pmu.h> extern void exynos4_secondary_startup(void); +#define CPU1_BOOT_REG S5P_VA_SYSRAM + /* * control for which core is the next to come out of the secondary * boot "holding pen" @@ -58,6 +61,31 @@ static void __iomem *scu_base_addr(void) static DEFINE_SPINLOCK(boot_lock); +static void __cpuinit exynos4_gic_secondary_init(void) +{ + void __iomem *dist_base = S5P_VA_GIC_DIST + + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + void __iomem *cpu_base = S5P_VA_GIC_CPU + + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + int i; + + /* + * Deal with the banked PPI and SGI interrupts - disable all + * PPI interrupts, ensure all SGI interrupts are enabled. + */ + __raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); + __raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); + + /* + * Set priority on PPI and SGI interrupts + */ + for (i = 0; i < 32; i += 4) + __raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); + + __raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK); + __raw_writel(1, cpu_base + GIC_CPU_CTRL); +} + void __cpuinit platform_secondary_init(unsigned int cpu) { /* @@ -65,7 +93,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * core (e.g. timer irq), then they will not have been enabled * for us: do so */ - gic_secondary_init(0); + exynos4_gic_secondary_init(); /* * let the primary processor know we're out of the @@ -100,16 +128,41 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu); + if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) { + __raw_writel(S5P_CORE_LOCAL_PWR_EN, + S5P_ARM_CORE1_CONFIGURATION); + + timeout = 10; + + /* wait max 10 ms until cpu1 is on */ + while ((__raw_readl(S5P_ARM_CORE1_STATUS) + & S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) { + if (timeout-- == 0) + break; + + mdelay(1); + } + + if (timeout == 0) { + printk(KERN_ERR "cpu1 power enable failed"); + spin_unlock(&boot_lock); + return -ETIMEDOUT; + } + } /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, * and branch to the address found there. */ - gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); + + __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), + CPU1_BOOT_REG); + gic_raise_softirq(cpumask_of(cpu), 1); + if (pen_release == -1) break; diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c index 533c28f..bc6ca94 100644 --- a/arch/arm/mach-exynos4/pm.c +++ b/arch/arm/mach-exynos4/pm.c @@ -18,92 +18,23 @@ #include <linux/suspend.h> #include <linux/syscore_ops.h> #include <linux/io.h> +#include <linux/err.h> +#include <linux/clk.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> #include <plat/cpu.h> #include <plat/pm.h> +#include <plat/pll.h> +#include <plat/regs-srom.h> #include <mach/regs-irq.h> #include <mach/regs-gpio.h> #include <mach/regs-clock.h> #include <mach/regs-pmu.h> #include <mach/pm-core.h> - -static struct sleep_save exynos4_sleep[] = { - { .reg = S5P_ARM_CORE0_LOWPWR , .val = 0x2, }, - { .reg = S5P_DIS_IRQ_CORE0 , .val = 0x0, }, - { .reg = S5P_DIS_IRQ_CENTRAL0 , .val = 0x0, }, - { .reg = S5P_ARM_CORE1_LOWPWR , .val = 0x2, }, - { .reg = S5P_DIS_IRQ_CORE1 , .val = 0x0, }, - { .reg = S5P_DIS_IRQ_CENTRAL1 , .val = 0x0, }, - { .reg = S5P_ARM_COMMON_LOWPWR , .val = 0x2, }, - { .reg = S5P_L2_0_LOWPWR , .val = 0x3, }, - { .reg = S5P_L2_1_LOWPWR , .val = 0x3, }, - { .reg = S5P_CMU_ACLKSTOP_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_SCLKSTOP_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_LOWPWR , .val = 0x0, }, - { .reg = S5P_APLL_SYSCLK_LOWPWR , .val = 0x0, }, - { .reg = S5P_MPLL_SYSCLK_LOWPWR , .val = 0x0, }, - { .reg = S5P_VPLL_SYSCLK_LOWPWR , .val = 0x0, }, - { .reg = S5P_EPLL_SYSCLK_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_GPSALIVE_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_CAM_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_TV_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_MFC_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_G3D_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_LCD0_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_LCD1_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_MAUDIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_CLKSTOP_GPS_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_CAM_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_TV_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_MFC_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_G3D_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_LCD0_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_LCD1_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_MAUDIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_CMU_RESET_GPS_LOWPWR , .val = 0x0, }, - { .reg = S5P_TOP_BUS_LOWPWR , .val = 0x0, }, - { .reg = S5P_TOP_RETENTION_LOWPWR , .val = 0x1, }, - { .reg = S5P_TOP_PWR_LOWPWR , .val = 0x3, }, - { .reg = S5P_LOGIC_RESET_LOWPWR , .val = 0x0, }, - { .reg = S5P_ONENAND_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_MODIMIF_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_G2D_ACP_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_USBOTG_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_HSMMC_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_CSSYS_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_SECSS_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_PCIE_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_SATA_MEM_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_DRAM_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_MAUDIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_GPIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_UART_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_MMCA_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_MMCB_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_EBIA_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_EBIB_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_ISOLATION_LOWPWR , .val = 0x0, }, - { .reg = S5P_PAD_RETENTION_ALV_SEL_LOWPWR , .val = 0x0, }, - { .reg = S5P_XUSBXTI_LOWPWR , .val = 0x0, }, - { .reg = S5P_XXTI_LOWPWR , .val = 0x0, }, - { .reg = S5P_EXT_REGULATOR_LOWPWR , .val = 0x0, }, - { .reg = S5P_GPIO_MODE_LOWPWR , .val = 0x0, }, - { .reg = S5P_GPIO_MODE_MAUDIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_CAM_LOWPWR , .val = 0x0, }, - { .reg = S5P_TV_LOWPWR , .val = 0x0, }, - { .reg = S5P_MFC_LOWPWR , .val = 0x0, }, - { .reg = S5P_G3D_LOWPWR , .val = 0x0, }, - { .reg = S5P_LCD0_LOWPWR , .val = 0x0, }, - { .reg = S5P_LCD1_LOWPWR , .val = 0x0, }, - { .reg = S5P_MAUDIO_LOWPWR , .val = 0x0, }, - { .reg = S5P_GPS_LOWPWR , .val = 0x0, }, - { .reg = S5P_GPS_ALIVE_LOWPWR , .val = 0x0, }, -}; +#include <mach/pmu.h> static struct sleep_save exynos4_set_clksrc[] = { { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, }, @@ -118,20 +49,28 @@ static struct sleep_save exynos4_set_clksrc[] = { { .reg = S5P_CLKSRC_MASK_DMC , .val = 0x00010000, }, }; +static struct sleep_save exynos4_epll_save[] = { + SAVE_ITEM(S5P_EPLL_CON0), + SAVE_ITEM(S5P_EPLL_CON1), +}; + +static struct sleep_save exynos4_vpll_save[] = { + SAVE_ITEM(S5P_VPLL_CON0), + SAVE_ITEM(S5P_VPLL_CON1), +}; + static struct sleep_save exynos4_core_save[] = { /* CMU side */ SAVE_ITEM(S5P_CLKDIV_LEFTBUS), SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS), SAVE_ITEM(S5P_CLKDIV_RIGHTBUS), SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS), - SAVE_ITEM(S5P_EPLL_CON0), - SAVE_ITEM(S5P_EPLL_CON1), - SAVE_ITEM(S5P_VPLL_CON0), - SAVE_ITEM(S5P_VPLL_CON1), SAVE_ITEM(S5P_CLKSRC_TOP0), SAVE_ITEM(S5P_CLKSRC_TOP1), SAVE_ITEM(S5P_CLKSRC_CAM), + SAVE_ITEM(S5P_CLKSRC_TV), SAVE_ITEM(S5P_CLKSRC_MFC), + SAVE_ITEM(S5P_CLKSRC_G3D), SAVE_ITEM(S5P_CLKSRC_IMAGE), SAVE_ITEM(S5P_CLKSRC_LCD0), SAVE_ITEM(S5P_CLKSRC_LCD1), @@ -158,6 +97,7 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_CLKDIV_PERIL4), SAVE_ITEM(S5P_CLKDIV_PERIL5), SAVE_ITEM(S5P_CLKDIV_TOP), + SAVE_ITEM(S5P_CLKSRC_MASK_TOP), SAVE_ITEM(S5P_CLKSRC_MASK_CAM), SAVE_ITEM(S5P_CLKSRC_MASK_TV), SAVE_ITEM(S5P_CLKSRC_MASK_LCD0), @@ -166,6 +106,7 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_CLKSRC_MASK_FSYS), SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0), SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1), + SAVE_ITEM(S5P_CLKDIV2_RATIO), SAVE_ITEM(S5P_CLKGATE_SCLKCAM), SAVE_ITEM(S5P_CLKGATE_IP_CAM), SAVE_ITEM(S5P_CLKGATE_IP_TV), @@ -186,8 +127,10 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_CLKGATE_IP_DMC), SAVE_ITEM(S5P_CLKSRC_CPU), SAVE_ITEM(S5P_CLKDIV_CPU), + SAVE_ITEM(S5P_CLKDIV_CPU + 0x4), SAVE_ITEM(S5P_CLKGATE_SCLKCPU), SAVE_ITEM(S5P_CLKGATE_IP_CPU), + /* GIC side */ SAVE_ITEM(S5P_VA_GIC_CPU + 0x000), SAVE_ITEM(S5P_VA_GIC_CPU + 0x004), @@ -270,6 +213,13 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070), SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080), SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090), + + /* SROM side */ + SAVE_ITEM(S5P_SROM_BW), + SAVE_ITEM(S5P_SROM_BC0), + SAVE_ITEM(S5P_SROM_BC1), + SAVE_ITEM(S5P_SROM_BC2), + SAVE_ITEM(S5P_SROM_BC3), }; static struct sleep_save exynos4_l2cc_save[] = { @@ -280,37 +230,11 @@ static struct sleep_save exynos4_l2cc_save[] = { SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), }; +/* For Cortex-A9 Diagnostic and Power control register */ +static unsigned int save_arm_register[2]; + static int exynos4_cpu_suspend(unsigned long arg) { - unsigned long tmp; - unsigned long mask = 0xFFFFFFFF; - - /* Setting Central Sequence Register for power down mode */ - - tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); - tmp &= ~(S5P_CENTRAL_LOWPWR_CFG); - __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); - - /* Setting Central Sequence option Register */ - - tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION); - tmp &= ~(S5P_USE_MASK); - tmp |= S5P_USE_STANDBY_WFI0; - __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); - - /* Clear all interrupt pending to avoid early wakeup */ - - __raw_writel(mask, (S5P_VA_GIC_DIST + 0x280)); - __raw_writel(mask, (S5P_VA_GIC_DIST + 0x284)); - __raw_writel(mask, (S5P_VA_GIC_DIST + 0x288)); - - /* Disable all interrupt */ - - __raw_writel(0x0, (S5P_VA_GIC_CPU + 0x000)); - __raw_writel(0x0, (S5P_VA_GIC_DIST + 0x000)); - __raw_writel(mask, (S5P_VA_GIC_DIST + 0x184)); - __raw_writel(mask, (S5P_VA_GIC_DIST + 0x188)); - outer_flush_all(); /* issue the standby signal into the pm unit. */ @@ -326,12 +250,14 @@ static void exynos4_pm_prepare(void) s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); + s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); + s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); tmp = __raw_readl(S5P_INFORM1); /* Set value of power down register for sleep mode */ - s3c_pm_do_restore_core(exynos4_sleep, ARRAY_SIZE(exynos4_sleep)); + exynos4_sys_powerdown_conf(SYS_SLEEP); __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); /* ensure at least INFORM0 has the resume address */ @@ -373,12 +299,80 @@ void exynos4_scu_enable(void __iomem *scu_base) flush_cache_all(); } +static unsigned long pll_base_rate; + +static void exynos4_restore_pll(void) +{ + unsigned long pll_con, locktime, lockcnt; + unsigned long pll_in_rate; + unsigned int p_div, epll_wait = 0, vpll_wait = 0; + + if (pll_base_rate == 0) + return; + + pll_in_rate = pll_base_rate; + + /* EPLL */ + pll_con = exynos4_epll_save[0].val; + + if (pll_con & (1 << 31)) { + pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT); + p_div = (pll_con >> PLL46XX_PDIV_SHIFT); + + pll_in_rate /= 1000000; + + locktime = (3000 / pll_in_rate) * p_div; + lockcnt = locktime * 10000 / (10000 / pll_in_rate); + + __raw_writel(lockcnt, S5P_EPLL_LOCK); + + s3c_pm_do_restore_core(exynos4_epll_save, + ARRAY_SIZE(exynos4_epll_save)); + epll_wait = 1; + } + + pll_in_rate = pll_base_rate; + + /* VPLL */ + pll_con = exynos4_vpll_save[0].val; + + if (pll_con & (1 << 31)) { + pll_in_rate /= 1000000; + /* 750us */ + locktime = 750; + lockcnt = locktime * 10000 / (10000 / pll_in_rate); + + __raw_writel(lockcnt, S5P_VPLL_LOCK); + + s3c_pm_do_restore_core(exynos4_vpll_save, + ARRAY_SIZE(exynos4_vpll_save)); + vpll_wait = 1; + } + + /* Wait PLL locking */ + + do { + if (epll_wait) { + pll_con = __raw_readl(S5P_EPLL_CON0); + if (pll_con & (1 << S5P_EPLLCON0_LOCKED_SHIFT)) + epll_wait = 0; + } + + if (vpll_wait) { + pll_con = __raw_readl(S5P_VPLL_CON0); + if (pll_con & (1 << S5P_VPLLCON0_LOCKED_SHIFT)) + vpll_wait = 0; + } + } while (epll_wait || vpll_wait); +} + static struct sysdev_driver exynos4_pm_driver = { .add = exynos4_pm_add, }; static __init int exynos4_pm_drvinit(void) { + struct clk *pll_base; unsigned int tmp; s3c_pm_init(); @@ -389,12 +383,69 @@ static __init int exynos4_pm_drvinit(void) tmp |= ((0xFF << 8) | (0x1F << 1)); __raw_writel(tmp, S5P_WAKEUP_MASK); + pll_base = clk_get(NULL, "xtal"); + + if (!IS_ERR(pll_base)) { + pll_base_rate = clk_get_rate(pll_base); + clk_put(pll_base); + } + return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver); } arch_initcall(exynos4_pm_drvinit); +static int exynos4_pm_suspend(void) +{ + unsigned long tmp; + + /* Setting Central Sequence Register for power down mode */ + + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + tmp &= ~S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + + /* Save Power control register */ + asm ("mrc p15, 0, %0, c15, c0, 0" + : "=r" (tmp) : : "cc"); + save_arm_register[0] = tmp; + + /* Save Diagnostic register */ + asm ("mrc p15, 0, %0, c15, c0, 1" + : "=r" (tmp) : : "cc"); + save_arm_register[1] = tmp; + + return 0; +} + static void exynos4_pm_resume(void) { + unsigned long tmp; + + /* + * If PMU failed while entering sleep mode, WFI will be + * ignored by PMU and then exiting cpu_do_idle(). + * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically + * in this situation. + */ + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { + tmp |= S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + /* No need to perform below restore code */ + goto early_wakeup; + } + /* Restore Power control register */ + tmp = save_arm_register[0]; + asm volatile ("mcr p15, 0, %0, c15, c0, 0" + : : "r" (tmp) + : "cc"); + + /* Restore Diagnostic register */ + tmp = save_arm_register[1]; + asm volatile ("mcr p15, 0, %0, c15, c0, 1" + : : "r" (tmp) + : "cc"); + /* For release retention */ __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); @@ -407,6 +458,8 @@ static void exynos4_pm_resume(void) s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); + exynos4_restore_pll(); + exynos4_scu_enable(S5P_VA_SCU); #ifdef CONFIG_CACHE_L2X0 @@ -415,9 +468,13 @@ static void exynos4_pm_resume(void) /* enable L2X0*/ writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL); #endif + +early_wakeup: + return; } static struct syscore_ops exynos4_pm_syscore_ops = { + .suspend = exynos4_pm_suspend, .resume = exynos4_pm_resume, }; diff --git a/arch/arm/mach-exynos4/pmu.c b/arch/arm/mach-exynos4/pmu.c new file mode 100644 index 0000000..7ea9eb2 --- /dev/null +++ b/arch/arm/mach-exynos4/pmu.c @@ -0,0 +1,175 @@ +/* linux/arch/arm/mach-exynos4/pmu.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * EXYNOS4210 - CPU PMU(Power Management Unit) support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/kernel.h> + +#include <mach/regs-clock.h> +#include <mach/pmu.h> + +static void __iomem *sys_powerdown_reg[] = { + S5P_ARM_CORE0_LOWPWR, + S5P_DIS_IRQ_CORE0, + S5P_DIS_IRQ_CENTRAL0, + S5P_ARM_CORE1_LOWPWR, + S5P_DIS_IRQ_CORE1, + S5P_DIS_IRQ_CENTRAL1, + S5P_ARM_COMMON_LOWPWR, + S5P_L2_0_LOWPWR, + S5P_L2_1_LOWPWR, + S5P_CMU_ACLKSTOP_LOWPWR, + S5P_CMU_SCLKSTOP_LOWPWR, + S5P_CMU_RESET_LOWPWR, + S5P_APLL_SYSCLK_LOWPWR, + S5P_MPLL_SYSCLK_LOWPWR, + S5P_VPLL_SYSCLK_LOWPWR, + S5P_EPLL_SYSCLK_LOWPWR, + S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, + S5P_CMU_RESET_GPSALIVE_LOWPWR, + S5P_CMU_CLKSTOP_CAM_LOWPWR, + S5P_CMU_CLKSTOP_TV_LOWPWR, + S5P_CMU_CLKSTOP_MFC_LOWPWR, + S5P_CMU_CLKSTOP_G3D_LOWPWR, + S5P_CMU_CLKSTOP_LCD0_LOWPWR, + S5P_CMU_CLKSTOP_LCD1_LOWPWR, + S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, + S5P_CMU_CLKSTOP_GPS_LOWPWR, + S5P_CMU_RESET_CAM_LOWPWR, + S5P_CMU_RESET_TV_LOWPWR, + S5P_CMU_RESET_MFC_LOWPWR, + S5P_CMU_RESET_G3D_LOWPWR, + S5P_CMU_RESET_LCD0_LOWPWR, + S5P_CMU_RESET_LCD1_LOWPWR, + S5P_CMU_RESET_MAUDIO_LOWPWR, + S5P_CMU_RESET_GPS_LOWPWR, + S5P_TOP_BUS_LOWPWR, + S5P_TOP_RETENTION_LOWPWR, + S5P_TOP_PWR_LOWPWR, + S5P_LOGIC_RESET_LOWPWR, + S5P_ONENAND_MEM_LOWPWR, + S5P_MODIMIF_MEM_LOWPWR, + S5P_G2D_ACP_MEM_LOWPWR, + S5P_USBOTG_MEM_LOWPWR, + S5P_HSMMC_MEM_LOWPWR, + S5P_CSSYS_MEM_LOWPWR, + S5P_SECSS_MEM_LOWPWR, + S5P_PCIE_MEM_LOWPWR, + S5P_SATA_MEM_LOWPWR, + S5P_PAD_RETENTION_DRAM_LOWPWR, + S5P_PAD_RETENTION_MAUDIO_LOWPWR, + S5P_PAD_RETENTION_GPIO_LOWPWR, + S5P_PAD_RETENTION_UART_LOWPWR, + S5P_PAD_RETENTION_MMCA_LOWPWR, + S5P_PAD_RETENTION_MMCB_LOWPWR, + S5P_PAD_RETENTION_EBIA_LOWPWR, + S5P_PAD_RETENTION_EBIB_LOWPWR, + S5P_PAD_RETENTION_ISOLATION_LOWPWR, + S5P_PAD_RETENTION_ALV_SEL_LOWPWR, + S5P_XUSBXTI_LOWPWR, + S5P_XXTI_LOWPWR, + S5P_EXT_REGULATOR_LOWPWR, + S5P_GPIO_MODE_LOWPWR, + S5P_GPIO_MODE_MAUDIO_LOWPWR, + S5P_CAM_LOWPWR, + S5P_TV_LOWPWR, + S5P_MFC_LOWPWR, + S5P_G3D_LOWPWR, + S5P_LCD0_LOWPWR, + S5P_LCD1_LOWPWR, + S5P_MAUDIO_LOWPWR, + S5P_GPS_LOWPWR, + S5P_GPS_ALIVE_LOWPWR, +}; + +static const unsigned int sys_powerdown_val[][NUM_SYS_POWERDOWN] = { + /* { AFTR, LPA, SLEEP }*/ + { 0, 0, 2 }, /* ARM_CORE0 */ + { 0, 0, 0 }, /* ARM_DIS_IRQ_CORE0 */ + { 0, 0, 0 }, /* ARM_DIS_IRQ_CENTRAL0 */ + { 0, 0, 2 }, /* ARM_CORE1 */ + { 0, 0, 0 }, /* ARM_DIS_IRQ_CORE1 */ + { 0, 0, 0 }, /* ARM_DIS_IRQ_CENTRAL1 */ + { 0, 0, 2 }, /* ARM_COMMON */ + { 2, 2, 3 }, /* ARM_CPU_L2_0 */ + { 2, 2, 3 }, /* ARM_CPU_L2_1 */ + { 1, 0, 0 }, /* CMU_ACLKSTOP */ + { 1, 0, 0 }, /* CMU_SCLKSTOP */ + { 1, 1, 0 }, /* CMU_RESET */ + { 1, 0, 0 }, /* APLL_SYSCLK */ + { 1, 0, 0 }, /* MPLL_SYSCLK */ + { 1, 0, 0 }, /* VPLL_SYSCLK */ + { 1, 1, 0 }, /* EPLL_SYSCLK */ + { 1, 1, 0 }, /* CMU_CLKSTOP_GPS_ALIVE */ + { 1, 1, 0 }, /* CMU_RESET_GPS_ALIVE */ + { 1, 1, 0 }, /* CMU_CLKSTOP_CAM */ + { 1, 1, 0 }, /* CMU_CLKSTOP_TV */ + { 1, 1, 0 }, /* CMU_CLKSTOP_MFC */ + { 1, 1, 0 }, /* CMU_CLKSTOP_G3D */ + { 1, 1, 0 }, /* CMU_CLKSTOP_LCD0 */ + { 1, 1, 0 }, /* CMU_CLKSTOP_LCD1 */ + { 1, 1, 0 }, /* CMU_CLKSTOP_MAUDIO */ + { 1, 1, 0 }, /* CMU_CLKSTOP_GPS */ + { 1, 1, 0 }, /* CMU_RESET_CAM */ + { 1, 1, 0 }, /* CMU_RESET_TV */ + { 1, 1, 0 }, /* CMU_RESET_MFC */ + { 1, 1, 0 }, /* CMU_RESET_G3D */ + { 1, 1, 0 }, /* CMU_RESET_LCD0 */ + { 1, 1, 0 }, /* CMU_RESET_LCD1 */ + { 1, 1, 0 }, /* CMU_RESET_MAUDIO */ + { 1, 1, 0 }, /* CMU_RESET_GPS */ + { 3, 0, 0 }, /* TOP_BUS */ + { 1, 0, 1 }, /* TOP_RETENTION */ + { 3, 0, 3 }, /* TOP_PWR */ + { 1, 1, 0 }, /* LOGIC_RESET */ + { 3, 0, 0 }, /* ONENAND_MEM */ + { 3, 0, 0 }, /* MODIMIF_MEM */ + { 3, 0, 0 }, /* G2D_ACP_MEM */ + { 3, 0, 0 }, /* USBOTG_MEM */ + { 3, 0, 0 }, /* HSMMC_MEM */ + { 3, 0, 0 }, /* CSSYS_MEM */ + { 3, 0, 0 }, /* SECSS_MEM */ + { 3, 0, 0 }, /* PCIE_MEM */ + { 3, 0, 0 }, /* SATA_MEM */ + { 1, 0, 0 }, /* PAD_RETENTION_DRAM */ + { 1, 1, 0 }, /* PAD_RETENTION_MAUDIO */ + { 1, 0, 0 }, /* PAD_RETENTION_GPIO */ + { 1, 0, 0 }, /* PAD_RETENTION_UART */ + { 1, 0, 0 }, /* PAD_RETENTION_MMCA */ + { 1, 0, 0 }, /* PAD_RETENTION_MMCB */ + { 1, 0, 0 }, /* PAD_RETENTION_EBIA */ + { 1, 0, 0 }, /* PAD_RETENTION_EBIB */ + { 1, 0, 0 }, /* PAD_RETENTION_ISOLATION */ + { 1, 0, 0 }, /* PAD_RETENTION_ALV_SEL */ + { 1, 1, 0 }, /* XUSBXTI */ + { 1, 1, 0 }, /* XXTI */ + { 1, 1, 0 }, /* EXT_REGULATOR */ + { 1, 0, 0 }, /* GPIO_MODE */ + { 1, 1, 0 }, /* GPIO_MODE_MAUDIO */ + { 7, 0, 0 }, /* CAM */ + { 7, 0, 0 }, /* TV */ + { 7, 0, 0 }, /* MFC */ + { 7, 0, 0 }, /* G3D */ + { 7, 0, 0 }, /* LCD0 */ + { 7, 0, 0 }, /* LCD1 */ + { 7, 7, 0 }, /* MAUDIO */ + { 7, 0, 0 }, /* GPS */ + { 7, 0, 0 }, /* GPS_ALIVE */ +}; + +void exynos4_sys_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int count = ARRAY_SIZE(sys_powerdown_reg); + + for (; count > 0; count--) + __raw_writel(sys_powerdown_val[count - 1][mode], + sys_powerdown_reg[count - 1]); +} diff --git a/arch/arm/mach-exynos4/setup-fimd0.c b/arch/arm/mach-exynos4/setup-fimd0.c new file mode 100644 index 0000000..07a6dbe --- /dev/null +++ b/arch/arm/mach-exynos4/setup-fimd0.c @@ -0,0 +1,43 @@ +/* linux/arch/arm/mach-exynos4/setup-fimd0.c + * + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Base Exynos4 FIMD 0 configuration + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/fb.h> +#include <linux/gpio.h> + +#include <plat/gpio-cfg.h> +#include <plat/regs-fb-v4.h> + +#include <mach/map.h> + +void exynos4_fimd0_gpio_setup_24bpp(void) +{ + unsigned int reg; + + s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2)); + s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2)); + s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2)); + s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2)); + + /* + * Set DISPLAY_CONTROL register for Display path selection. + * + * DISPLAY_CONTROL[1:0] + * --------------------- + * 00 | MIE + * 01 | MDINE + * 10 | FIMD : selected + * 11 | FIMD + */ + reg = __raw_readl(S3C_VA_SYS + 0x0210); + reg |= (1 << 1); + __raw_writel(reg, S3C_VA_SYS + 0x0210); +} diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c index 0883c1b..39aca04 100644 --- a/arch/arm/mach-exynos4/setup-usb-phy.c +++ b/arch/arm/mach-exynos4/setup-usb-phy.c @@ -82,7 +82,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev) rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); writel(rstcon, EXYNOS4_RSTCON); - udelay(50); + udelay(80); clk_disable(otg_clk); clk_put(otg_clk); diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c deleted file mode 100644 index ebb8f38..0000000 --- a/arch/arm/mach-exynos4/time.c +++ /dev/null @@ -1,301 +0,0 @@ -/* linux/arch/arm/mach-exynos4/time.c - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 (and compatible) HRT support - * PWM 2/4 is used for this feature - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/clockchips.h> -#include <linux/platform_device.h> - -#include <asm/smp_twd.h> - -#include <mach/map.h> -#include <plat/regs-timer.h> -#include <asm/mach/time.h> - -static unsigned long clock_count_per_tick; - -static struct clk *tin2; -static struct clk *tin4; -static struct clk *tdiv2; -static struct clk *tdiv4; -static struct clk *timerclk; - -static void exynos4_pwm_stop(unsigned int pwm_id) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (pwm_id) { - case 2: - tcon &= ~S3C2410_TCON_T2START; - break; - case 4: - tcon &= ~S3C2410_TCON_T4START; - break; - default: - break; - } - __raw_writel(tcon, S3C2410_TCON); -} - -static void exynos4_pwm_init(unsigned int pwm_id, unsigned long tcnt) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - /* timers reload after counting zero, so reduce the count by 1 */ - tcnt--; - - /* ensure timer is stopped... */ - switch (pwm_id) { - case 2: - tcon &= ~(0xf<<12); - tcon |= S3C2410_TCON_T2MANUALUPD; - - __raw_writel(tcnt, S3C2410_TCNTB(2)); - __raw_writel(tcnt, S3C2410_TCMPB(2)); - __raw_writel(tcon, S3C2410_TCON); - - break; - case 4: - tcon &= ~(7<<20); - tcon |= S3C2410_TCON_T4MANUALUPD; - - __raw_writel(tcnt, S3C2410_TCNTB(4)); - __raw_writel(tcnt, S3C2410_TCMPB(4)); - __raw_writel(tcon, S3C2410_TCON); - - break; - default: - break; - } -} - -static inline void exynos4_pwm_start(unsigned int pwm_id, bool periodic) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (pwm_id) { - case 2: - tcon |= S3C2410_TCON_T2START; - tcon &= ~S3C2410_TCON_T2MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T2RELOAD; - else - tcon &= ~S3C2410_TCON_T2RELOAD; - break; - case 4: - tcon |= S3C2410_TCON_T4START; - tcon &= ~S3C2410_TCON_T4MANUALUPD; - - if (periodic) - tcon |= S3C2410_TCON_T4RELOAD; - else - tcon &= ~S3C2410_TCON_T4RELOAD; - break; - default: - break; - } - __raw_writel(tcon, S3C2410_TCON); -} - -static int exynos4_pwm_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - exynos4_pwm_init(2, cycles); - exynos4_pwm_start(2, 0); - return 0; -} - -static void exynos4_pwm_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - exynos4_pwm_stop(2); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - exynos4_pwm_init(2, clock_count_per_tick); - exynos4_pwm_start(2, 1); - break; - case CLOCK_EVT_MODE_ONESHOT: - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_RESUME: - break; - } -} - -static struct clock_event_device pwm_event_device = { - .name = "pwm_timer2", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .rating = 200, - .shift = 32, - .set_next_event = exynos4_pwm_set_next_event, - .set_mode = exynos4_pwm_set_mode, -}; - -irqreturn_t exynos4_clock_event_isr(int irq, void *dev_id) -{ - struct clock_event_device *evt = &pwm_event_device; - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction exynos4_clock_event_irq = { - .name = "pwm_timer2_irq", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = exynos4_clock_event_isr, -}; - -static void __init exynos4_clockevent_init(void) -{ - unsigned long pclk; - unsigned long clock_rate; - struct clk *tscaler; - - pclk = clk_get_rate(timerclk); - - /* configure clock tick */ - - tscaler = clk_get_parent(tdiv2); - - clk_set_rate(tscaler, pclk / 2); - clk_set_rate(tdiv2, pclk / 2); - clk_set_parent(tin2, tdiv2); - - clock_rate = clk_get_rate(tin2); - - clock_count_per_tick = clock_rate / HZ; - - pwm_event_device.mult = - div_sc(clock_rate, NSEC_PER_SEC, pwm_event_device.shift); - pwm_event_device.max_delta_ns = - clockevent_delta2ns(-1, &pwm_event_device); - pwm_event_device.min_delta_ns = - clockevent_delta2ns(1, &pwm_event_device); - - pwm_event_device.cpumask = cpumask_of(0); - clockevents_register_device(&pwm_event_device); - - setup_irq(IRQ_TIMER2, &exynos4_clock_event_irq); -} - -static cycle_t exynos4_pwm4_read(struct clocksource *cs) -{ - return (cycle_t) ~__raw_readl(S3C_TIMERREG(0x40)); -} - -#ifdef CONFIG_PM -static void exynos4_pwm4_resume(struct clocksource *cs) -{ - unsigned long pclk; - - pclk = clk_get_rate(timerclk); - - clk_set_rate(tdiv4, pclk / 2); - clk_set_parent(tin4, tdiv4); - - exynos4_pwm_init(4, ~0); - exynos4_pwm_start(4, 1); -} -#endif - -struct clocksource pwm_clocksource = { - .name = "pwm_timer4", - .rating = 250, - .read = exynos4_pwm4_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS , -#ifdef CONFIG_PM - .resume = exynos4_pwm4_resume, -#endif -}; - -static void __init exynos4_clocksource_init(void) -{ - unsigned long pclk; - unsigned long clock_rate; - - pclk = clk_get_rate(timerclk); - - clk_set_rate(tdiv4, pclk / 2); - clk_set_parent(tin4, tdiv4); - - clock_rate = clk_get_rate(tin4); - - exynos4_pwm_init(4, ~0); - exynos4_pwm_start(4, 1); - - if (clocksource_register_hz(&pwm_clocksource, clock_rate)) - panic("%s: can't register clocksource\n", pwm_clocksource.name); -} - -static void __init exynos4_timer_resources(void) -{ - struct platform_device tmpdev; - - tmpdev.dev.bus = &platform_bus_type; - - timerclk = clk_get(NULL, "timers"); - if (IS_ERR(timerclk)) - panic("failed to get timers clock for system timer"); - - clk_enable(timerclk); - - tmpdev.id = 2; - tin2 = clk_get(&tmpdev.dev, "pwm-tin"); - if (IS_ERR(tin2)) - panic("failed to get pwm-tin2 clock for system timer"); - - tdiv2 = clk_get(&tmpdev.dev, "pwm-tdiv"); - if (IS_ERR(tdiv2)) - panic("failed to get pwm-tdiv2 clock for system timer"); - clk_enable(tin2); - - tmpdev.id = 4; - tin4 = clk_get(&tmpdev.dev, "pwm-tin"); - if (IS_ERR(tin4)) - panic("failed to get pwm-tin4 clock for system timer"); - - tdiv4 = clk_get(&tmpdev.dev, "pwm-tdiv"); - if (IS_ERR(tdiv4)) - panic("failed to get pwm-tdiv4 clock for system timer"); - - clk_enable(tin4); -} - -static void __init exynos4_timer_init(void) -{ -#ifdef CONFIG_LOCAL_TIMERS - twd_base = S5P_VA_TWD; -#endif - - exynos4_timer_resources(); - exynos4_clockevent_init(); - exynos4_clocksource_init(); -} - -struct sys_timer exynos4_timer = { - .init = exynos4_timer_init, -}; diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index dc26fff..c8e7afc 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig @@ -62,6 +62,7 @@ config ARCH_EBSA285_HOST config ARCH_NETWINDER bool "NetWinder" select CLKSRC_I8253 + select CLKEVT_I8253 select FOOTBRIDGE_HOST select ISA select ISA_DMA diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c index ae3e1c8..32321f6 100644 --- a/arch/arm/mach-footbridge/cats-pci.c +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -16,7 +16,7 @@ /* cats host-specific stuff */ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; -static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->irq >= 255) return -1; /* not a valid interrupt. */ diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 3ffa548..18c32a5 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -18,6 +18,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/spinlock.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/system.h> @@ -295,6 +296,9 @@ void __init dc21285_preinit(void) unsigned int mem_size, mem_mask; int cfn_mode; + pcibios_min_mem = 0x81000000; + vga_base = PCIMEM_BASE; + mem_size = (unsigned int)high_memory - PAGE_OFFSET; for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1) if (mem_mask >= mem_size) diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c index e5ab5bd..511c673 100644 --- a/arch/arm/mach-footbridge/ebsa285-pci.c +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -15,7 +15,7 @@ static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; -static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->vendor == PCI_VENDOR_ID_CONTAQ && dev->device == PCI_DEVICE_ID_CONTAQ_82C693) diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h index b6fdf23..15d5498 100644 --- a/arch/arm/mach-footbridge/include/mach/hardware.h +++ b/arch/arm/mach-footbridge/include/mach/hardware.h @@ -100,9 +100,4 @@ extern unsigned int nw_gpio_read(void); extern void nw_cpld_modify(unsigned int mask, unsigned int set); #endif -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x1000 -#define PCIBIOS_MIN_MEM 0x81000000 - #endif diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c index e263d6d..6218761 100644 --- a/arch/arm/mach-footbridge/netwinder-pci.c +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -17,7 +17,7 @@ * We now use the slot ID instead of the device identifiers to select * which interrupt is routed where. */ -static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 0: /* host bridge */ diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c index d5fca95..aeb651d 100644 --- a/arch/arm/mach-footbridge/personal-pci.c +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -18,7 +18,8 @@ static int irqmap_personal_server[] __initdata = { IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI }; -static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { unsigned char line; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index e8dd22f..0519dd7 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -278,6 +278,7 @@ config MACH_MX27_3DS select SOC_IMX27 select IMX_HAVE_PLATFORM_FSL_USB2_UDC select IMX_HAVE_PLATFORM_IMX2_WDT + select IMX_HAVE_PLATFORM_IMX_FB select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD select IMX_HAVE_PLATFORM_IMX_UART diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c index dcc4172..4aabeb2 100644 --- a/arch/arm/mach-imx/clock-imx1.c +++ b/arch/arm/mach-imx/clock-imx1.c @@ -587,9 +587,9 @@ static struct clk_lookup lookups[] __initdata = { _REGISTER_CLOCK(NULL, "mma", mma_clk) _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk) + _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk) + _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk) + _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk) _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk) diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c index bf30a8c..ee15d8c 100644 --- a/arch/arm/mach-imx/clock-imx21.c +++ b/arch/arm/mach-imx/clock-imx21.c @@ -1162,10 +1162,10 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "perclk3", per_clk[2]) _REGISTER_CLOCK(NULL, "perclk4", per_clk[3]) _REGISTER_CLOCK(NULL, "clko", clko_clk) - _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0]) - _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1]) - _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2]) - _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3]) + _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0]) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1]) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2]) + _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3]) _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0]) _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1]) _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2]) diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c index af1c580..e63e235 100644 --- a/arch/arm/mach-imx/clock-imx25.c +++ b/arch/arm/mach-imx/clock-imx25.c @@ -272,11 +272,12 @@ DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL); }, static struct clk_lookup lookups[] = { - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) + /* i.mx25 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) @@ -295,19 +296,20 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) - _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk) _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk) _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk) _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) - _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) + /* i.mx25 has the i.mx35 type sdma */ + _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) }; int __init mx25_clocks_init(void) @@ -329,6 +331,9 @@ int __init mx25_clocks_init(void) __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0), CRM_BASE + 0x64); + /* Clock source for gpt is ahb_div */ + __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64); + mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c index 583f251..6912b82 100644 --- a/arch/arm/mach-imx/clock-imx27.c +++ b/arch/arm/mach-imx/clock-imx27.c @@ -624,12 +624,13 @@ DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk); }, static struct clk_lookup lookups[] = { - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk) + /* i.mx27 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) + _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk) _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk) _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk) _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk) @@ -662,7 +663,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "brom", brom_clk) _REGISTER_CLOCK(NULL, "emma", emma_clk) _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) - _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) _REGISTER_CLOCK(NULL, "emi", emi_clk) _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk) _REGISTER_CLOCK(NULL, "ata", ata_clk) diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c index 25f343f..d973770 100644 --- a/arch/arm/mach-imx/clock-imx31.c +++ b/arch/arm/mach-imx/clock-imx31.c @@ -547,11 +547,12 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) + /* i.mx31 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) @@ -564,7 +565,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "rng", rng_clk) - _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1) + _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1) _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c index 5a4cc1e..88b62a07 100644 --- a/arch/arm/mach-imx/clock-imx35.c +++ b/arch/arm/mach-imx/clock-imx35.c @@ -458,10 +458,11 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk) _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk) _REGISTER_CLOCK(NULL, "esai", esai_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk) - _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk) + /* i.mx35 has the i.mx27 type fec */ + _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) @@ -481,14 +482,15 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "rtc", rtc_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "scc", scc_clk) - _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) + _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) _REGISTER_CLOCK(NULL, "spba", spba_clk) _REGISTER_CLOCK(NULL, "spdif", spdif_clk) _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + /* i.mx35 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c index 01ebcb3..66e8726 100644 --- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c @@ -225,7 +225,8 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { static struct esdhc_platform_data sd1_pdata = { .cd_gpio = GPIO_SD1CD, - .wp_gpio = -EINVAL, + .cd_type = ESDHC_CD_GPIO, + .wp_type = ESDHC_WP_NONE, }; /* diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c index 558eb52..0f0af02 100644 --- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c @@ -236,7 +236,8 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { static struct esdhc_platform_data sd1_pdata = { .cd_gpio = GPIO_SD1CD, - .wp_gpio = -EINVAL, + .cd_type = ESDHC_CD_GPIO, + .wp_type = ESDHC_WP_NONE, }; /* diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 87887ac..f851fe9 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c @@ -310,7 +310,7 @@ static struct sys_timer eukrea_cpuimx27_timer = { .init = eukrea_cpuimx27_timer_init, }; -MACHINE_START(CPUIMX27, "EUKREA CPUIMX27") +MACHINE_START(EUKREA_CPUIMX27, "EUKREA CPUIMX27") .boot_params = MX27_PHYS_OFFSET + 0x100, .map_io = mx27_map_io, .init_early = imx27_init_early, diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index f39a478b..4bd083b 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -192,7 +192,7 @@ struct sys_timer eukrea_cpuimx35_timer = { .init = eukrea_cpuimx35_timer_init, }; -MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35") +MACHINE_START(EUKREA_CPUIMX35SD, "Eukrea CPUIMX35") /* Maintainer: Eukrea Electromatique */ .boot_params = MX3x_PHYS_OFFSET + 0x100, .map_io = mx35_map_io, diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c index da36da5..2442d5d 100644 --- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c +++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c @@ -161,7 +161,7 @@ static struct sys_timer eukrea_cpuimx25_timer = { .init = eukrea_cpuimx25_timer_init, }; -MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25") +MACHINE_START(EUKREA_CPUIMX25SD, "Eukrea CPUIMX25") /* Maintainer: Eukrea Electromatique */ .boot_params = MX25_PHYS_OFFSET + 0x100, .map_io = mx25_map_io, diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index 6707de0a..6778f81 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -30,6 +30,7 @@ #include <linux/input.h> #include <linux/gpio.h> #include <linux/delay.h> +#include <sound/tlv320aic32x4.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> @@ -196,6 +197,17 @@ static struct pca953x_platform_data visstrim_m10_pca9555_pdata = { .invert = 0, }; +static struct aic32x4_pdata visstrim_m10_aic32x4_pdata = { + .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN | + AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE | + AIC32X4_PWR_AIC32X4_LDO_ENABLE | + AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 | + AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED, + .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K | + AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K, + .swapdacs = false, +}; + static struct i2c_board_info visstrim_m10_i2c_devices[] = { { I2C_BOARD_INFO("pca9555", 0x20), @@ -203,6 +215,7 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { }, { I2C_BOARD_INFO("tlv320aic32x4", 0x18), + .platform_data = &visstrim_m10_aic32x4_pdata, } }; diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c index 01534bb..7f66a91 100644 --- a/arch/arm/mach-imx/mach-mx25_3ds.c +++ b/arch/arm/mach-imx/mach-mx25_3ds.c @@ -215,6 +215,8 @@ static const struct imxi2c_platform_data mx25_3ds_i2c0_data __initconst = { static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = { .wp_gpio = SD1_GPIO_WP, .cd_gpio = SD1_GPIO_CD, + .wp_type = ESDHC_WP_GPIO, + .cd_type = ESDHC_CD_GPIO, }; static void __init mx25pdk_init(void) diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index b31d412..6fa6934 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -29,6 +29,7 @@ #include <linux/mfd/mc13783.h> #include <linux/spi/spi.h> #include <linux/regulator/machine.h> +#include <linux/spi/l4f00242t03.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -47,7 +48,10 @@ #define SPI2_SS0 IMX_GPIO_NR(4, 21) #define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(3, 28)) #define PMIC_INT IMX_GPIO_NR(3, 14) +#define SPI1_SS0 IMX_GPIO_NR(4, 28) #define SD1_CD IMX_GPIO_NR(2, 26) +#define LCD_RESET IMX_GPIO_NR(1, 3) +#define LCD_ENABLE IMX_GPIO_NR(1, 31) static const int mx27pdk_pins[] __initconst = { /* UART1 */ @@ -96,6 +100,12 @@ static const int mx27pdk_pins[] __initconst = { PE2_PF_USBOTG_DIR, PE24_PF_USBOTG_CLK, PE25_PF_USBOTG_DATA7, + /* CSPI1 */ + PD31_PF_CSPI1_MOSI, + PD30_PF_CSPI1_MISO, + PD29_PF_CSPI1_SCLK, + PD25_PF_CSPI1_RDY, + SPI1_SS0 | GPIO_GPIO | GPIO_OUT, /* CSPI2 */ PD22_PF_CSPI2_SCLK, PD23_PF_CSPI2_MISO, @@ -106,6 +116,31 @@ static const int mx27pdk_pins[] __initconst = { PD18_PF_I2C_CLK, /* PMIC INT */ PMIC_INT | GPIO_GPIO | GPIO_IN, + /* LCD */ + PA5_PF_LSCLK, + PA6_PF_LD0, + PA7_PF_LD1, + PA8_PF_LD2, + PA9_PF_LD3, + PA10_PF_LD4, + PA11_PF_LD5, + PA12_PF_LD6, + PA13_PF_LD7, + PA14_PF_LD8, + PA15_PF_LD9, + PA16_PF_LD10, + PA17_PF_LD11, + PA18_PF_LD12, + PA19_PF_LD13, + PA20_PF_LD14, + PA21_PF_LD15, + PA22_PF_LD16, + PA23_PF_LD17, + PA28_PF_HSYNC, + PA29_PF_VSYNC, + PA30_PF_CONTRAST, + LCD_ENABLE | GPIO_GPIO | GPIO_OUT, + LCD_RESET | GPIO_GPIO | GPIO_OUT, }; static const struct imxuart_platform_data uart_pdata __initconst = { @@ -258,10 +293,18 @@ static struct mc13xxx_platform_data mc13783_pdata = { .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), }, - .flags = MC13783_USE_REGULATOR, + .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN | + MC13783_USE_RTC, }; /* SPI */ +static int spi1_chipselect[] = {SPI1_SS0}; + +static const struct spi_imx_master spi1_pdata __initconst = { + .chipselect = spi1_chipselect, + .num_chipselect = ARRAY_SIZE(spi1_chipselect), +}; + static int spi2_chipselect[] = {SPI2_SS0}; static const struct spi_imx_master spi2_pdata __initconst = { @@ -269,6 +312,46 @@ static const struct spi_imx_master spi2_pdata __initconst = { .num_chipselect = ARRAY_SIZE(spi2_chipselect), }; +static struct imx_fb_videomode mx27_3ds_modes[] = { + { /* 480x640 @ 60 Hz */ + .mode = { + .name = "Epson-VGA", + .refresh = 60, + .xres = 480, + .yres = 640, + .pixclock = 41701, + .left_margin = 20, + .right_margin = 41, + .upper_margin = 10, + .lower_margin = 5, + .hsync_len = 20, + .vsync_len = 10, + .sync = FB_SYNC_OE_ACT_HIGH | + FB_SYNC_CLK_INVERT, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, + .bpp = 16, + .pcr = 0xFAC08B82, + }, +}; + +static const struct imx_fb_platform_data mx27_3ds_fb_data __initconst = { + .mode = mx27_3ds_modes, + .num_modes = ARRAY_SIZE(mx27_3ds_modes), + .pwmr = 0x00A903FF, + .lscr1 = 0x00120300, + .dmacr = 0x00020010, +}; + +/* LCD */ +static struct l4f00242t03_pdata mx27_3ds_lcd_pdata = { + .reset_gpio = LCD_RESET, + .data_enable_gpio = LCD_ENABLE, + .core_supply = "lcd_2v8", + .io_supply = "vdd_lcdio", +}; + static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { { .modalias = "mc13783", @@ -278,6 +361,12 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { .platform_data = &mc13783_pdata, .irq = gpio_to_irq(PMIC_INT), .mode = SPI_CS_HIGH, + }, { + .modalias = "l4f00242t03", + .max_speed_hz = 5000000, + .bus_num = 0, + .chip_select = 0, /* SS0 */ + .platform_data = &mx27_3ds_lcd_pdata, }, }; @@ -311,12 +400,14 @@ static void __init mx27pdk_init(void) imx27_add_fsl_usb2_udc(&otg_device_pdata); imx27_add_spi_imx1(&spi2_pdata); + imx27_add_spi_imx0(&spi1_pdata); spi_register_board_info(mx27_3ds_spi_devs, ARRAY_SIZE(mx27_3ds_spi_devs)); if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT)) pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n"); imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data); + imx27_add_imx_fb(&mx27_3ds_fb_data); } static void __init mx27pdk_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 0ce4947..29ca890 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -468,7 +468,7 @@ static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { #endif }; -static void mxc_init_i2c(void) +static void __init mxc_init_i2c(void) { i2c_register_board_info(1, mx31ads_i2c1_devices, ARRAY_SIZE(mx31ads_i2c1_devices)); @@ -486,7 +486,7 @@ static unsigned int ssi_pins[] = { MX31_PIN_STXD5__STXD5, }; -static void mxc_init_audio(void) +static void __init mxc_init_audio(void) { imx31_add_imx_ssi(0, NULL); mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c index 750368d..126913a 100644 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ b/arch/arm/mach-imx/mach-mx31lilly.c @@ -192,7 +192,7 @@ static struct mxc_usbh_platform_data usbh2_pdata __initdata = { .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, }; -static void lilly1131_usb_init(void) +static void __init lilly1131_usb_init(void) { imx31_add_mxc_ehci_hs(1, &usbh1_pdata); diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index 163cc318..660ec3e 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -349,6 +349,8 @@ __setup("otg_mode=", pcm043_otg_mode); static struct esdhc_platform_data sd1_pdata = { .wp_gpio = SD1_GPIO_WP, .cd_gpio = SD1_GPIO_CD, + .wp_type = ESDHC_WP_GPIO, + .cd_type = ESDHC_CD_GPIO, }; /* diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c index 6d7d518..3f05dfe 100644 --- a/arch/arm/mach-imx/mm-imx21.c +++ b/arch/arm/mach-imx/mm-imx21.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <mach/hardware.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <asm/pgtable.h> #include <asm/mach/map.h> #include <mach/irqs.h> @@ -82,4 +83,6 @@ void __init imx21_soc_init(void) mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); + + imx_add_imx_dma(); } diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index 9a1591c..cc4d152 100644 --- a/arch/arm/mach-imx/mm-imx25.c +++ b/arch/arm/mach-imx/mm-imx25.c @@ -24,6 +24,7 @@ #include <asm/mach/map.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <mach/hardware.h> #include <mach/mx25.h> #include <mach/iomux-v3.h> @@ -61,6 +62,27 @@ void __init mx25_init_irq(void) mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR)); } +static struct sdma_script_start_addrs imx25_sdma_script __initdata = { + .ap_2_ap_addr = 729, + .uart_2_mcu_addr = 904, + .per_2_app_addr = 1255, + .mcu_2_app_addr = 834, + .uartsh_2_mcu_addr = 1120, + .per_2_shp_addr = 1329, + .mcu_2_shp_addr = 1048, + .ata_2_mcu_addr = 1560, + .mcu_2_ata_addr = 1479, + .app_2_per_addr = 1189, + .app_2_mcu_addr = 770, + .shp_2_per_addr = 1407, + .shp_2_mcu_addr = 979, +}; + +static struct sdma_platform_data imx25_sdma_pdata __initdata = { + .fw_name = "sdma-imx25.bin", + .script_addrs = &imx25_sdma_script, +}; + void __init imx25_soc_init(void) { /* i.mx25 has the i.mx31 type gpio */ @@ -68,4 +90,7 @@ void __init imx25_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); + + /* i.mx25 has the i.mx35 type sdma */ + imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata); } diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c index 133b300..96dd1f5 100644 --- a/arch/arm/mach-imx/mm-imx27.c +++ b/arch/arm/mach-imx/mm-imx27.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <mach/hardware.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <asm/pgtable.h> #include <asm/mach/map.h> #include <mach/irqs.h> @@ -83,4 +84,6 @@ void __init imx27_soc_init(void) mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); + + imx_add_imx_dma(); } diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c index 6d103c0..b7c55e7 100644 --- a/arch/arm/mach-imx/mm-imx31.c +++ b/arch/arm/mach-imx/mm-imx31.c @@ -24,6 +24,7 @@ #include <asm/mach/map.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <mach/hardware.h> #include <mach/iomux-v3.h> #include <mach/irqs.h> @@ -57,9 +58,34 @@ void __init mx31_init_irq(void) mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); } +static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = { + .per_2_per_addr = 1677, +}; + +static struct sdma_script_start_addrs imx31_to2_sdma_script __initdata = { + .ap_2_ap_addr = 423, + .ap_2_bp_addr = 829, + .bp_2_ap_addr = 1029, +}; + +static struct sdma_platform_data imx31_sdma_pdata __initdata = { + .fw_name = "sdma-imx31-to2.bin", + .script_addrs = &imx31_to2_sdma_script, +}; + void __init imx31_soc_init(void) { + int to_version = mx31_revision() >> 4; + mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0); mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); + + if (to_version == 1) { + strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", + strlen(imx31_sdma_pdata.fw_name)); + imx31_sdma_pdata.script_addrs = &imx31_to1_sdma_script; + } + + imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata); } diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c index bb068bc..f49bac7 100644 --- a/arch/arm/mach-imx/mm-imx35.c +++ b/arch/arm/mach-imx/mm-imx35.c @@ -25,6 +25,7 @@ #include <asm/hardware/cache-l2x0.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <mach/hardware.h> #include <mach/iomux-v3.h> #include <mach/irqs.h> @@ -54,10 +55,55 @@ void __init mx35_init_irq(void) mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); } +static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = { + .ap_2_ap_addr = 642, + .uart_2_mcu_addr = 817, + .mcu_2_app_addr = 747, + .uartsh_2_mcu_addr = 1183, + .per_2_shp_addr = 1033, + .mcu_2_shp_addr = 961, + .ata_2_mcu_addr = 1333, + .mcu_2_ata_addr = 1252, + .app_2_mcu_addr = 683, + .shp_2_per_addr = 1111, + .shp_2_mcu_addr = 892, +}; + +static struct sdma_script_start_addrs imx35_to2_sdma_script __initdata = { + .ap_2_ap_addr = 729, + .uart_2_mcu_addr = 904, + .per_2_app_addr = 1597, + .mcu_2_app_addr = 834, + .uartsh_2_mcu_addr = 1270, + .per_2_shp_addr = 1120, + .mcu_2_shp_addr = 1048, + .ata_2_mcu_addr = 1429, + .mcu_2_ata_addr = 1339, + .app_2_per_addr = 1531, + .app_2_mcu_addr = 770, + .shp_2_per_addr = 1198, + .shp_2_mcu_addr = 979, +}; + +static struct sdma_platform_data imx35_sdma_pdata __initdata = { + .fw_name = "sdma-imx35-to2.bin", + .script_addrs = &imx35_to2_sdma_script, +}; + void __init imx35_soc_init(void) { + int to_version = mx35_revision() >> 4; + /* i.mx35 has the i.mx31 type gpio */ mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); + + if (to_version == 1) { + strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin", + strlen(imx35_sdma_pdata.fw_name)); + imx35_sdma_pdata.script_addrs = &imx35_to1_sdma_script; + } + + imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata); } diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h index 57f51ba..65fed7c 100644 --- a/arch/arm/mach-integrator/include/mach/hardware.h +++ b/arch/arm/mach-integrator/include/mach/hardware.h @@ -32,13 +32,6 @@ #define IO_SIZE 0x0B000000 // How much? #define IO_START INTEGRATOR_HDR_BASE // PA of IO -#define PCIMEM_BASE PCI_MEMORY_VADDR - -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x6000 -#define PCIBIOS_MIN_MEM 0x00100000 - /* macro to get at IO space when running virtually */ #ifdef CONFIG_MMU #define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE) diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 2fbbdd5..fcf0ae9 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -337,15 +337,15 @@ static unsigned long timer_reload; static void integrator_clocksource_init(u32 khz) { void __iomem *base = (void __iomem *)TIMER2_VA_BASE; - u32 ctrl = TIMER_CTRL_ENABLE; + u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; if (khz >= 1500) { khz /= 16; - ctrl = TIMER_CTRL_DIV16; + ctrl |= TIMER_CTRL_DIV16; } - writel(ctrl, base + TIMER_CTRL); writel(0xffff, base + TIMER_LOAD); + writel(ctrl, base + TIMER_CTRL); clocksource_mmio_init(base + TIMER_VALUE, "timer2", khz * 1000, 200, 16, clocksource_mmio_readl_down); diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index 2fdb954..520b6bf 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -95,7 +95,7 @@ static int irq_tab[4] __initdata = { * map the specified device/slot/pin to an IRQ. This works out such * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. */ -static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init integrator_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int intnr = ((slot - 9) + (pin - 1)) & 3; diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 6467d99..dd56bfb 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -27,6 +27,7 @@ #include <linux/spinlock.h> #include <linux/init.h> #include <linux/io.h> +#include <video/vga.h> #include <mach/hardware.h> #include <mach/platform.h> @@ -502,6 +503,10 @@ void __init pci_v3_preinit(void) unsigned int temp; int ret; + pcibios_min_io = 0x6000; + pcibios_min_mem = 0x00100000; + vga_base = PCI_MEMORY_VADDR; + /* * Hook in our fault handler for PCI errors */ diff --git a/arch/arm/mach-iop13xx/include/mach/hardware.h b/arch/arm/mach-iop13xx/include/mach/hardware.h index 8e1d562..786fa26 100644 --- a/arch/arm/mach-iop13xx/include/mach/hardware.h +++ b/arch/arm/mach-iop13xx/include/mach/hardware.h @@ -2,18 +2,11 @@ #define __ASM_ARCH_HARDWARE_H #include <asm/types.h> -#define pcibios_assign_all_busses() 1 - #ifndef __ASSEMBLY__ -extern unsigned long iop13xx_pcibios_min_io; -extern unsigned long iop13xx_pcibios_min_mem; extern u16 iop13xx_dev_id(void); extern void iop13xx_set_atu_mmr_bases(void); #endif -#define PCIBIOS_MIN_IO (iop13xx_pcibios_min_io) -#define PCIBIOS_MIN_MEM (iop13xx_pcibios_min_mem) - /* * Generic chipset bits * diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 9b5a63f..23dfaff 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -30,7 +30,7 @@ extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */ static int __init -iq81340mc_pcix_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +iq81340mc_pcix_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin) { switch (idsel) { case 1: diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index ba3dae3..251c408 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -39,8 +39,6 @@ u32 iop13xx_atue_mem_base; u32 iop13xx_atux_mem_base; size_t iop13xx_atue_mem_size; size_t iop13xx_atux_mem_size; -unsigned long iop13xx_pcibios_min_io = 0; -unsigned long iop13xx_pcibios_min_mem = 0; EXPORT_SYMBOL(iop13xx_atue_mem_base); EXPORT_SYMBOL(iop13xx_atux_mem_base); @@ -390,7 +388,7 @@ static int iop13xx_atue_pci_status(int clear) } static int -iop13xx_pcie_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +iop13xx_pcie_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin) { WARN_ON(idsel != 0); @@ -971,7 +969,8 @@ void __init iop13xx_pci_init(void) __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR); /* Setup the Min Address for PCI memory... */ - iop13xx_pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA; + pcibios_min_io = 0; + pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA; /* if Linux is given control of an ATU * clear out its prior configuration, diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 779f924..6cbffbf 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c @@ -81,7 +81,7 @@ void __init em7210_map_io(void) #define INTD IRQ_IOP32X_XINT3 static int __init -em7210_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +em7210_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[][4] = { /* diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index c6b6f9c..ceef5d4 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -77,7 +77,7 @@ void __init glantank_map_io(void) #define INTD IRQ_IOP32X_XINT3 static int __init -glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +glantank_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[][4] = { /* diff --git a/arch/arm/mach-iop32x/include/mach/hardware.h b/arch/arm/mach-iop32x/include/mach/hardware.h index d559c4e..48cb1b2 100644 --- a/arch/arm/mach-iop32x/include/mach/hardware.h +++ b/arch/arm/mach-iop32x/include/mach/hardware.h @@ -18,9 +18,6 @@ * but when we read them, we convert them to virtual addresses. See * arch/arm/plat-iop/pci.c. */ -#define pcibios_assign_all_busses() 1 -#define PCIBIOS_MIN_IO 0x00000000 -#define PCIBIOS_MIN_MEM 0x00000000 #ifndef __ASSEMBLY__ void iop32x_init_irq(void); diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index fde962c..3a62514 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -103,7 +103,7 @@ void __init iq31244_map_io(void) * EP80219/IQ31244 PCI. */ static int __init -ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +ep80219_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; @@ -139,7 +139,7 @@ static struct hw_pci ep80219_pci __initdata = { }; static int __init -iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +iq31244_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 3a95950..35b7e69 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -71,7 +71,7 @@ void __init iq80321_map_io(void) * IQ80321 PCI. */ static int __init -iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +iq80321_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 626aa37..1a374ea 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -78,7 +78,7 @@ void __init n2100_map_io(void) * N2100 PCI. */ static int __init -n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-iop33x/include/mach/hardware.h b/arch/arm/mach-iop33x/include/mach/hardware.h index 8c10e43..8392853 100644 --- a/arch/arm/mach-iop33x/include/mach/hardware.h +++ b/arch/arm/mach-iop33x/include/mach/hardware.h @@ -18,9 +18,6 @@ * but when we read them, we convert them to virtual addresses. See * arch/arm/mach-iop3xx/iop3xx-pci.c */ -#define pcibios_assign_all_busses() 1 -#define PCIBIOS_MIN_IO 0x00000000 -#define PCIBIOS_MIN_MEM 0x00000000 #ifndef __ASSEMBLY__ void iop33x_init_irq(void); diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index c565f8d..637c027 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -54,7 +54,7 @@ static struct sys_timer iq80331_timer = { * IQ80331 PCI. */ static int __init -iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +iq80331_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 36a9efb..90a0436 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -54,7 +54,7 @@ static struct sys_timer iq80332_timer = { * IQ80332 PCI. */ static int __init -iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +iq80332_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 88663ab..62c60ad 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -148,7 +148,8 @@ static struct pci_bus * __init enp2611_pci_scan_bus(int nr, return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys); } -static int __init enp2611_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-ixp2000/include/mach/hardware.h b/arch/arm/mach-ixp2000/include/mach/hardware.h index f033de4..cdaf1db 100644 --- a/arch/arm/mach-ixp2000/include/mach/hardware.h +++ b/arch/arm/mach-ixp2000/include/mach/hardware.h @@ -19,16 +19,8 @@ #ifndef __ASM_ARCH_HARDWARE_H__ #define __ASM_ARCH_HARDWARE_H__ -/* - * This needs to be platform-specific? - */ -#define PCIBIOS_MIN_IO 0x00000000 -#define PCIBIOS_MIN_MEM 0x00000000 - #include "ixp2000-regs.h" /* Chipset Registers */ -#define pcibios_assign_all_busses() 0 - /* * Platform helper functions */ diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index dfffc1e..5bad1a8 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -78,7 +78,8 @@ int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) return 1; } -static int __init ixdp2400_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdp2400_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { if (ixdp2x00_master_npu()) { diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index cd4c9bc..3d3cef8 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -161,7 +161,8 @@ static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) return 1; } -static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdp2800_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { if (ixdp2x00_master_npu()) { diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 84835b2..be2a254 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -252,7 +252,8 @@ void __init ixdp2x01_pci_preinit(void) #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) -static int __init ixdp2x01_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdp2x01_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { u8 bus = dev->bus->number; u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index f797c5f..f5098b3 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -196,6 +196,11 @@ clear_master_aborts(void) void __init ixp2000_pci_preinit(void) { + pci_set_flags(0); + + pcibios_min_io = 0; + pcibios_min_mem = 0; + #ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO /* * Configure the PCI unit to properly byteswap I/O transactions, diff --git a/arch/arm/mach-ixp23xx/include/mach/hardware.h b/arch/arm/mach-ixp23xx/include/mach/hardware.h index 57b508b..60e55fa 100644 --- a/arch/arm/mach-ixp23xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp23xx/include/mach/hardware.h @@ -15,13 +15,9 @@ #define __ASM_ARCH_HARDWARE_H /* PCI IO info */ -#define PCIBIOS_MIN_IO 0x00000000 -#define PCIBIOS_MIN_MEM 0xe0000000 #include "ixp23xx.h" -#define pcibios_assign_all_busses() 0 - /* * Platform helper functions */ diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index 8dcba17..ec028e3 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -168,7 +168,7 @@ void __init ixdp2351_init_irq(void) */ #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) -static int __init ixdp2351_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdp2351_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u8 bus = dev->bus->number; u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 563819a..e6be571 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -227,6 +227,11 @@ static void __init ixp23xx_pci_common_init(void) void __init ixp23xx_pci_preinit(void) { + pcibios_min_io = 0; + pcibios_min_mem = 0xe0000000; + + pci_set_flags(0); + ixp23xx_pci_common_init(); hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0, diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index 8fe0c62..844551d 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -56,7 +56,8 @@ #define INTC_PIN IXP23XX_GPIO_PIN_11 #define INTD_PIN IXP23XX_GPIO_PIN_12 -static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +static int __init roadrunner_map_irq(const struct pci_dev *dev, u8 idsel, + u8 pin) { static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA}; static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD}; diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c index 162043f..8fea0a3 100644 --- a/arch/arm/mach-ixp4xx/avila-pci.c +++ b/arch/arm/mach-ixp4xx/avila-pci.c @@ -46,7 +46,7 @@ void __init avila_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init avila_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[IRQ_LINES] = { IXP4XX_GPIO_IRQ(INTA), diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e2e98bb..2131832 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -346,6 +346,11 @@ void __init ixp4xx_pci_preinit(void) { unsigned long cpuid = read_cpuid_id(); +#ifdef CONFIG_IXP4XX_INDIRECT_PCI + pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */ +#else + pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */ +#endif /* * Determine which PCI read method to use. * Rev 0 IXP425 requires workaround. diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c index 37fda7d..71f5c9c 100644 --- a/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/arch/arm/mach-ixp4xx/coyote-pci.c @@ -37,7 +37,7 @@ void __init coyote_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init coyote_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == SLOT0_DEVID) return IXP4XX_GPIO_IRQ(SLOT0_INTA); diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c index c761201..0532510 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -44,7 +44,7 @@ void __init dsmg600_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init dsmg600_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[MAX_DEV][IRQ_LINES] = { { IXP4XX_GPIO_IRQ(INTE), -1, -1 }, diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c index 44ccde9..d2ac803 100644 --- a/arch/arm/mach-ixp4xx/fsg-pci.c +++ b/arch/arm/mach-ixp4xx/fsg-pci.c @@ -38,7 +38,7 @@ void __init fsg_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init fsg_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[IRQ_LINES] = { IXP4XX_GPIO_IRQ(INTC), diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c index fc11241..76581fb 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-pci.c +++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c @@ -35,7 +35,8 @@ void __init gateway7001_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { if (slot == 1) return IRQ_IXP4XX_GPIO11; diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index 5f00ad2..7548d9a 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -462,7 +462,7 @@ static void __init gmlr_pci_postinit(void) } } -static int __init gmlr_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch(slot) { case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA); diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c index 38cc072..d68fc06 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -49,7 +49,7 @@ void __init gtwx5715_pci_preinit(void) } -static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init gtwx5715_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int rc = -1; diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index 8138371..c30e7e9 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h @@ -17,19 +17,14 @@ #ifndef __ASM_ARCH_HARDWARE_H__ #define __ASM_ARCH_HARDWARE_H__ -#define PCIBIOS_MIN_IO 0x00001000 #ifdef CONFIG_IXP4XX_INDIRECT_PCI -#define PCIBIOS_MIN_MEM 0x10000000 /* 1 GB of indirect PCI MMIO space */ #define PCIBIOS_MAX_MEM 0x4FFFFFFF #else -#define PCIBIOS_MIN_MEM 0x48000000 /* 64 MB of PCI MMIO space */ #define PCIBIOS_MAX_MEM 0x4BFFFFFF #endif #define ARCH_HAS_DMA_SET_COHERENT_MASK -#define pcibios_assign_all_busses() 1 - /* Register locations and bits */ #include "ixp4xx-regs.h" diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c index 58f4004..fffd8c5 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -43,7 +43,7 @@ void __init ixdp425_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdp425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[IRQ_LINES] = { IXP4XX_GPIO_IRQ(INTA), diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c index e64f6d0..34efe75 100644 --- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -31,7 +31,7 @@ void __init ixdpg425_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init ixdpg425_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init ixdpg425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 12 || slot == 13) return IRQ_IXP4XX_GPIO7; diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c index 428d120..5434ccf 100644 --- a/arch/arm/mach-ixp4xx/nas100d-pci.c +++ b/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -41,7 +41,7 @@ void __init nas100d_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init nas100d_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[MAX_DEV][IRQ_LINES] = { { IXP4XX_GPIO_IRQ(INTA), -1, -1 }, diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c index 2e85f76..b571605 100644 --- a/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -38,7 +38,7 @@ void __init nslu2_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init nslu2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { static int pci_irq_table[IRQ_LINES] = { IXP4XX_GPIO_IRQ(INTA), diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c index 03bdec5..0bc3f34 100644 --- a/arch/arm/mach-ixp4xx/vulcan-pci.c +++ b/arch/arm/mach-ixp4xx/vulcan-pci.c @@ -43,7 +43,7 @@ void __init vulcan_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init vulcan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init vulcan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 1) return IXP4XX_GPIO_IRQ(INTA); diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c index 17f3cf5..f27dfcf 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-pci.c +++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c @@ -35,7 +35,7 @@ void __init wg302v2_pci_preinit(void) ixp4xx_pci_preinit(); } -static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init wg302v2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 1) return IRQ_IXP4XX_GPIO8; diff --git a/arch/arm/mach-kirkwood/include/mach/hardware.h b/arch/arm/mach-kirkwood/include/mach/hardware.h index cde8528..742b74f 100644 --- a/arch/arm/mach-kirkwood/include/mach/hardware.h +++ b/arch/arm/mach-kirkwood/include/mach/hardware.h @@ -11,11 +11,4 @@ #include "kirkwood.h" -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x00001000 -#define PCIBIOS_MIN_MEM 0x01000000 -#define PCIMEM_BASE KIRKWOOD_PCIE_MEM_PHYS_BASE /* mem base for VGA */ - - #endif diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index ca294ff..74b992d 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -12,6 +12,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/mbus.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> #include <plat/pcie.h> @@ -244,7 +245,8 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys) return bus; } -static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init kirkwood_pcie_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { struct pcie_port *pp = bus_to_port(dev->bus); @@ -271,6 +273,8 @@ static void __init add_pcie_port(int index, unsigned long base) void __init kirkwood_pcie_init(unsigned int portmask) { + vga_base = KIRKWOOD_PCIE_MEM_PHYS_BASE; + if (portmask & KW_PCIE0) add_pcie_port(0, PCIE_VIRT_BASE); diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c index ada92b6..1338cb3 100644 --- a/arch/arm/mach-ks8695/board-dsm320.c +++ b/arch/arm/mach-ks8695/board-dsm320.c @@ -34,7 +34,7 @@ #include "generic.h" #ifdef CONFIG_PCI -static int dsm320_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int dsm320_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 0: diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c index c7ad09b..e2e3cba 100644 --- a/arch/arm/mach-ks8695/board-micrel.c +++ b/arch/arm/mach-ks8695/board-micrel.c @@ -24,7 +24,7 @@ #include "generic.h" #ifdef CONFIG_PCI -static int micrel_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int micrel_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return KS8695_IRQ_EXTERN0; } diff --git a/arch/arm/mach-ks8695/include/mach/devices.h b/arch/arm/mach-ks8695/include/mach/devices.h index 2744fec..85a3c9a 100644 --- a/arch/arm/mach-ks8695/include/mach/devices.h +++ b/arch/arm/mach-ks8695/include/mach/devices.h @@ -30,7 +30,7 @@ extern void __init ks8695_init_leds(u8 cpu_led, u8 timer_led); struct ks8695_pci_cfg { short mode; - int (*map_irq)(struct pci_dev *, u8, u8); + int (*map_irq)(const struct pci_dev *, u8, u8); }; extern __init void ks8695_init_pci(struct ks8695_pci_cfg *); diff --git a/arch/arm/mach-ks8695/include/mach/hardware.h b/arch/arm/mach-ks8695/include/mach/hardware.h index e0f911d..5e0c388 100644 --- a/arch/arm/mach-ks8695/include/mach/hardware.h +++ b/arch/arm/mach-ks8695/include/mach/hardware.h @@ -42,13 +42,4 @@ #define KS8695_PCIIO_PA 0x80000000 #define KS8695_PCIIO_SIZE SZ_64K - -/* - * PCI support - */ -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0 -#define PCIBIOS_MIN_MEM 0 - #endif diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index 5fcd082..c7c9a18 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -317,6 +317,9 @@ void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg) return; } + pcibios_min_io = 0; + pcibios_min_mem = 0; + printk(KERN_INFO "PCI: Initialising\n"); ks8695_show_pciregs(); diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index da0e649..1e02751 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -1077,7 +1077,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0) _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1) - _REGISTER_CLOCK("lpc32xx-ts", NULL, clk_tsc) + _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc) _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc) _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c index ee24dc2..205b2db 100644 --- a/arch/arm/mach-lpc32xx/common.c +++ b/arch/arm/mach-lpc32xx/common.c @@ -95,6 +95,48 @@ struct platform_device lpc32xx_i2c2_device = { }, }; +/* TSC (Touch Screen Controller) */ + +static struct resource lpc32xx_tsc_resources[] = { + { + .start = LPC32XX_ADC_BASE, + .end = LPC32XX_ADC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LPC32XX_TS_IRQ, + .end = IRQ_LPC32XX_TS_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device lpc32xx_tsc_device = { + .name = "ts-lpc32xx", + .id = -1, + .num_resources = ARRAY_SIZE(lpc32xx_tsc_resources), + .resource = lpc32xx_tsc_resources, +}; + +/* RTC */ + +static struct resource lpc32xx_rtc_resources[] = { + { + .start = LPC32XX_RTC_BASE, + .end = LPC32XX_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + },{ + .start = IRQ_LPC32XX_RTC, + .end = IRQ_LPC32XX_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device lpc32xx_rtc_device = { + .name = "rtc-lpc32xx", + .id = -1, + .num_resources = ARRAY_SIZE(lpc32xx_rtc_resources), + .resource = lpc32xx_rtc_resources, +}; + /* * Returns the unique ID for the device */ diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h index f82211f..5583f52 100644 --- a/arch/arm/mach-lpc32xx/common.h +++ b/arch/arm/mach-lpc32xx/common.h @@ -28,6 +28,8 @@ extern struct platform_device lpc32xx_watchdog_device; extern struct platform_device lpc32xx_i2c0_device; extern struct platform_device lpc32xx_i2c1_device; extern struct platform_device lpc32xx_i2c2_device; +extern struct platform_device lpc32xx_tsc_device; +extern struct platform_device lpc32xx_rtc_device; /* * Other arch specific structures and functions diff --git a/arch/arm/mach-lpc32xx/include/mach/clkdev.h b/arch/arm/mach-lpc32xx/include/mach/clkdev.h deleted file mode 100644 index 9bf0637..0000000 --- a/arch/arm/mach-lpc32xx/include/mach/clkdev.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/include/mach/clkdev.h - * - * Author: Kevin Wells <kevin.wells@nxp.com> - * - * Copyright (C) 2010 NXP Semiconductors - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_CLKDEV_H -#define __ASM_ARCH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 67793a6..56ef5f6 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -77,6 +77,13 @@ config MACH_TETON_BGA Say 'Y' here if you want to support the Marvell PXA168-based Teton BGA Development Board. +config MACH_SHEEVAD + bool "Marvell's PXA168 GuruPlug Display (gplugD) Board" + select CPU_PXA168 + help + Say 'Y' here if you want to support the Marvell PXA168-based + GuruPlug Display (gplugD) Board + endmenu config CPU_PXA168 diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 5c68382..b0ac942 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o +obj-$(CONFIG_MACH_SHEEVAD) += gplugd.o diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c index 886e056..7c6f95f 100644 --- a/arch/arm/mach-mmp/clock.c +++ b/arch/arm/mach-mmp/clock.c @@ -88,3 +88,18 @@ unsigned long clk_get_rate(struct clk *clk) return rate; } EXPORT_SYMBOL(clk_get_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + int ret = -EINVAL; + + if (clk->ops->setrate) { + spin_lock_irqsave(&clocks_lock, flags); + ret = clk->ops->setrate(clk, rate); + spin_unlock_irqrestore(&clocks_lock, flags); + } + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h index 9b027d7..3143e99 100644 --- a/arch/arm/mach-mmp/clock.h +++ b/arch/arm/mach-mmp/clock.h @@ -12,6 +12,7 @@ struct clkops { void (*enable)(struct clk *); void (*disable)(struct clk *); unsigned long (*getrate)(struct clk *); + int (*setrate)(struct clk *, unsigned long); }; struct clk { diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c new file mode 100644 index 0000000..98e25d9 --- /dev/null +++ b/arch/arm/mach-mmp/gplugd.c @@ -0,0 +1,197 @@ +/* + * linux/arch/arm/mach-mmp/gplugd.c + * + * Support for the Marvell PXA168-based GuruPlug Display (gplugD) Platform. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/init.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include <mach/gpio.h> +#include <mach/pxa168.h> +#include <mach/mfp-pxa168.h> + +#include "common.h" + +static unsigned long gplugd_pin_config[] __initdata = { + /* UART3 */ + GPIO8_UART3_TXD, + GPIO9_UART3_RXD, + GPIO1O_UART3_CTS, + GPIO11_UART3_RTS, + + /* USB OTG PEN */ + GPIO18_GPIO, + + /* MMC2 */ + GPIO28_MMC2_CMD, + GPIO29_MMC2_CLK, + GPIO30_MMC2_DAT0, + GPIO31_MMC2_DAT1, + GPIO32_MMC2_DAT2, + GPIO33_MMC2_DAT3, + + /* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */ + GPIO35_GPIO, + GPIO36_GPIO, /* CEC Interrupt */ + + /* MMC1 */ + GPIO43_MMC1_CLK, + GPIO49_MMC1_CMD, + GPIO41_MMC1_DAT0, + GPIO40_MMC1_DAT1, + GPIO52_MMC1_DAT2, + GPIO51_MMC1_DAT3, + GPIO53_MMC1_CD, + + /* LCD */ + GPIO56_LCD_FCLK_RD, + GPIO57_LCD_LCLK_A0, + GPIO58_LCD_PCLK_WR, + GPIO59_LCD_DENA_BIAS, + GPIO60_LCD_DD0, + GPIO61_LCD_DD1, + GPIO62_LCD_DD2, + GPIO63_LCD_DD3, + GPIO64_LCD_DD4, + GPIO65_LCD_DD5, + GPIO66_LCD_DD6, + GPIO67_LCD_DD7, + GPIO68_LCD_DD8, + GPIO69_LCD_DD9, + GPIO70_LCD_DD10, + GPIO71_LCD_DD11, + GPIO72_LCD_DD12, + GPIO73_LCD_DD13, + GPIO74_LCD_DD14, + GPIO75_LCD_DD15, + GPIO76_LCD_DD16, + GPIO77_LCD_DD17, + GPIO78_LCD_DD18, + GPIO79_LCD_DD19, + GPIO80_LCD_DD20, + GPIO81_LCD_DD21, + GPIO82_LCD_DD22, + GPIO83_LCD_DD23, + + /* GPIO */ + GPIO84_GPIO, + GPIO85_GPIO, + + /* Fast-Ethernet*/ + GPIO86_TX_CLK, + GPIO87_TX_EN, + GPIO88_TX_DQ3, + GPIO89_TX_DQ2, + GPIO90_TX_DQ1, + GPIO91_TX_DQ0, + GPIO92_MII_CRS, + GPIO93_MII_COL, + GPIO94_RX_CLK, + GPIO95_RX_ER, + GPIO96_RX_DQ3, + GPIO97_RX_DQ2, + GPIO98_RX_DQ1, + GPIO99_RX_DQ0, + GPIO100_MII_MDC, + GPIO101_MII_MDIO, + GPIO103_RX_DV, + GPIO104_GPIO, /* Reset PHY */ + + /* RTC interrupt */ + GPIO102_GPIO, + + /* I2C */ + GPIO105_CI2C_SDA, + GPIO106_CI2C_SCL, + + /* SPI NOR Flash on SSP2 */ + GPIO107_SSP2_RXD, + GPIO108_SSP2_TXD, + GPIO110_GPIO, /* SPI_CSn */ + GPIO111_SSP2_CLK, + + /* Select JTAG */ + GPIO109_GPIO, + + /* I2S */ + GPIO114_I2S_FRM, + GPIO115_I2S_BCLK, + GPIO116_I2S_TXD +}; + +static struct i2c_board_info gplugd_i2c_board_info[] = { + { + .type = "isl1208", + .addr = 0x6F, + } +}; + +/* Bring PHY out of reset by setting GPIO 104 */ +static int gplugd_eth_init(void) +{ + if (unlikely(gpio_request(104, "ETH_RESET_N"))) { + printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet " + "PHY out of reset\n"); + return -EIO; + } + + gpio_direction_output(104, 1); + gpio_free(104); + return 0; +} + +struct pxa168_eth_platform_data gplugd_eth_platform_data = { + .port_number = 0, + .phy_addr = 0, + .speed = 0, /* Autonagotiation */ + .init = gplugd_eth_init, +}; + +static void __init select_disp_freq(void) +{ + /* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */ + if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) { + printk(KERN_ERR "Can't get hold of GPIO 35 to select display " + "frequency\n"); + } else { + gpio_direction_output(35, 1); + gpio_free(35); + } + + if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) { + printk(KERN_ERR "Can't get hold of GPIO 85 to select display " + "frequency\n"); + } else { + gpio_direction_output(85, 0); + gpio_free(85); + } +} + +static void __init gplugd_init(void) +{ + mfp_config(ARRAY_AND_SIZE(gplugd_pin_config)); + + select_disp_freq(); + + /* on-chip devices */ + pxa168_add_uart(3); + pxa168_add_ssp(0); + pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info)); + + pxa168_add_eth(&gplugd_eth_platform_data); +} + +MACHINE_START(SHEEVAD, "PXA168-based GuruPlug Display (gplugD) Platform") + .map_io = mmp_map_io, + .nr_irqs = IRQ_BOARD_START, + .init_irq = pxa168_init_irq, + .timer = &pxa168_timer, + .init_machine = gplugd_init, +MACHINE_END diff --git a/arch/arm/mach-mmp/include/mach/clkdev.h b/arch/arm/mach-mmp/include/mach/clkdev.h deleted file mode 100644 index 2fb354e..0000000 --- a/arch/arm/mach-mmp/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif /* __ASM_MACH_CLKDEV_H */ diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index 713be15..92aaa3c 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -203,6 +203,10 @@ #define GPIO33_CF_nCD2 MFP_CFG(GPIO33, AF3) /* UART */ +#define GPIO8_UART3_TXD MFP_CFG(GPIO8, AF2) +#define GPIO9_UART3_RXD MFP_CFG(GPIO9, AF2) +#define GPIO1O_UART3_CTS MFP_CFG(GPIO10, AF2) +#define GPIO11_UART3_RTS MFP_CFG(GPIO11, AF2) #define GPIO88_UART2_TXD MFP_CFG(GPIO88, AF2) #define GPIO89_UART2_RXD MFP_CFG(GPIO89, AF2) #define GPIO107_UART1_TXD MFP_CFG_DRV(GPIO107, AF1, FAST) @@ -232,6 +236,22 @@ #define GPIO53_MMC1_CD MFP_CFG(GPIO53, AF1) #define GPIO46_MMC1_WP MFP_CFG(GPIO46, AF1) +/* MMC2 */ +#define GPIO28_MMC2_CMD MFP_CFG_DRV(GPIO28, AF6, FAST) +#define GPIO29_MMC2_CLK MFP_CFG_DRV(GPIO29, AF6, FAST) +#define GPIO30_MMC2_DAT0 MFP_CFG_DRV(GPIO30, AF6, FAST) +#define GPIO31_MMC2_DAT1 MFP_CFG_DRV(GPIO31, AF6, FAST) +#define GPIO32_MMC2_DAT2 MFP_CFG_DRV(GPIO32, AF6, FAST) +#define GPIO33_MMC2_DAT3 MFP_CFG_DRV(GPIO33, AF6, FAST) + +/* MMC4 */ +#define GPIO125_MMC4_DAT3 MFP_CFG_DRV(GPIO125, AF7, FAST) +#define GPIO126_MMC4_DAT2 MFP_CFG_DRV(GPIO126, AF7, FAST) +#define GPIO127_MMC4_DAT1 MFP_CFG_DRV(GPIO127, AF7, FAST) +#define GPIO0_2_MMC4_DAT0 MFP_CFG_DRV(GPIO0_2, AF7, FAST) +#define GPIO1_2_MMC4_CMD MFP_CFG_DRV(GPIO1_2, AF7, FAST) +#define GPIO2_2_MMC4_CLK MFP_CFG_DRV(GPIO2_2, AF7, FAST) + /* LCD */ #define GPIO84_LCD_CS MFP_CFG(GPIO84, AF1) #define GPIO60_LCD_DD0 MFP_CFG(GPIO60, AF1) @@ -269,11 +289,12 @@ #define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1) /* I2S */ -#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6) -#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1) -#define GPIO115_I2S_BCLK MFP_CFG(GPIO115,AF1) -#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2) -#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2) +#define GPIO113_I2S_MCLK MFP_CFG(GPIO113, AF6) +#define GPIO114_I2S_FRM MFP_CFG(GPIO114, AF1) +#define GPIO115_I2S_BCLK MFP_CFG(GPIO115, AF1) +#define GPIO116_I2S_RXD MFP_CFG(GPIO116, AF2) +#define GPIO116_I2S_TXD MFP_CFG(GPIO116, AF1) +#define GPIO117_I2S_TXD MFP_CFG(GPIO117, AF2) /* PWM */ #define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1) @@ -305,4 +326,29 @@ #define GPIO112_KP_MKOUT6 MFP_CFG(GPIO112, AF7) #define GPIO121_KP_MKIN4 MFP_CFG(GPIO121, AF7) +/* Fast Ethernet */ +#define GPIO86_TX_CLK MFP_CFG(GPIO86, AF5) +#define GPIO87_TX_EN MFP_CFG(GPIO87, AF5) +#define GPIO88_TX_DQ3 MFP_CFG(GPIO88, AF5) +#define GPIO89_TX_DQ2 MFP_CFG(GPIO89, AF5) +#define GPIO90_TX_DQ1 MFP_CFG(GPIO90, AF5) +#define GPIO91_TX_DQ0 MFP_CFG(GPIO91, AF5) +#define GPIO92_MII_CRS MFP_CFG(GPIO92, AF5) +#define GPIO93_MII_COL MFP_CFG(GPIO93, AF5) +#define GPIO94_RX_CLK MFP_CFG(GPIO94, AF5) +#define GPIO95_RX_ER MFP_CFG(GPIO95, AF5) +#define GPIO96_RX_DQ3 MFP_CFG(GPIO96, AF5) +#define GPIO97_RX_DQ2 MFP_CFG(GPIO97, AF5) +#define GPIO98_RX_DQ1 MFP_CFG(GPIO98, AF5) +#define GPIO99_RX_DQ0 MFP_CFG(GPIO99, AF5) +#define GPIO100_MII_MDC MFP_CFG(GPIO100, AF5) +#define GPIO101_MII_MDIO MFP_CFG(GPIO101, AF5) +#define GPIO103_RX_DV MFP_CFG(GPIO103, AF5) + +/* SSP2 */ +#define GPIO107_SSP2_RXD MFP_CFG(GPIO107, AF4) +#define GPIO108_SSP2_TXD MFP_CFG(GPIO108, AF4) +#define GPIO111_SSP2_CLK MFP_CFG(GPIO111, AF4) +#define GPIO112_SSP2_FRM MFP_CFG(GPIO112, AF4) + #endif /* __ASM_MACH_MFP_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index a52b3d2..7f00584 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -14,9 +14,11 @@ extern void pxa168_clear_keypad_wakeup(void); #include <video/pxa168fb.h> #include <plat/pxa27x_keypad.h> #include <mach/cputype.h> +#include <linux/pxa168_eth.h> extern struct pxa_device_desc pxa168_device_uart1; extern struct pxa_device_desc pxa168_device_uart2; +extern struct pxa_device_desc pxa168_device_uart3; extern struct pxa_device_desc pxa168_device_twsi0; extern struct pxa_device_desc pxa168_device_twsi1; extern struct pxa_device_desc pxa168_device_pwm1; @@ -31,6 +33,7 @@ extern struct pxa_device_desc pxa168_device_ssp5; extern struct pxa_device_desc pxa168_device_nand; extern struct pxa_device_desc pxa168_device_fb; extern struct pxa_device_desc pxa168_device_keypad; +extern struct pxa_device_desc pxa168_device_eth; static inline int pxa168_add_uart(int id) { @@ -39,6 +42,7 @@ static inline int pxa168_add_uart(int id) switch (id) { case 1: d = &pxa168_device_uart1; break; case 2: d = &pxa168_device_uart2; break; + case 3: d = &pxa168_device_uart3; break; } if (d == NULL) @@ -117,4 +121,8 @@ static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data) return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data)); } +static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data) +{ + return pxa_register_device(&pxa168_device_eth, data, sizeof(*data)); +} #endif /* __ASM_MACH_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h index f7011ef..8447ac6 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apmu.h +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h @@ -29,6 +29,7 @@ #define APMU_BUS APMU_REG(0x06c) #define APMU_SDH2 APMU_REG(0x0e8) #define APMU_SDH3 APMU_REG(0x0ec) +#define APMU_ETH APMU_REG(0x0fc) #define APMU_FNCLK_EN (1 << 4) #define APMU_AXICLK_EN (1 << 3) diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index ab9f999..0156f53 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -66,6 +66,7 @@ void __init pxa168_init_irq(void) /* APB peripheral clocks */ static APBC_CLK(uart1, PXA168_UART1, 1, 14745600); static APBC_CLK(uart2, PXA168_UART2, 1, 14745600); +static APBC_CLK(uart3, PXA168_UART3, 1, 14745600); static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000); static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000); static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000); @@ -81,11 +82,13 @@ static APBC_CLK(keypad, PXA168_KPC, 0, 32000); static APMU_CLK(nand, NAND, 0x19b, 156000000); static APMU_CLK(lcd, LCD, 0x7f, 312000000); +static APMU_CLK(eth, ETH, 0x09, 0); /* device and clock bindings */ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), + INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL), INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL), INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL), INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL), @@ -100,6 +103,7 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), + INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), }; static int __init pxa168_init(void) @@ -149,6 +153,7 @@ void pxa168_clear_keypad_wakeup(void) /* on-chip devices */ PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22); PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24); +PXA168_DEVICE(uart3, "pxa2xx-uart", 2, UART3, 0xd4026000, 0x30, 23, 24); PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28); PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28); PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10); @@ -163,3 +168,4 @@ PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59); PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61); PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8); PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); +PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff); diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 99833b9..4e91ee6 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -51,12 +51,12 @@ static inline uint32_t timer_read(void) { int delay = 100; - __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0)); + __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1)); while (delay--) cpu_relax(); - return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); + return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); } unsigned long long notrace sched_clock(void) @@ -75,28 +75,51 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) { struct clock_event_device *c = dev_id; - /* disable and clear pending interrupt status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); - __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0)); + /* + * Clear pending interrupt status. + */ + __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); + + /* + * Disable timer 0. + */ + __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + c->event_handler(c); + return IRQ_HANDLED; } static int timer_set_next_event(unsigned long delta, struct clock_event_device *dev) { - unsigned long flags, next; + unsigned long flags; local_irq_save(flags); - /* clear pending interrupt status and enable */ + /* + * Disable timer 0. + */ + __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); + + /* + * Clear and enable timer match 0 interrupt. + */ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); - next = timer_read() + delta; - __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); + /* + * Setup new clockevent timer value. + */ + __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); + + /* + * Enable timer 0. + */ + __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER); local_irq_restore(flags); + return 0; } @@ -145,23 +168,26 @@ static struct clocksource cksrc = { static void __init timer_config(void) { uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); - uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER); - uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR); - __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ + __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */ - ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3); + ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : + (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); - /* free-running mode */ - __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR); + /* set timer 0 to periodic mode, and timer 1 to free-running mode */ + __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */ + __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */ __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); - /* enable timer counter */ - __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER); + __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */ + __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ + __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); + + /* enable timer 1 counter */ + __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER); } static struct irqaction timer_irq = { diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index e411039..6bd37a2 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -15,6 +15,8 @@ #include <linux/mtd/partitions.h> #include <linux/mtd/onenand.h> #include <linux/interrupt.h> +#include <linux/i2c/pca953x.h> +#include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -25,7 +27,17 @@ #include "common.h" -#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 24) +#define TTCDKB_GPIO_EXT0(x) (NR_BUILTIN_GPIO + ((x < 0) ? 0 : \ + ((x < 16) ? x : 15))) +#define TTCDKB_GPIO_EXT1(x) (NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \ + ((x < 16) ? x : 15))) + +/* + * 16 board interrupts -- MAX7312 GPIO expander + * 16 board interrupts -- PCA9575 GPIO expander + * 24 board interrupts -- 88PM860x PMIC + */ +#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 16 + 16 + 24) static unsigned long ttc_dkb_pin_config[] __initdata = { /* UART2 */ @@ -113,6 +125,22 @@ static struct platform_device *ttc_dkb_devices[] = { &ttc_dkb_device_onenand, }; +static struct pca953x_platform_data max7312_data[] = { + { + .gpio_base = TTCDKB_GPIO_EXT0(0), + .irq_base = IRQ_BOARD_START, + }, +}; + +static struct i2c_board_info ttc_dkb_i2c_info[] = { + { + .type = "max7312", + .addr = 0x23, + .irq = IRQ_GPIO(80), + .platform_data = &max7312_data, + }, +}; + static void __init ttc_dkb_init(void) { mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config)); @@ -121,6 +149,7 @@ static void __init ttc_dkb_init(void) pxa910_add_uart(1); /* off-chip devices */ + pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info)); platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices)); } diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 888e925..ebde97f 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -11,6 +11,7 @@ config ARCH_MSM7X00A select MSM_SMD select MSM_SMD_PKG3 select CPU_V6 + select GPIO_MSM_V1 select MSM_PROC_COMM select HAS_MSM_DEBUG_UART_PHYS @@ -22,6 +23,7 @@ config ARCH_MSM7X30 select MSM_VIC select CPU_V7 select MSM_GPIOMUX + select GPIO_MSM_V1 select MSM_PROC_COMM select HAS_MSM_DEBUG_UART_PHYS @@ -33,6 +35,7 @@ config ARCH_QSD8X50 select MSM_VIC select CPU_V7 select MSM_GPIOMUX + select GPIO_MSM_V1 select MSM_PROC_COMM select HAS_MSM_DEBUG_UART_PHYS @@ -44,6 +47,7 @@ config ARCH_MSM8X60 select ARM_GIC select CPU_V7 select MSM_V2_TLMM + select GPIO_MSM_V2 select MSM_GPIOMUX select MSM_SCM if SMP diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index b70658c..4285dfd 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -29,11 +29,3 @@ obj-$(CONFIG_ARCH_MSM8960) += board-msm8960.o devices-msm8960.o obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o -ifdef CONFIG_MSM_V2_TLMM -ifndef CONFIG_ARCH_MSM8960 -# TODO: TLMM Mapping issues need to be resolved -obj-y += gpio-v2.o -endif -else -obj-y += gpio.o -endif diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c deleted file mode 100644 index cc9c4fd..0000000 --- a/arch/arm/mach-msm/gpio-v2.c +++ /dev/null @@ -1,433 +0,0 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#define pr_fmt(fmt) "%s: " fmt, __func__ - -#include <linux/bitmap.h> -#include <linux/bitops.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> - -#include <asm/mach/irq.h> - -#include <mach/msm_iomap.h> -#include "gpiomux.h" - -/* Bits of interest in the GPIO_IN_OUT register. - */ -enum { - GPIO_IN = 0, - GPIO_OUT = 1 -}; - -/* Bits of interest in the GPIO_INTR_STATUS register. - */ -enum { - INTR_STATUS = 0, -}; - -/* Bits of interest in the GPIO_CFG register. - */ -enum { - GPIO_OE = 9, -}; - -/* Bits of interest in the GPIO_INTR_CFG register. - * When a GPIO triggers, two separate decisions are made, controlled - * by two separate flags. - * - * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS - * register for that GPIO will be updated to reflect the triggering of that - * gpio. If this bit is 0, this register will not be updated. - * - Second, INTR_ENABLE controls whether an interrupt is triggered. - * - * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt - * can be triggered but the status register will not reflect it. - */ -enum { - INTR_ENABLE = 0, - INTR_POL_CTL = 1, - INTR_DECT_CTL = 2, - INTR_RAW_STATUS_EN = 3, -}; - -/* Codes of interest in GPIO_INTR_CFG_SU. - */ -enum { - TARGET_PROC_SCORPION = 4, - TARGET_PROC_NONE = 7, -}; - - -#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio))) -#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio))) -#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio))) -#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio))) -#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio))) - -/** - * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure - * - * @enabled_irqs: a bitmap used to optimize the summary-irq handler. By - * keeping track of which gpios are unmasked as irq sources, we avoid - * having to do readl calls on hundreds of iomapped registers each time - * the summary interrupt fires in order to locate the active interrupts. - * - * @wake_irqs: a bitmap for tracking which interrupt lines are enabled - * as wakeup sources. When the device is suspended, interrupts which are - * not wakeup sources are disabled. - * - * @dual_edge_irqs: a bitmap used to track which irqs are configured - * as dual-edge, as this is not supported by the hardware and requires - * some special handling in the driver. - */ -struct msm_gpio_dev { - struct gpio_chip gpio_chip; - DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS); - DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS); - DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS); -}; - -static DEFINE_SPINLOCK(tlmm_lock); - -static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip) -{ - return container_of(chip, struct msm_gpio_dev, gpio_chip); -} - -static inline void set_gpio_bits(unsigned n, void __iomem *reg) -{ - writel(readl(reg) | n, reg); -} - -static inline void clear_gpio_bits(unsigned n, void __iomem *reg) -{ - writel(readl(reg) & ~n, reg); -} - -static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN); -} - -static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val) -{ - writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset)); -} - -static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&tlmm_lock, irq_flags); - clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset)); - spin_unlock_irqrestore(&tlmm_lock, irq_flags); - return 0; -} - -static int msm_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, - int val) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&tlmm_lock, irq_flags); - msm_gpio_set(chip, offset, val); - set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset)); - spin_unlock_irqrestore(&tlmm_lock, irq_flags); - return 0; -} - -static int msm_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - return msm_gpiomux_get(chip->base + offset); -} - -static void msm_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - msm_gpiomux_put(chip->base + offset); -} - -static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - return MSM_GPIO_TO_INT(chip->base + offset); -} - -static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq) -{ - return irq - MSM_GPIO_TO_INT(chip->base); -} - -static struct msm_gpio_dev msm_gpio = { - .gpio_chip = { - .base = 0, - .ngpio = NR_GPIO_IRQS, - .direction_input = msm_gpio_direction_input, - .direction_output = msm_gpio_direction_output, - .get = msm_gpio_get, - .set = msm_gpio_set, - .to_irq = msm_gpio_to_irq, - .request = msm_gpio_request, - .free = msm_gpio_free, - }, -}; - -/* For dual-edge interrupts in software, since the hardware has no - * such support: - * - * At appropriate moments, this function may be called to flip the polarity - * settings of both-edge irq lines to try and catch the next edge. - * - * The attempt is considered successful if: - * - the status bit goes high, indicating that an edge was caught, or - * - the input value of the gpio doesn't change during the attempt. - * If the value changes twice during the process, that would cause the first - * test to fail but would force the second, as two opposite - * transitions would cause a detection no matter the polarity setting. - * - * The do-loop tries to sledge-hammer closed the timing hole between - * the initial value-read and the polarity-write - if the line value changes - * during that window, an interrupt is lost, the new polarity setting is - * incorrect, and the first success test will fail, causing a retry. - * - * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c. - */ -static void msm_gpio_update_dual_edge_pos(unsigned gpio) -{ - int loop_limit = 100; - unsigned val, val2, intstat; - - do { - val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN); - if (val) - clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio)); - else - set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio)); - val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN); - intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS); - if (intstat || val == val2) - return; - } while (loop_limit-- > 0); - pr_err("dual-edge irq failed to stabilize, " - "interrupts dropped. %#08x != %#08x\n", - val, val2); -} - -static void msm_gpio_irq_ack(struct irq_data *d) -{ - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); - - writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio)); - if (test_bit(gpio, msm_gpio.dual_edge_irqs)) - msm_gpio_update_dual_edge_pos(gpio); -} - -static void msm_gpio_irq_mask(struct irq_data *d) -{ - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); - unsigned long irq_flags; - - spin_lock_irqsave(&tlmm_lock, irq_flags); - writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); - clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); - __clear_bit(gpio, msm_gpio.enabled_irqs); - spin_unlock_irqrestore(&tlmm_lock, irq_flags); -} - -static void msm_gpio_irq_unmask(struct irq_data *d) -{ - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); - unsigned long irq_flags; - - spin_lock_irqsave(&tlmm_lock, irq_flags); - __set_bit(gpio, msm_gpio.enabled_irqs); - set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); - writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio)); - spin_unlock_irqrestore(&tlmm_lock, irq_flags); -} - -static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) -{ - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); - unsigned long irq_flags; - uint32_t bits; - - spin_lock_irqsave(&tlmm_lock, irq_flags); - - bits = readl(GPIO_INTR_CFG(gpio)); - - if (flow_type & IRQ_TYPE_EDGE_BOTH) { - bits |= BIT(INTR_DECT_CTL); - __irq_set_handler_locked(d->irq, handle_edge_irq); - if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) - __set_bit(gpio, msm_gpio.dual_edge_irqs); - else - __clear_bit(gpio, msm_gpio.dual_edge_irqs); - } else { - bits &= ~BIT(INTR_DECT_CTL); - __irq_set_handler_locked(d->irq, handle_level_irq); - __clear_bit(gpio, msm_gpio.dual_edge_irqs); - } - - if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) - bits |= BIT(INTR_POL_CTL); - else - bits &= ~BIT(INTR_POL_CTL); - - writel(bits, GPIO_INTR_CFG(gpio)); - - if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) - msm_gpio_update_dual_edge_pos(gpio); - - spin_unlock_irqrestore(&tlmm_lock, irq_flags); - - return 0; -} - -/* - * When the summary IRQ is raised, any number of GPIO lines may be high. - * It is the job of the summary handler to find all those GPIO lines - * which have been set as summary IRQ lines and which are triggered, - * and to call their interrupt handlers. - */ -static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - unsigned long i; - struct irq_chip *chip = irq_desc_get_chip(desc); - - chained_irq_enter(chip, desc); - - for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS); - i < NR_GPIO_IRQS; - i = find_next_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS, i + 1)) { - if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS)) - generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip, - i)); - } - - chained_irq_exit(chip, desc); -} - -static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) -{ - int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq); - - if (on) { - if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) - irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1); - set_bit(gpio, msm_gpio.wake_irqs); - } else { - clear_bit(gpio, msm_gpio.wake_irqs); - if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) - irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0); - } - - return 0; -} - -static struct irq_chip msm_gpio_irq_chip = { - .name = "msmgpio", - .irq_mask = msm_gpio_irq_mask, - .irq_unmask = msm_gpio_irq_unmask, - .irq_ack = msm_gpio_irq_ack, - .irq_set_type = msm_gpio_irq_set_type, - .irq_set_wake = msm_gpio_irq_set_wake, -}; - -static int __devinit msm_gpio_probe(struct platform_device *dev) -{ - int i, irq, ret; - - bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS); - bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS); - bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS); - msm_gpio.gpio_chip.label = dev->name; - ret = gpiochip_add(&msm_gpio.gpio_chip); - if (ret < 0) - return ret; - - for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) { - irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i); - irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, - handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - - irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ, - msm_summary_irq_handler); - return 0; -} - -static int __devexit msm_gpio_remove(struct platform_device *dev) -{ - int ret = gpiochip_remove(&msm_gpio.gpio_chip); - - if (ret < 0) - return ret; - - irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL); - - return 0; -} - -static struct platform_driver msm_gpio_driver = { - .probe = msm_gpio_probe, - .remove = __devexit_p(msm_gpio_remove), - .driver = { - .name = "msmgpio", - .owner = THIS_MODULE, - }, -}; - -static struct platform_device msm_device_gpio = { - .name = "msmgpio", - .id = -1, -}; - -static int __init msm_gpio_init(void) -{ - int rc; - - rc = platform_driver_register(&msm_gpio_driver); - if (!rc) { - rc = platform_device_register(&msm_device_gpio); - if (rc) - platform_driver_unregister(&msm_gpio_driver); - } - - return rc; -} - -static void __exit msm_gpio_exit(void) -{ - platform_device_unregister(&msm_device_gpio); - platform_driver_unregister(&msm_gpio_driver); -} - -postcore_initcall(msm_gpio_init); -module_exit(msm_gpio_exit); - -MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>"); -MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:msmgpio"); diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c deleted file mode 100644 index 5ea273b..0000000 --- a/arch/arm/mach-msm/gpio.c +++ /dev/null @@ -1,376 +0,0 @@ -/* linux/arch/arm/mach-msm/gpio.c - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/bitops.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/module.h> -#include "gpio_hw.h" -#include "gpiomux.h" - -#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0) - -#define MSM_GPIO_BANK(bank, first, last) \ - { \ - .regs = { \ - .out = MSM_GPIO_OUT_##bank, \ - .in = MSM_GPIO_IN_##bank, \ - .int_status = MSM_GPIO_INT_STATUS_##bank, \ - .int_clear = MSM_GPIO_INT_CLEAR_##bank, \ - .int_en = MSM_GPIO_INT_EN_##bank, \ - .int_edge = MSM_GPIO_INT_EDGE_##bank, \ - .int_pos = MSM_GPIO_INT_POS_##bank, \ - .oe = MSM_GPIO_OE_##bank, \ - }, \ - .chip = { \ - .base = (first), \ - .ngpio = (last) - (first) + 1, \ - .get = msm_gpio_get, \ - .set = msm_gpio_set, \ - .direction_input = msm_gpio_direction_input, \ - .direction_output = msm_gpio_direction_output, \ - .to_irq = msm_gpio_to_irq, \ - .request = msm_gpio_request, \ - .free = msm_gpio_free, \ - } \ - } - -#define MSM_GPIO_BROKEN_INT_CLEAR 1 - -struct msm_gpio_regs { - void __iomem *out; - void __iomem *in; - void __iomem *int_status; - void __iomem *int_clear; - void __iomem *int_en; - void __iomem *int_edge; - void __iomem *int_pos; - void __iomem *oe; -}; - -struct msm_gpio_chip { - spinlock_t lock; - struct gpio_chip chip; - struct msm_gpio_regs regs; -#if MSM_GPIO_BROKEN_INT_CLEAR - unsigned int_status_copy; -#endif - unsigned int both_edge_detect; - unsigned int int_enable[2]; /* 0: awake, 1: sleep */ -}; - -static int msm_gpio_write(struct msm_gpio_chip *msm_chip, - unsigned offset, unsigned on) -{ - unsigned mask = BIT(offset); - unsigned val; - - val = readl(msm_chip->regs.out); - if (on) - writel(val | mask, msm_chip->regs.out); - else - writel(val & ~mask, msm_chip->regs.out); - return 0; -} - -static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip) -{ - int loop_limit = 100; - unsigned pol, val, val2, intstat; - do { - val = readl(msm_chip->regs.in); - pol = readl(msm_chip->regs.int_pos); - pol = (pol & ~msm_chip->both_edge_detect) | - (~val & msm_chip->both_edge_detect); - writel(pol, msm_chip->regs.int_pos); - intstat = readl(msm_chip->regs.int_status); - val2 = readl(msm_chip->regs.in); - if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0) - return; - } while (loop_limit-- > 0); - printk(KERN_ERR "msm_gpio_update_both_edge_detect, " - "failed to reach stable state %x != %x\n", val, val2); -} - -static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip, - unsigned offset) -{ - unsigned bit = BIT(offset); - -#if MSM_GPIO_BROKEN_INT_CLEAR - /* Save interrupts that already triggered before we loose them. */ - /* Any interrupt that triggers between the read of int_status */ - /* and the write to int_clear will still be lost though. */ - msm_chip->int_status_copy |= readl(msm_chip->regs.int_status); - msm_chip->int_status_copy &= ~bit; -#endif - writel(bit, msm_chip->regs.int_clear); - msm_gpio_update_both_edge_detect(msm_chip); - return 0; -} - -static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct msm_gpio_chip *msm_chip; - unsigned long irq_flags; - - msm_chip = container_of(chip, struct msm_gpio_chip, chip); - spin_lock_irqsave(&msm_chip->lock, irq_flags); - writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); - return 0; -} - -static int -msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) -{ - struct msm_gpio_chip *msm_chip; - unsigned long irq_flags; - - msm_chip = container_of(chip, struct msm_gpio_chip, chip); - spin_lock_irqsave(&msm_chip->lock, irq_flags); - msm_gpio_write(msm_chip, offset, value); - writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); - return 0; -} - -static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct msm_gpio_chip *msm_chip; - - msm_chip = container_of(chip, struct msm_gpio_chip, chip); - return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0; -} - -static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct msm_gpio_chip *msm_chip; - unsigned long irq_flags; - - msm_chip = container_of(chip, struct msm_gpio_chip, chip); - spin_lock_irqsave(&msm_chip->lock, irq_flags); - msm_gpio_write(msm_chip, offset, value); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); -} - -static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - return MSM_GPIO_TO_INT(chip->base + offset); -} - -#ifdef CONFIG_MSM_GPIOMUX -static int msm_gpio_request(struct gpio_chip *chip, unsigned offset) -{ - return msm_gpiomux_get(chip->base + offset); -} - -static void msm_gpio_free(struct gpio_chip *chip, unsigned offset) -{ - msm_gpiomux_put(chip->base + offset); -} -#else -#define msm_gpio_request NULL -#define msm_gpio_free NULL -#endif - -struct msm_gpio_chip msm_gpio_chips[] = { -#if defined(CONFIG_ARCH_MSM7X00A) - MSM_GPIO_BANK(0, 0, 15), - MSM_GPIO_BANK(1, 16, 42), - MSM_GPIO_BANK(2, 43, 67), - MSM_GPIO_BANK(3, 68, 94), - MSM_GPIO_BANK(4, 95, 106), - MSM_GPIO_BANK(5, 107, 121), -#elif defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X27) - MSM_GPIO_BANK(0, 0, 15), - MSM_GPIO_BANK(1, 16, 42), - MSM_GPIO_BANK(2, 43, 67), - MSM_GPIO_BANK(3, 68, 94), - MSM_GPIO_BANK(4, 95, 106), - MSM_GPIO_BANK(5, 107, 132), -#elif defined(CONFIG_ARCH_MSM7X30) - MSM_GPIO_BANK(0, 0, 15), - MSM_GPIO_BANK(1, 16, 43), - MSM_GPIO_BANK(2, 44, 67), - MSM_GPIO_BANK(3, 68, 94), - MSM_GPIO_BANK(4, 95, 106), - MSM_GPIO_BANK(5, 107, 133), - MSM_GPIO_BANK(6, 134, 150), - MSM_GPIO_BANK(7, 151, 181), -#elif defined(CONFIG_ARCH_QSD8X50) - MSM_GPIO_BANK(0, 0, 15), - MSM_GPIO_BANK(1, 16, 42), - MSM_GPIO_BANK(2, 43, 67), - MSM_GPIO_BANK(3, 68, 94), - MSM_GPIO_BANK(4, 95, 103), - MSM_GPIO_BANK(5, 104, 121), - MSM_GPIO_BANK(6, 122, 152), - MSM_GPIO_BANK(7, 153, 164), -#endif -}; - -static void msm_gpio_irq_ack(struct irq_data *d) -{ - unsigned long irq_flags; - struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d); - spin_lock_irqsave(&msm_chip->lock, irq_flags); - msm_gpio_clear_detect_status(msm_chip, - d->irq - gpio_to_irq(msm_chip->chip.base)); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); -} - -static void msm_gpio_irq_mask(struct irq_data *d) -{ - unsigned long irq_flags; - struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d); - unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base); - - spin_lock_irqsave(&msm_chip->lock, irq_flags); - /* level triggered interrupts are also latched */ - if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) - msm_gpio_clear_detect_status(msm_chip, offset); - msm_chip->int_enable[0] &= ~BIT(offset); - writel(msm_chip->int_enable[0], msm_chip->regs.int_en); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); -} - -static void msm_gpio_irq_unmask(struct irq_data *d) -{ - unsigned long irq_flags; - struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d); - unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base); - - spin_lock_irqsave(&msm_chip->lock, irq_flags); - /* level triggered interrupts are also latched */ - if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) - msm_gpio_clear_detect_status(msm_chip, offset); - msm_chip->int_enable[0] |= BIT(offset); - writel(msm_chip->int_enable[0], msm_chip->regs.int_en); - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); -} - -static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) -{ - unsigned long irq_flags; - struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d); - unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base); - - spin_lock_irqsave(&msm_chip->lock, irq_flags); - - if (on) - msm_chip->int_enable[1] |= BIT(offset); - else - msm_chip->int_enable[1] &= ~BIT(offset); - - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); - return 0; -} - -static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) -{ - unsigned long irq_flags; - struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d); - unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base); - unsigned val, mask = BIT(offset); - - spin_lock_irqsave(&msm_chip->lock, irq_flags); - val = readl(msm_chip->regs.int_edge); - if (flow_type & IRQ_TYPE_EDGE_BOTH) { - writel(val | mask, msm_chip->regs.int_edge); - __irq_set_handler_locked(d->irq, handle_edge_irq); - } else { - writel(val & ~mask, msm_chip->regs.int_edge); - __irq_set_handler_locked(d->irq, handle_level_irq); - } - if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { - msm_chip->both_edge_detect |= mask; - msm_gpio_update_both_edge_detect(msm_chip); - } else { - msm_chip->both_edge_detect &= ~mask; - val = readl(msm_chip->regs.int_pos); - if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) - writel(val | mask, msm_chip->regs.int_pos); - else - writel(val & ~mask, msm_chip->regs.int_pos); - } - spin_unlock_irqrestore(&msm_chip->lock, irq_flags); - return 0; -} - -static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - int i, j, mask; - unsigned val; - - for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { - struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i]; - val = readl(msm_chip->regs.int_status); - val &= msm_chip->int_enable[0]; - while (val) { - mask = val & -val; - j = fls(mask) - 1; - /* printk("%s %08x %08x bit %d gpio %d irq %d\n", - __func__, v, m, j, msm_chip->chip.start + j, - FIRST_GPIO_IRQ + msm_chip->chip.start + j); */ - val &= ~mask; - generic_handle_irq(FIRST_GPIO_IRQ + - msm_chip->chip.base + j); - } - } - desc->irq_data.chip->irq_ack(&desc->irq_data); -} - -static struct irq_chip msm_gpio_irq_chip = { - .name = "msmgpio", - .irq_ack = msm_gpio_irq_ack, - .irq_mask = msm_gpio_irq_mask, - .irq_unmask = msm_gpio_irq_unmask, - .irq_set_wake = msm_gpio_irq_set_wake, - .irq_set_type = msm_gpio_irq_set_type, -}; - -static int __init msm_init_gpio(void) -{ - int i, j = 0; - - for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) { - if (i - FIRST_GPIO_IRQ >= - msm_gpio_chips[j].chip.base + - msm_gpio_chips[j].chip.ngpio) - j++; - irq_set_chip_data(i, &msm_gpio_chips[j]); - irq_set_chip_and_handler(i, &msm_gpio_irq_chip, - handle_edge_irq); - set_irq_flags(i, IRQF_VALID); - } - - for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { - spin_lock_init(&msm_gpio_chips[i].lock); - writel(0, msm_gpio_chips[i].regs.int_en); - gpiochip_add(&msm_gpio_chips[i].chip); - } - - irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); - irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); - irq_set_irq_wake(INT_GPIO_GROUP1, 1); - irq_set_irq_wake(INT_GPIO_GROUP2, 2); - return 0; -} - -postcore_initcall(msm_init_gpio); diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h deleted file mode 100644 index 6b50660..0000000 --- a/arch/arm/mach-msm/gpio_hw.h +++ /dev/null @@ -1,278 +0,0 @@ -/* arch/arm/mach-msm/gpio_hw.h - * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland <swetland@google.com> - * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H -#define __ARCH_ARM_MACH_MSM_GPIO_HW_H - -#include <mach/msm_iomap.h> - -/* see 80-VA736-2 Rev C pp 695-751 -** -** These are actually the *shadow* gpio registers, since the -** real ones (which allow full access) are only available to the -** ARM9 side of the world. -** -** Since the _BASE need to be page-aligned when we're mapping them -** to virtual addresses, adjust for the additional offset in these -** macros. -*/ - -#if defined(CONFIG_ARCH_MSM7X30) -#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off)) -#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off)) -#else -#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) -#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) -#endif - -#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X25) ||\ - defined(CONFIG_ARCH_MSM7X27) - -/* output value */ -#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ -#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */ -#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */ -#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ -#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */ -#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 107-121 */ - -/* same pin map as above, output enable */ -#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10) -#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) -#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14) -#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18) -#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C) -#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54) - -/* same pin map as above, input read */ -#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34) -#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) -#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38) -#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C) -#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40) -#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44) - -/* same pin map as above, 1=edge 0=level interrup */ -#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60) -#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) -#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64) -#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68) -#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C) -#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0) - -/* same pin map as above, 1=positive 0=negative */ -#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70) -#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) -#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74) -#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78) -#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C) -#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC) - -/* same pin map as above, interrupt enable */ -#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80) -#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) -#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84) -#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88) -#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C) -#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8) - -/* same pin map as above, write 1 to clear interrupt */ -#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90) -#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) -#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94) -#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98) -#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C) -#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4) - -/* same pin map as above, 1=interrupt pending */ -#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0) -#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) -#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4) -#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8) -#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC) -#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0) - -#endif - -#if defined(CONFIG_ARCH_QSD8X50) -/* output value */ -#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ -#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */ -#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */ -#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ -#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 103-95 */ -#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x10) /* gpio 121-104 */ -#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0x14) /* gpio 152-122 */ -#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x18) /* gpio 164-153 */ - -/* same pin map as above, output enable */ -#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x20) -#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) -#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x24) -#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x28) -#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x2C) -#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x30) -#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0x34) -#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x38) - -/* same pin map as above, input read */ -#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x50) -#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) -#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x54) -#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x58) -#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x5C) -#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x60) -#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0x64) -#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x68) - -/* same pin map as above, 1=edge 0=level interrup */ -#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x70) -#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) -#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x74) -#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x78) -#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x7C) -#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0x80) -#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0x84) -#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x88) - -/* same pin map as above, 1=positive 0=negative */ -#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x90) -#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) -#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x94) -#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x98) -#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x9C) -#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xA0) -#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xA4) -#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0xA8) - -/* same pin map as above, interrupt enable */ -#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0xB0) -#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) -#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0xB4) -#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0xB8) -#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0xBC) -#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xC0) -#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xC4) -#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0xC8) - -/* same pin map as above, write 1 to clear interrupt */ -#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0xD0) -#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) -#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0xD4) -#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0xD8) -#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0xDC) -#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xE0) -#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xE4) -#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0xE8) - -/* same pin map as above, 1=interrupt pending */ -#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xF0) -#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) -#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xF4) -#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xF8) -#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xFC) -#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0x100) -#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0x104) -#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x108) - -#endif - -#if defined(CONFIG_ARCH_MSM7X30) - -/* output value */ -#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ -#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 43-16 */ -#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-44 */ -#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ -#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */ -#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 133-107 */ -#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0xC4) /* gpio 150-134 */ -#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x214) /* gpio 181-151 */ - -/* same pin map as above, output enable */ -#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10) -#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) -#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14) -#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18) -#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C) -#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54) -#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0xC8) -#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x218) - -/* same pin map as above, input read */ -#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34) -#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) -#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38) -#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C) -#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40) -#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44) -#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0xCC) -#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x21C) - -/* same pin map as above, 1=edge 0=level interrup */ -#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60) -#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) -#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64) -#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68) -#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C) -#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0) -#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0xD0) -#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x240) - -/* same pin map as above, 1=positive 0=negative */ -#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70) -#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) -#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74) -#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78) -#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C) -#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC) -#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xD4) -#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0x228) - -/* same pin map as above, interrupt enable */ -#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80) -#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) -#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84) -#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88) -#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C) -#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8) -#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xD8) -#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0x22C) - -/* same pin map as above, write 1 to clear interrupt */ -#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90) -#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) -#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94) -#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98) -#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C) -#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4) -#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xDC) -#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0x230) - -/* same pin map as above, 1=interrupt pending */ -#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0) -#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) -#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4) -#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8) -#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC) -#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0) -#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0xE0) -#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x234) - -#endif - -#endif diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h index b178d9c..00459f6 100644 --- a/arch/arm/mach-msm/gpiomux.h +++ b/arch/arm/mach-msm/gpiomux.h @@ -19,6 +19,7 @@ #include <linux/bitops.h> #include <linux/errno.h> +#include <mach/msm_gpiomux.h> #if defined(CONFIG_MSM_V2_TLMM) #include "gpiomux-v2.h" @@ -71,12 +72,6 @@ enum { */ extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS]; -/* Increment a gpio's reference count, possibly activating the line. */ -int __must_check msm_gpiomux_get(unsigned gpio); - -/* Decrement a gpio's reference count, possibly suspending the line. */ -int msm_gpiomux_put(unsigned gpio); - /* Install a new configuration to the gpio line. To avoid overwriting * a configuration, leave the VALID bit out. */ @@ -94,16 +89,6 @@ int msm_gpiomux_write(unsigned gpio, */ void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val); #else -static inline int __must_check msm_gpiomux_get(unsigned gpio) -{ - return -ENOSYS; -} - -static inline int msm_gpiomux_put(unsigned gpio) -{ - return -ENOSYS; -} - static inline int msm_gpiomux_write(unsigned gpio, gpiomux_config_t active, gpiomux_config_t suspended) diff --git a/arch/arm/mach-msm/include/mach/clkdev.h b/arch/arm/mach-msm/include/mach/msm_gpiomux.h index f87a57b..0c7d393 100644 --- a/arch/arm/mach-msm/include/mach/clkdev.h +++ b/arch/arm/mach-msm/include/mach/msm_gpiomux.h @@ -9,11 +9,30 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#ifndef __ASM_ARCH_MSM_CLKDEV_H -#define __ASM_ARCH_MSM_CLKDEV_H -struct clk; +#ifndef _LINUX_MSM_GPIOMUX_H +#define _LINUX_MSM_GPIOMUX_H + +#ifdef CONFIG_MSM_GPIOMUX + +/* Increment a gpio's reference count, possibly activating the line. */ +int __must_check msm_gpiomux_get(unsigned gpio); + +/* Decrement a gpio's reference count, possibly suspending the line. */ +int msm_gpiomux_put(unsigned gpio); + +#else + +static inline int __must_check msm_gpiomux_get(unsigned gpio) +{ + return -ENOSYS; +} + +static inline int msm_gpiomux_put(unsigned gpio) +{ + return -ENOSYS; +} -static inline int __clk_get(struct clk *clk) { return 1; } -static inline void __clk_put(struct clk *clk) { } #endif + +#endif /* _LINUX_MSM_GPIOMUX_H */ diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h index 8f99d97..94fe9fe 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -55,13 +55,11 @@ #define MSM_DMOV_PHYS 0xA9700000 #define MSM_DMOV_SIZE SZ_4K -#define MSM_GPIO1_BASE IOMEM(0xE0003000) -#define MSM_GPIO1_PHYS 0xA9200000 -#define MSM_GPIO1_SIZE SZ_4K +#define MSM7X00_GPIO1_PHYS 0xA9200000 +#define MSM7X00_GPIO1_SIZE SZ_4K -#define MSM_GPIO2_BASE IOMEM(0xE0004000) -#define MSM_GPIO2_PHYS 0xA9300000 -#define MSM_GPIO2_SIZE SZ_4K +#define MSM7X00_GPIO2_PHYS 0xA9300000 +#define MSM7X00_GPIO2_SIZE SZ_4K #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) #define MSM_CLK_CTL_PHYS 0xA8600000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h index 4d84be1..3769444 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -46,13 +46,11 @@ #define MSM_DMOV_PHYS 0xAC400000 #define MSM_DMOV_SIZE SZ_4K -#define MSM_GPIO1_BASE IOMEM(0xE0003000) -#define MSM_GPIO1_PHYS 0xAC001000 -#define MSM_GPIO1_SIZE SZ_4K +#define MSM7X30_GPIO1_PHYS 0xAC001000 +#define MSM7X30_GPIO1_SIZE SZ_4K -#define MSM_GPIO2_BASE IOMEM(0xE0004000) -#define MSM_GPIO2_PHYS 0xAC101000 -#define MSM_GPIO2_SIZE SZ_4K +#define MSM7X30_GPIO2_PHYS 0xAC101000 +#define MSM7X30_GPIO2_SIZE SZ_4K #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) #define MSM_CLK_CTL_PHYS 0xAB800000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h index d414320..d67cd73 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -46,13 +46,11 @@ #define MSM_DMOV_PHYS 0xA9700000 #define MSM_DMOV_SIZE SZ_4K -#define MSM_GPIO1_BASE IOMEM(0xE0003000) -#define MSM_GPIO1_PHYS 0xA9000000 -#define MSM_GPIO1_SIZE SZ_4K +#define QSD8X50_GPIO1_PHYS 0xA9000000 +#define QSD8X50_GPIO1_SIZE SZ_4K -#define MSM_GPIO2_BASE IOMEM(0xE0004000) -#define MSM_GPIO2_PHYS 0xA9100000 -#define MSM_GPIO2_SIZE SZ_4K +#define QSD8X50_GPIO2_PHYS 0xA9100000 +#define QSD8X50_GPIO2_SIZE SZ_4K #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) #define MSM_CLK_CTL_PHYS 0xA8600000 diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 2f494b6..4ded152 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -61,5 +61,7 @@ #define MSM_QGIC_CPU_BASE IOMEM(0xF0001000) #define MSM_TMR_BASE IOMEM(0xF0200000) #define MSM_TMR0_BASE IOMEM(0xF0201000) +#define MSM_GPIO1_BASE IOMEM(0xE0003000) +#define MSM_GPIO2_BASE IOMEM(0xE0004000) #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index cec6ed1..140ddbb 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -43,8 +43,8 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, MSM7X00), MSM_DEVICE(DMOV), - MSM_DEVICE(GPIO1), - MSM_DEVICE(GPIO2), + MSM_CHIP_DEVICE(GPIO1, MSM7X00), + MSM_CHIP_DEVICE(GPIO2, MSM7X00), MSM_DEVICE(CLK_CTL), #ifdef CONFIG_MSM_DEBUG_UART MSM_DEVICE(DEBUG_UART), @@ -76,8 +76,8 @@ static struct map_desc qsd8x50_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, QSD8X50), MSM_DEVICE(DMOV), - MSM_DEVICE(GPIO1), - MSM_DEVICE(GPIO2), + MSM_CHIP_DEVICE(GPIO1, QSD8X50), + MSM_CHIP_DEVICE(GPIO2, QSD8X50), MSM_DEVICE(CLK_CTL), MSM_DEVICE(SIRC), MSM_DEVICE(SCPLL), @@ -135,8 +135,8 @@ static struct map_desc msm7x30_io_desc[] __initdata = { MSM_DEVICE(VIC), MSM_CHIP_DEVICE(CSR, MSM7X30), MSM_DEVICE(DMOV), - MSM_DEVICE(GPIO1), - MSM_DEVICE(GPIO2), + MSM_CHIP_DEVICE(GPIO1, MSM7X30), + MSM_CHIP_DEVICE(GPIO2, MSM7X30), MSM_DEVICE(CLK_CTL), MSM_DEVICE(CLK_CTL_SH2), MSM_DEVICE(AD5), diff --git a/arch/arm/mach-mv78xx0/include/mach/hardware.h b/arch/arm/mach-mv78xx0/include/mach/hardware.h index 5d88755..67cab0a 100644 --- a/arch/arm/mach-mv78xx0/include/mach/hardware.h +++ b/arch/arm/mach-mv78xx0/include/mach/hardware.h @@ -11,11 +11,4 @@ #include "mv78xx0.h" -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x00001000 -#define PCIBIOS_MIN_MEM 0x01000000 -#define PCIMEM_BASE MV78XX0_PCIE_MEM_PHYS_BASE /* mem base for VGA */ - - #endif diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index f27c7d2..c51af1c 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/mbus.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> #include <plat/pcie.h> @@ -259,7 +260,8 @@ mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) return bus; } -static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { struct pcie_port *pp = bus_to_port(dev->bus->number); @@ -297,6 +299,8 @@ static void __init add_pcie_port(int maj, int min, unsigned long base) void __init mv78xx0_pcie_init(int init_port0, int init_port1) { + vga_base = MV78XX0_PCIE_MEM_PHYS_BASE; + if (init_port0) { add_pcie_port(0, 0, PCIE00_VIRT_BASE); if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) { diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index f25e9d7..b4e7c58 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -180,6 +180,7 @@ config MACH_MX53_EVK select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX select IMX_HAVE_PLATFORM_SPI_IMX + select LEDS_GPIO_REGISTER help Include support for MX53 EVK platform. This includes specific configurations for the board and its peripherals. @@ -203,10 +204,23 @@ config MACH_MX53_LOCO select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX select IMX_HAVE_PLATFORM_GPIO_KEYS + select LEDS_GPIO_REGISTER help Include support for MX53 LOCO platform. This includes specific configurations for the board and its peripherals. +config MACH_MX53_ARD + bool "Support MX53 ARD platforms" + select SOC_IMX53 + select IMX_HAVE_PLATFORM_IMX2_WDT + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_GPIO_KEYS + help + Include support for MX53 ARD platform. This includes specific + configurations for the board and its peripherals. + endif # ARCH_MX53_SUPPORTED endif diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 0b9338c..383e7cd 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -6,12 +6,14 @@ obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o obj-$(CONFIG_SOC_IMX50) += mm-mx50.o +obj-$(CONFIG_PM) += pm-imx5.o obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o obj-$(CONFIG_MACH_MX53_SMD) += board-mx53_smd.o obj-$(CONFIG_MACH_MX53_LOCO) += board-mx53_loco.o +obj-$(CONFIG_MACH_MX53_ARD) += board-mx53_ard.o obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c index 7c893fa..68934ea 100644 --- a/arch/arm/mach-mx5/board-cpuimx51.c +++ b/arch/arm/mach-mx5/board-cpuimx51.c @@ -81,7 +81,7 @@ static struct plat_serial8250_port serial_platform_data[] = { .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, }, { .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000), - .irq = irq_to_gpio(CPUIMX51_QUARTD_GPIO), + .irq = gpio_to_irq(CPUIMX51_QUARTD_GPIO), .irqflags = IRQF_TRIGGER_HIGH, .uartclk = CPUIMX51_QUART_XTAL, .regshift = CPUIMX51_QUART_REGSHIFT, diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index e54e4bf..11b0ff6 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -41,6 +41,8 @@ #define BABBAGE_POWER_KEY IMX_GPIO_NR(2, 21) #define BABBAGE_ECSPI1_CS0 IMX_GPIO_NR(4, 24) #define BABBAGE_ECSPI1_CS1 IMX_GPIO_NR(4, 25) +#define BABBAGE_SD2_CD IMX_GPIO_NR(1, 6) +#define BABBAGE_SD2_WP IMX_GPIO_NR(1, 5) /* USB_CTRL_1 */ #define MX51_USB_CTRL_1_OFFSET 0x10 @@ -142,6 +144,9 @@ static iomux_v3_cfg_t mx51babbage_pads[] = { MX51_PAD_SD1_DATA1__SD1_DATA1, MX51_PAD_SD1_DATA2__SD1_DATA2, MX51_PAD_SD1_DATA3__SD1_DATA3, + /* CD/WP from controller */ + MX51_PAD_GPIO1_0__SD1_CD, + MX51_PAD_GPIO1_1__SD1_WP, /* SD 2 */ MX51_PAD_SD2_CMD__SD2_CMD, @@ -150,6 +155,9 @@ static iomux_v3_cfg_t mx51babbage_pads[] = { MX51_PAD_SD2_DATA1__SD2_DATA1, MX51_PAD_SD2_DATA2__SD2_DATA2, MX51_PAD_SD2_DATA3__SD2_DATA3, + /* CD/WP gpio */ + MX51_PAD_GPIO1_6__GPIO1_6, + MX51_PAD_GPIO1_5__GPIO1_5, /* eCSPI1 */ MX51_PAD_CSPI1_MISO__ECSPI1_MISO, @@ -331,6 +339,18 @@ static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = { .num_chipselect = ARRAY_SIZE(mx51_babbage_spi_cs), }; +static const struct esdhc_platform_data mx51_babbage_sd1_data __initconst = { + .cd_type = ESDHC_CD_CONTROLLER, + .wp_type = ESDHC_WP_CONTROLLER, +}; + +static const struct esdhc_platform_data mx51_babbage_sd2_data __initconst = { + .cd_gpio = BABBAGE_SD2_CD, + .wp_gpio = BABBAGE_SD2_WP, + .cd_type = ESDHC_CD_GPIO, + .wp_type = ESDHC_WP_GPIO, +}; + /* * Board specific initialization. */ @@ -349,7 +369,7 @@ static void __init mx51_babbage_init(void) ARRAY_SIZE(mx51babbage_pads)); imx51_add_imx_uart(0, &uart_pdata); - imx51_add_imx_uart(1, &uart_pdata); + imx51_add_imx_uart(1, NULL); imx51_add_imx_uart(2, &uart_pdata); babbage_fec_reset(); @@ -376,8 +396,8 @@ static void __init mx51_babbage_init(void) mxc_iomux_v3_setup_pad(usbh1stp); babbage_usbhub_reset(); - imx51_add_sdhci_esdhc_imx(0, NULL); - imx51_add_sdhci_esdhc_imx(1, NULL); + imx51_add_sdhci_esdhc_imx(0, &mx51_babbage_sd1_data); + imx51_add_sdhci_esdhc_imx(1, &mx51_babbage_sd2_data); spi_register_board_info(mx51_babbage_spi_board_info, ARRAY_SIZE(mx51_babbage_spi_board_info)); diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c index f70700d..551daf8 100644 --- a/arch/arm/mach-mx5/board-mx51_efikamx.c +++ b/arch/arm/mach-mx5/board-mx51_efikamx.c @@ -108,9 +108,9 @@ static void __init mx51_efikamx_board_id(void) gpio_request(EFIKAMX_PCBID2, "pcbid2"); gpio_direction_input(EFIKAMX_PCBID2); - id = gpio_get_value(EFIKAMX_PCBID0); - id |= gpio_get_value(EFIKAMX_PCBID1) << 1; - id |= gpio_get_value(EFIKAMX_PCBID2) << 2; + id = gpio_get_value(EFIKAMX_PCBID0) ? 1 : 0; + id |= (gpio_get_value(EFIKAMX_PCBID1) ? 1 : 0) << 1; + id |= (gpio_get_value(EFIKAMX_PCBID2) ? 1 : 0) << 2; switch (id) { case 7: diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c index 2e4d9d3..8a9bca2 100644 --- a/arch/arm/mach-mx5/board-mx51_efikasb.c +++ b/arch/arm/mach-mx5/board-mx51_efikasb.c @@ -156,23 +156,24 @@ static struct gpio_keys_button mx51_efikasb_keys[] = { { .code = KEY_POWER, .gpio = EFIKASB_PWRKEY, - .type = EV_PWR, + .type = EV_KEY, .desc = "Power Button", .wakeup = 1, - .debounce_interval = 10, /* ms */ + .active_low = 1, }, { .code = SW_LID, .gpio = EFIKASB_LID, .type = EV_SW, .desc = "Lid Switch", + .active_low = 1, }, { - /* SW_RFKILLALL vs KEY_RFKILL ? */ - .code = SW_RFKILL_ALL, + .code = KEY_RFKILL, .gpio = EFIKASB_RFKILL, - .type = EV_SW, + .type = EV_KEY, .desc = "rfkill", + .active_low = 1, }, }; @@ -224,8 +225,8 @@ static void __init mx51_efikasb_board_id(void) gpio_request(EFIKASB_PCBID1, "pcb id1"); gpio_direction_input(EFIKASB_PCBID1); - id = gpio_get_value(EFIKASB_PCBID0); - id |= gpio_get_value(EFIKASB_PCBID1) << 1; + id = gpio_get_value(EFIKASB_PCBID0) ? 1 : 0; + id |= (gpio_get_value(EFIKASB_PCBID1) ? 1 : 0) << 1; switch (id) { default: diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c new file mode 100644 index 0000000..76a67c4 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx53_ard.c @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * 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. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/smsc911x.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/iomux-mx53.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "crm_regs.h" +#include "devices-imx53.h" + +#define ARD_ETHERNET_INT_B IMX_GPIO_NR(2, 31) +#define ARD_SD1_CD IMX_GPIO_NR(1, 1) +#define ARD_SD1_WP IMX_GPIO_NR(1, 9) +#define ARD_I2CPORTEXP_B IMX_GPIO_NR(2, 3) +#define ARD_VOLUMEDOWN IMX_GPIO_NR(4, 0) +#define ARD_HOME IMX_GPIO_NR(5, 10) +#define ARD_BACK IMX_GPIO_NR(5, 11) +#define ARD_PROG IMX_GPIO_NR(5, 12) +#define ARD_VOLUMEUP IMX_GPIO_NR(5, 13) + +static iomux_v3_cfg_t mx53_ard_pads[] = { + /* UART1 */ + MX53_PAD_PATA_DIOW__UART1_TXD_MUX, + MX53_PAD_PATA_DMACK__UART1_RXD_MUX, + /* WEIM for CS1 */ + MX53_PAD_EIM_EB3__GPIO2_31, /* ETHERNET_INT_B */ + MX53_PAD_EIM_D16__EMI_WEIM_D_16, + MX53_PAD_EIM_D17__EMI_WEIM_D_17, + MX53_PAD_EIM_D18__EMI_WEIM_D_18, + MX53_PAD_EIM_D19__EMI_WEIM_D_19, + MX53_PAD_EIM_D20__EMI_WEIM_D_20, + MX53_PAD_EIM_D21__EMI_WEIM_D_21, + MX53_PAD_EIM_D22__EMI_WEIM_D_22, + MX53_PAD_EIM_D23__EMI_WEIM_D_23, + MX53_PAD_EIM_D24__EMI_WEIM_D_24, + MX53_PAD_EIM_D25__EMI_WEIM_D_25, + MX53_PAD_EIM_D26__EMI_WEIM_D_26, + MX53_PAD_EIM_D27__EMI_WEIM_D_27, + MX53_PAD_EIM_D28__EMI_WEIM_D_28, + MX53_PAD_EIM_D29__EMI_WEIM_D_29, + MX53_PAD_EIM_D30__EMI_WEIM_D_30, + MX53_PAD_EIM_D31__EMI_WEIM_D_31, + MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0, + MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1, + MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2, + MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3, + MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4, + MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5, + MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6, + MX53_PAD_EIM_OE__EMI_WEIM_OE, + MX53_PAD_EIM_RW__EMI_WEIM_RW, + MX53_PAD_EIM_CS1__EMI_WEIM_CS_1, + /* SDHC1 */ + MX53_PAD_SD1_CMD__ESDHC1_CMD, + MX53_PAD_SD1_CLK__ESDHC1_CLK, + MX53_PAD_SD1_DATA0__ESDHC1_DAT0, + MX53_PAD_SD1_DATA1__ESDHC1_DAT1, + MX53_PAD_SD1_DATA2__ESDHC1_DAT2, + MX53_PAD_SD1_DATA3__ESDHC1_DAT3, + MX53_PAD_PATA_DATA8__ESDHC1_DAT4, + MX53_PAD_PATA_DATA9__ESDHC1_DAT5, + MX53_PAD_PATA_DATA10__ESDHC1_DAT6, + MX53_PAD_PATA_DATA11__ESDHC1_DAT7, + MX53_PAD_GPIO_1__GPIO1_1, + MX53_PAD_GPIO_9__GPIO1_9, + /* I2C2 */ + MX53_PAD_EIM_EB2__I2C2_SCL, + MX53_PAD_KEY_ROW3__I2C2_SDA, + /* I2C3 */ + MX53_PAD_GPIO_3__I2C3_SCL, + MX53_PAD_GPIO_16__I2C3_SDA, + /* GPIO */ + MX53_PAD_DISP0_DAT16__GPIO5_10, /* home */ + MX53_PAD_DISP0_DAT17__GPIO5_11, /* back */ + MX53_PAD_DISP0_DAT18__GPIO5_12, /* prog */ + MX53_PAD_DISP0_DAT19__GPIO5_13, /* vol up */ + MX53_PAD_GPIO_10__GPIO4_0, /* vol down */ +}; + +#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \ +{ \ + .gpio = gpio_num, \ + .type = EV_KEY, \ + .code = ev_code, \ + .active_low = act_low, \ + .desc = "btn " descr, \ + .wakeup = wake, \ +} + +static struct gpio_keys_button ard_buttons[] = { + GPIO_BUTTON(ARD_HOME, KEY_HOME, 1, "home", 0), + GPIO_BUTTON(ARD_BACK, KEY_BACK, 1, "back", 0), + GPIO_BUTTON(ARD_PROG, KEY_PROGRAM, 1, "program", 0), + GPIO_BUTTON(ARD_VOLUMEUP, KEY_VOLUMEUP, 1, "volume-up", 0), + GPIO_BUTTON(ARD_VOLUMEDOWN, KEY_VOLUMEDOWN, 1, "volume-down", 0), +}; + +static const struct gpio_keys_platform_data ard_button_data __initconst = { + .buttons = ard_buttons, + .nbuttons = ARRAY_SIZE(ard_buttons), +}; + +static struct resource ard_smsc911x_resources[] = { + { + .start = MX53_CS1_64MB_BASE_ADDR, + .end = MX53_CS1_64MB_BASE_ADDR + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = gpio_to_irq(ARD_ETHERNET_INT_B), + .end = gpio_to_irq(ARD_ETHERNET_INT_B), + .flags = IORESOURCE_IRQ, + }, +}; + +struct smsc911x_platform_config ard_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_32BIT, +}; + +static struct platform_device ard_smsc_lan9220_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(ard_smsc911x_resources), + .resource = ard_smsc911x_resources, + .dev = { + .platform_data = &ard_smsc911x_config, + }, +}; + +static const struct esdhc_platform_data mx53_ard_sd1_data __initconst = { + .cd_gpio = ARD_SD1_CD, + .wp_gpio = ARD_SD1_WP, +}; + +static struct imxi2c_platform_data mx53_ard_i2c2_data = { + .bitrate = 50000, +}; + +static struct imxi2c_platform_data mx53_ard_i2c3_data = { + .bitrate = 400000, +}; + +static void __init mx53_ard_io_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads, + ARRAY_SIZE(mx53_ard_pads)); + + gpio_request(ARD_ETHERNET_INT_B, "eth-int-b"); + gpio_direction_input(ARD_ETHERNET_INT_B); + + gpio_request(ARD_I2CPORTEXP_B, "i2cptexp-rst"); + gpio_direction_output(ARD_I2CPORTEXP_B, 1); +} + +/* Config CS1 settings for ethernet controller */ +static int weim_cs_config(void) +{ + u32 reg; + void __iomem *weim_base, *iomuxc_base; + + weim_base = ioremap(MX53_WEIM_BASE_ADDR, SZ_4K); + if (!weim_base) + return -ENOMEM; + + iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K); + if (!iomuxc_base) + return -ENOMEM; + + /* CS1 timings for LAN9220 */ + writel(0x20001, (weim_base + 0x18)); + writel(0x0, (weim_base + 0x1C)); + writel(0x16000202, (weim_base + 0x20)); + writel(0x00000002, (weim_base + 0x24)); + writel(0x16002082, (weim_base + 0x28)); + writel(0x00000000, (weim_base + 0x2C)); + writel(0x00000000, (weim_base + 0x90)); + + /* specify 64 MB on CS1 and CS0 on GPR1 */ + reg = readl(iomuxc_base + 0x4); + reg &= ~0x3F; + reg |= 0x1B; + writel(reg, (iomuxc_base + 0x4)); + + iounmap(iomuxc_base); + iounmap(weim_base); + + return 0; +} + +static struct platform_device *devices[] __initdata = { + &ard_smsc_lan9220_device, +}; + +static void __init mx53_ard_board_init(void) +{ + imx53_soc_init(); + imx53_add_imx_uart(0, NULL); + + mx53_ard_io_init(); + weim_cs_config(); + platform_add_devices(devices, ARRAY_SIZE(devices)); + + imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data); + imx53_add_imx2_wdt(0, NULL); + imx53_add_imx_i2c(1, &mx53_ard_i2c2_data); + imx53_add_imx_i2c(2, &mx53_ard_i2c3_data); + imx_add_gpio_keys(&ard_button_data); +} + +static void __init mx53_ard_timer_init(void) +{ + mx53_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mx53_ard_timer = { + .init = mx53_ard_timer_init, +}; + +MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board") + .map_io = mx53_map_io, + .init_early = imx53_init_early, + .init_irq = mx53_init_irq, + .timer = &mx53_ard_timer, + .init_machine = mx53_ard_board_init, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c index 0d9218a..1b417b0 100644 --- a/arch/arm/mach-mx5/board-mx53_evk.c +++ b/arch/arm/mach-mx5/board-mx53_evk.c @@ -35,6 +35,7 @@ #define MX53_EVK_FEC_PHY_RST IMX_GPIO_NR(7, 6) #define EVK_ECSPI1_CS0 IMX_GPIO_NR(2, 30) #define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19) +#define MX53EVK_LED IMX_GPIO_NR(7, 7) #include "crm_regs.h" #include "devices-imx53.h" @@ -58,12 +59,27 @@ static iomux_v3_cfg_t mx53_evk_pads[] = { /* ecspi chip select lines */ MX53_PAD_EIM_EB2__GPIO2_30, MX53_PAD_EIM_D19__GPIO3_19, + /* LED */ + MX53_PAD_PATA_DA_1__GPIO7_7, }; static const struct imxuart_platform_data mx53_evk_uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; +static const struct gpio_led mx53evk_leds[] __initconst = { + { + .name = "green", + .default_trigger = "heartbeat", + .gpio = MX53EVK_LED, + }, +}; + +static const struct gpio_led_platform_data mx53evk_leds_data __initconst = { + .leds = mx53evk_leds, + .num_leds = ARRAY_SIZE(mx53evk_leds), +}; + static inline void mx53_evk_init_uart(void) { imx53_add_imx_uart(0, NULL); @@ -135,6 +151,7 @@ static void __init mx53_evk_board_init(void) ARRAY_SIZE(mx53_evk_spi_board_info)); imx53_add_ecspi(0, &mx53_evk_spi_data); imx53_add_imx2_wdt(0, NULL); + gpio_led_register_device(-1, &mx53evk_leds_data); } static void __init mx53_evk_timer_init(void) diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index 359c3e2..4e1d51d 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c @@ -38,6 +38,10 @@ #define MX53_LOCO_UI1 IMX_GPIO_NR(2, 14) #define MX53_LOCO_UI2 IMX_GPIO_NR(2, 15) #define LOCO_FEC_PHY_RST IMX_GPIO_NR(7, 6) +#define LOCO_LED IMX_GPIO_NR(7, 7) +#define LOCO_SD3_CD IMX_GPIO_NR(3, 11) +#define LOCO_SD3_WP IMX_GPIO_NR(3, 12) +#define LOCO_SD1_CD IMX_GPIO_NR(3, 13) static iomux_v3_cfg_t mx53_loco_pads[] = { /* FEC */ @@ -70,6 +74,8 @@ static iomux_v3_cfg_t mx53_loco_pads[] = { MX53_PAD_SD1_DATA1__ESDHC1_DAT1, MX53_PAD_SD1_DATA2__ESDHC1_DAT2, MX53_PAD_SD1_DATA3__ESDHC1_DAT3, + /* SD1_CD */ + MX53_PAD_EIM_DA13__GPIO3_13, /* SD3 */ MX53_PAD_PATA_DATA8__ESDHC3_DAT0, MX53_PAD_PATA_DATA9__ESDHC3_DAT1, @@ -163,7 +169,7 @@ static iomux_v3_cfg_t mx53_loco_pads[] = { MX53_PAD_GPIO_7__SPDIF_PLOCK, MX53_PAD_GPIO_17__SPDIF_OUT1, /* GPIO */ - MX53_PAD_PATA_DA_1__GPIO7_7, + MX53_PAD_PATA_DA_1__GPIO7_7, /* LED */ MX53_PAD_PATA_DA_2__GPIO7_8, MX53_PAD_PATA_DATA5__GPIO2_5, MX53_PAD_PATA_DATA6__GPIO2_6, @@ -202,6 +208,19 @@ static const struct gpio_keys_platform_data loco_button_data __initconst = { .nbuttons = ARRAY_SIZE(loco_buttons), }; +static const struct esdhc_platform_data mx53_loco_sd1_data __initconst = { + .cd_gpio = LOCO_SD1_CD, + .cd_type = ESDHC_CD_GPIO, + .wp_type = ESDHC_WP_NONE, +}; + +static const struct esdhc_platform_data mx53_loco_sd3_data __initconst = { + .cd_gpio = LOCO_SD3_CD, + .wp_gpio = LOCO_SD3_WP, + .cd_type = ESDHC_CD_GPIO, + .wp_type = ESDHC_WP_GPIO, +}; + static inline void mx53_loco_fec_reset(void) { int ret; @@ -225,6 +244,19 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = { .bitrate = 100000, }; +static const struct gpio_led mx53loco_leds[] __initconst = { + { + .name = "green", + .default_trigger = "heartbeat", + .gpio = LOCO_LED, + }, +}; + +static const struct gpio_led_platform_data mx53loco_leds_data __initconst = { + .leds = mx53loco_leds, + .num_leds = ARRAY_SIZE(mx53loco_leds), +}; + static void __init mx53_loco_board_init(void) { imx53_soc_init(); @@ -237,9 +269,10 @@ static void __init mx53_loco_board_init(void) imx53_add_imx2_wdt(0, NULL); imx53_add_imx_i2c(0, &mx53_loco_i2c_data); imx53_add_imx_i2c(1, &mx53_loco_i2c_data); - imx53_add_sdhci_esdhc_imx(0, NULL); - imx53_add_sdhci_esdhc_imx(2, NULL); + imx53_add_sdhci_esdhc_imx(0, &mx53_loco_sd1_data); + imx53_add_sdhci_esdhc_imx(2, &mx53_loco_sd3_data); imx_add_gpio_keys(&loco_button_data); + gpio_led_register_device(-1, &mx53loco_leds_data); } static void __init mx53_loco_timer_init(void) diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 0adeea1..f7bf996 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -271,7 +271,11 @@ static int _clk_pll_enable(struct clk *clk) int i = 0; pllbase = _get_pll_base(clk); - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); + if (reg & MXC_PLL_DP_CTL_UPEN) + return 0; + + reg |= MXC_PLL_DP_CTL_UPEN; __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); /* Wait for lock */ @@ -1254,12 +1258,20 @@ DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, &ipg_clk, &aips_tz1_clk); DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, NULL, NULL, &ipg_clk, &spba_clk); +DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET, + NULL, NULL, &ipg_clk, &spba_clk); +DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET, + NULL, NULL, &ipg_clk, &spba_clk); DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &uart_root_clk, &uart1_ipg_clk); DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, NULL, NULL, &uart_root_clk, &uart2_ipg_clk); DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, NULL, NULL, &uart_root_clk, &uart3_ipg_clk); +DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET, + NULL, NULL, &uart_root_clk, &uart4_ipg_clk); +DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET, + NULL, NULL, &uart_root_clk, &uart5_ipg_clk); /* GPT */ DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, @@ -1279,6 +1291,8 @@ DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_perclk, NULL); DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, + NULL, NULL, &ipg_perclk, NULL); /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, @@ -1412,11 +1426,13 @@ DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET, }, static struct clk_lookup mx51_lookups[] = { - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + /* i.mx51 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK("fec.0", NULL, fec_clk) + /* i.mx51 has the i.mx27 type fec */ + _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) @@ -1436,7 +1452,8 @@ static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) - _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) + /* i.mx51 has the i.mx35 type sdma */ + _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) _REGISTER_CLOCK(NULL, "ckih", ckih_clk) _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) @@ -1444,10 +1461,10 @@ static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) /* i.mx51 has the i.mx35 type cspi */ _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk) _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) @@ -1460,25 +1477,36 @@ static struct clk_lookup mx51_lookups[] = { }; static struct clk_lookup mx53_lookups[] = { - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + /* i.mx53 has the i.mx21 type uart */ + _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK("fec.0", NULL, fec_clk) + /* i.mx53 has the i.mx25 type fec */ + _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_mx53_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_mx53_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_mx53_clk) + _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk) /* i.mx53 has the i.mx51 type ecspi */ _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) /* i.mx53 has the i.mx25 type cspi */ _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk) _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) + /* i.mx53 has the i.mx35 type sdma */ + _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) + _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) + _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) + _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) + _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) }; static void clk_tree_init(void) diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h index 87c0c58..5e11ba7 100644 --- a/arch/arm/mach-mx5/crm_regs.h +++ b/arch/arm/mach-mx5/crm_regs.h @@ -114,6 +114,8 @@ #define MXC_CCM_CCGR4 (MX51_CCM_BASE + 0x78) #define MXC_CCM_CCGR5 (MX51_CCM_BASE + 0x7C) #define MXC_CCM_CCGR6 (MX51_CCM_BASE + 0x80) +#define MXC_CCM_CCGR7 (MX51_CCM_BASE + 0x84) + #define MXC_CCM_CMEOR (MX51_CCM_BASE + 0x84) /* Define the bits in register CCR */ diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h index 48f4c8c..c27fe8b 100644 --- a/arch/arm/mach-mx5/devices-imx53.h +++ b/arch/arm/mach-mx5/devices-imx53.h @@ -32,3 +32,11 @@ extern const struct imx_spi_imx_data imx53_ecspi_data[]; extern const struct imx_imx2_wdt_data imx53_imx2_wdt_data[]; #define imx53_add_imx2_wdt(id, pdata) \ imx_add_imx2_wdt(&imx53_imx2_wdt_data[id]) + +extern const struct imx_imx_ssi_data imx53_imx_ssi_data[]; +#define imx53_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx53_imx_ssi_data[id], pdata) + +extern const struct imx_imx_keypad_data imx53_imx_keypad_data; +#define imx53_add_imx_keypad(pdata) \ + imx_add_imx_keypad(&imx53_imx_keypad_data, pdata) diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index 665843d..baea6e5 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -18,6 +18,7 @@ #include <mach/hardware.h> #include <mach/common.h> +#include <mach/devices-common.h> #include <mach/iomux-v3.h> /* @@ -100,6 +101,43 @@ void __init mx53_init_irq(void) tzic_init_irq(tzic_virt); } +static struct sdma_script_start_addrs imx51_sdma_script __initdata = { + .ap_2_ap_addr = 642, + .uart_2_mcu_addr = 817, + .mcu_2_app_addr = 747, + .mcu_2_shp_addr = 961, + .ata_2_mcu_addr = 1473, + .mcu_2_ata_addr = 1392, + .app_2_per_addr = 1033, + .app_2_mcu_addr = 683, + .shp_2_per_addr = 1251, + .shp_2_mcu_addr = 892, +}; + +static struct sdma_platform_data imx51_sdma_pdata __initdata = { + .fw_name = "sdma-imx51.bin", + .script_addrs = &imx51_sdma_script, +}; + +static struct sdma_script_start_addrs imx53_sdma_script __initdata = { + .ap_2_ap_addr = 642, + .app_2_mcu_addr = 683, + .mcu_2_app_addr = 747, + .uart_2_mcu_addr = 817, + .shp_2_mcu_addr = 891, + .mcu_2_shp_addr = 960, + .uartsh_2_mcu_addr = 1032, + .spdif_2_mcu_addr = 1100, + .mcu_2_spdif_addr = 1134, + .firi_2_mcu_addr = 1193, + .mcu_2_firi_addr = 1290, +}; + +static struct sdma_platform_data imx53_sdma_pdata __initdata = { + .fw_name = "sdma-imx53.bin", + .script_addrs = &imx53_sdma_script, +}; + void __init imx51_soc_init(void) { /* i.mx51 has the i.mx31 type gpio */ @@ -107,6 +145,9 @@ void __init imx51_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH); mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH); mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH); + + /* i.mx51 has the i.mx35 type sdma */ + imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); } void __init imx53_soc_init(void) @@ -119,4 +160,7 @@ void __init imx53_soc_init(void) mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH); mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); + + /* i.mx53 has the i.mx35 type sdma */ + imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); } diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c index 56739c2..c920945 100644 --- a/arch/arm/mach-mx5/mx51_efika.c +++ b/arch/arm/mach-mx5/mx51_efika.c @@ -186,7 +186,7 @@ static int initialize_usbh1_port(struct platform_device *pdev) mdelay(10); - return mx51_initialize_usb_hw(0, MXC_EHCI_ITC_NO_THRESHOLD); + return mx51_initialize_usb_hw(pdev->id, MXC_EHCI_ITC_NO_THRESHOLD); } static struct mxc_usbh_platform_data usbh1_config = { @@ -260,8 +260,8 @@ static struct regulator_consumer_supply vvideo_consumers[] = { }; static struct regulator_consumer_supply vsd_consumers[] = { - REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"), - REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx51.0"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx51.1"), }; static struct regulator_consumer_supply pwgt1_consumer[] = { diff --git a/arch/arm/mach-mx5/pm-imx5.c b/arch/arm/mach-mx5/pm-imx5.c new file mode 100644 index 0000000..e4529af --- /dev/null +++ b/arch/arm/mach-mx5/pm-imx5.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include <linux/suspend.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/err.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> +#include <mach/system.h> +#include "crm_regs.h" + +static struct clk *gpc_dvfs_clk; + +static int mx5_suspend_enter(suspend_state_t state) +{ + clk_enable(gpc_dvfs_clk); + switch (state) { + case PM_SUSPEND_MEM: + mx5_cpu_lp_set(STOP_POWER_OFF); + break; + case PM_SUSPEND_STANDBY: + mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + break; + default: + return -EINVAL; + } + + if (state == PM_SUSPEND_MEM) { + local_flush_tlb_all(); + flush_cache_all(); + + /*clear the EMPGC0/1 bits */ + __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); + __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); + } + cpu_do_idle(); + clk_disable(gpc_dvfs_clk); + + return 0; +} + +static int mx5_pm_valid(suspend_state_t state) +{ + return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX); +} + +static const struct platform_suspend_ops mx5_suspend_ops = { + .valid = mx5_pm_valid, + .enter = mx5_suspend_enter, +}; + +static int __init mx5_pm_init(void) +{ + if (gpc_dvfs_clk == NULL) + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + + if (!IS_ERR(gpc_dvfs_clk)) { + if (cpu_is_mx51()) + suspend_set_ops(&mx5_suspend_ops); + } else + return -EPERM; + + return 0; +} +device_initcall(mx5_pm_init); diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 162b0b0..4cd0231 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -41,6 +41,7 @@ config MACH_MX23EVK config MACH_MX28EVK bool "Support MX28EVK Platform" select SOC_IMX28 + select LEDS_GPIO_REGISTER select MXS_HAVE_AMBA_DUART select MXS_HAVE_PLATFORM_AUART select MXS_HAVE_PLATFORM_FEC @@ -60,6 +61,7 @@ config MODULE_TX28 select MXS_HAVE_PLATFORM_AUART select MXS_HAVE_PLATFORM_FEC select MXS_HAVE_PLATFORM_MXS_I2C + select MXS_HAVE_PLATFORM_MXS_MMC select MXS_HAVE_PLATFORM_MXS_PWM config MACH_TX28 diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h deleted file mode 100644 index 3a8f2e3..0000000 --- a/arch/arm/mach-mxs/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __MACH_MXS_CLKDEV_H__ -#define __MACH_MXS_CLKDEV_H__ - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index 56767a5..eaaf6ff 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/gpio.h> +#include <linux/leds.h> #include <linux/irq.h> #include <linux/clk.h> @@ -29,6 +30,7 @@ #define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13) #define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15) +#define MX28EVK_GPIO_LED MXS_GPIO_NR(3, 5) #define MX28EVK_BL_ENABLE MXS_GPIO_NR(3, 18) #define MX28EVK_LCD_ENABLE MXS_GPIO_NR(3, 30) #define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13) @@ -178,6 +180,23 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = { /* slot power enable */ MX28_PAD_PWM4__GPIO_3_29 | (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + + /* led */ + MX28_PAD_AUART1_TX__GPIO_3_5 | MXS_PAD_CTRL, +}; + +/* led */ +static const struct gpio_led mx28evk_leds[] __initconst = { + { + .name = "GPIO-LED", + .default_trigger = "heartbeat", + .gpio = MX28EVK_GPIO_LED, + }, +}; + +static const struct gpio_led_platform_data mx28evk_led_data __initconst = { + .leds = mx28evk_leds, + .num_leds = ARRAY_SIZE(mx28evk_leds), }; /* fec */ @@ -385,6 +404,8 @@ static void __init mx28evk_init(void) if (ret) pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret); mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); + + gpio_led_register_device(0, &mx28evk_led_data); } static void __init mx28evk_timer_init(void) diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c index 6766a12..515a423 100644 --- a/arch/arm/mach-mxs/mach-tx28.c +++ b/arch/arm/mach-mxs/mach-tx28.c @@ -139,6 +139,11 @@ static struct i2c_board_info tx28_stk5v3_i2c_boardinfo[] __initdata = { }, }; +static struct mxs_mmc_platform_data tx28_mmc0_pdata __initdata = { + .wp_gpio = -EINVAL, + .flags = SLOTF_4_BIT_CAPABLE, +}; + static void __init tx28_stk5v3_init(void) { mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads, @@ -155,6 +160,7 @@ static void __init tx28_stk5v3_init(void) mx28_add_mxs_i2c(0); i2c_register_board_info(0, tx28_stk5v3_i2c_boardinfo, ARRAY_SIZE(tx28_stk5v3_i2c_boardinfo)); + mx28_add_mxs_mmc(0, &tx28_mmc0_pdata); } static void __init tx28_timer_init(void) diff --git a/arch/arm/mach-nomadik/include/mach/clkdev.h b/arch/arm/mach-nomadik/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-nomadik/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-nuc93x/include/mach/clkdev.h b/arch/arm/mach-nuc93x/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-nuc93x/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-omap1/include/mach/clkdev.h b/arch/arm/mach-omap1/include/mach/clkdev.h deleted file mode 100644 index ea8640e..0000000 --- a/arch/arm/mach-omap1/include/mach/clkdev.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap1/include/mach/clkdev.h - */ - -#include <plat/clkdev.h> diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 98ba978..495b398 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -44,7 +44,7 @@ #include <linux/io.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 19d5891..57b66d5 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -7,7 +7,6 @@ config ARCH_OMAP2PLUS_TYPICAL default y select AEABI select REGULATOR - select PM select PM_RUNTIME select VFP select NEON if ARCH_OMAP3 || ARCH_OMAP4 @@ -266,9 +265,10 @@ config MACH_OMAP_ZOOM3 select REGULATOR_FIXED_VOLTAGE config MACH_CM_T35 - bool "CompuLab CM-T35 module" + bool "CompuLab CM-T35/CM-T3730 modules" depends on ARCH_OMAP3 default y + select MACH_CM_T3730 select OMAP_PACKAGE_CUS config MACH_CM_T3517 @@ -277,6 +277,9 @@ config MACH_CM_T3517 default y select OMAP_PACKAGE_CBB +config MACH_CM_T3730 + bool + config MACH_IGEP0020 bool "IGEP v2 board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 933b25b..c7cef44 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -22,6 +22,7 @@ #include <linux/i2c/twl.h> #include <linux/gpio_keys.h> #include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <linux/leds.h> #include <linux/leds_pwm.h> @@ -37,6 +38,7 @@ #include <plat/mmc.h> #include <plat/omap4-keypad.h> #include <video/omapdss.h> +#include <linux/wl12xx.h> #include "mux.h" #include "hsmmc.h" @@ -51,6 +53,9 @@ #define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ +#define GPIO_WIFI_PMENA 54 +#define GPIO_WIFI_IRQ 53 + static const int sdp4430_keymap[] = { KEY(0, 0, KEY_E), KEY(0, 1, KEY_R), @@ -124,6 +129,64 @@ static const int sdp4430_keymap[] = { KEY(7, 6, KEY_OK), KEY(7, 7, KEY_DOWN), }; +static struct omap_device_pad keypad_pads[] __initdata = { + { .name = "kpd_col1.kpd_col1", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_col1.kpd_col1", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_col2.kpd_col2", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_col3.kpd_col3", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_col4.kpd_col4", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_col5.kpd_col5", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "gpmc_a23.kpd_col7", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "gpmc_a22.kpd_col6", + .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, + }, + { .name = "kpd_row0.kpd_row0", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "kpd_row1.kpd_row1", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "kpd_row2.kpd_row2", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "kpd_row3.kpd_row3", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "kpd_row4.kpd_row4", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "kpd_row5.kpd_row5", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "gpmc_a18.kpd_row6", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, + { .name = "gpmc_a19.kpd_row7", + .enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | + OMAP_MUX_MODE1 | OMAP_INPUT_EN, + }, +}; static struct matrix_keymap_data sdp4430_keymap_data = { .keymap = sdp4430_keymap, @@ -135,6 +198,13 @@ static struct omap4_keypad_platform_data sdp4430_keypad_data = { .rows = 8, .cols = 8, }; + +static struct omap_board_data keypad_data = { + .id = 1, + .pads = keypad_pads, + .pads_cnt = ARRAY_SIZE(keypad_pads), +}; + static struct gpio_led sdp4430_gpio_leds[] = { { .name = "omap4:green:debug0", @@ -275,11 +345,40 @@ static struct platform_device sdp4430_lcd_device = { .id = -1, }; +static struct regulator_consumer_supply sdp4430_vbat_supply[] = { + REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"), + REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"), +}; + +static struct regulator_init_data sdp4430_vbat_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(sdp4430_vbat_supply), + .consumer_supplies = sdp4430_vbat_supply, +}; + +static struct fixed_voltage_config sdp4430_vbat_pdata = { + .supply_name = "VBAT", + .microvolts = 3750000, + .init_data = &sdp4430_vbat_data, + .gpio = -EINVAL, +}; + +static struct platform_device sdp4430_vbat = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &sdp4430_vbat_pdata, + }, +}; + static struct platform_device *sdp4430_devices[] __initdata = { &sdp4430_lcd_device, &sdp4430_gpio_keys_device, &sdp4430_leds_gpio, &sdp4430_leds_pwm, + &sdp4430_vbat, }; static struct omap_lcd_config sdp4430_lcd_config __initdata = { @@ -315,7 +414,16 @@ static struct omap2_hsmmc_info mmc[] = { { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + { + .mmc = 5, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, + .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, + .ocr_mask = MMC_VDD_165_195, + .nonremovable = true, }, {} /* Terminator */ }; @@ -324,6 +432,37 @@ static struct regulator_consumer_supply sdp4430_vaux_supply[] = { REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), }; +static struct regulator_consumer_supply omap4_sdp4430_vmmc5_supply = { + .supply = "vmmc", + .dev_name = "omap_hsmmc.4", +}; + +static struct regulator_init_data sdp4430_vmmc5 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &omap4_sdp4430_vmmc5_supply, +}; + +static struct fixed_voltage_config sdp4430_vwlan = { + .supply_name = "vwl1271", + .microvolts = 1800000, /* 1.8V */ + .gpio = GPIO_WIFI_PMENA, + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &sdp4430_vmmc5, +}; + +static struct platform_device omap_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &sdp4430_vwlan, + }, +}; + static int omap4_twl6030_hsmmc_late_init(struct device *dev) { int ret = 0; @@ -395,7 +534,33 @@ static struct regulator_init_data sdp4430_vusim = { }, }; +static struct twl4030_codec_data twl6040_codec = { + /* single-step ramp for headset and handsfree */ + .hs_left_step = 0x0f, + .hs_right_step = 0x0f, + .hf_left_step = 0x1d, + .hf_right_step = 0x1d, +}; + +static struct twl4030_vibra_data twl6040_vibra = { + .vibldrv_res = 8, + .vibrdrv_res = 3, + .viblmotor_res = 10, + .vibrmotor_res = 10, + .vddvibl_uV = 0, /* fixed volt supply - VBAT */ + .vddvibr_uV = 0, /* fixed volt supply - VBAT */ +}; + +static struct twl4030_audio_data twl6040_audio = { + .codec = &twl6040_codec, + .vibra = &twl6040_vibra, + .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, + .irq_base = TWL6040_CODEC_IRQ_BASE, +}; + static struct twl4030_platform_data sdp4430_twldata = { + .audio = &twl6040_audio, /* Regulators */ .vusim = &sdp4430_vusim, .vaux1 = &sdp4430_vaux1, @@ -593,6 +758,41 @@ static inline void board_serial_init(void) } #endif +static void omap4_sdp4430_wifi_mux_init(void) +{ + omap_mux_init_gpio(GPIO_WIFI_IRQ, OMAP_PIN_INPUT | + OMAP_PIN_OFF_WAKEUPENABLE); + omap_mux_init_gpio(GPIO_WIFI_PMENA, OMAP_PIN_OUTPUT); + + omap_mux_init_signal("sdmmc5_cmd.sdmmc5_cmd", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc5_clk.sdmmc5_clk", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc5_dat0.sdmmc5_dat0", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc5_dat1.sdmmc5_dat1", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc5_dat2.sdmmc5_dat2", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("sdmmc5_dat3.sdmmc5_dat3", + OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP); + +} + +static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = { + .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ), + .board_ref_clock = WL12XX_REFCLOCK_26, + .board_tcxo_clock = WL12XX_TCXOCLOCK_26, +}; + +static void omap4_sdp4430_wifi_init(void) +{ + omap4_sdp4430_wifi_mux_init(); + if (wl12xx_set_platform_data(&omap4_sdp4430_wlan_data)) + pr_err("Error setting wl12xx data\n"); + platform_device_register(&omap_vwlan_device); +} + static void __init omap_4430sdp_init(void) { int status; @@ -609,6 +809,7 @@ static void __init omap_4430sdp_init(void) omap_sfh7741prox_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); board_serial_init(); + omap4_sdp4430_wifi_init(); omap4_twl6030_hsmmc_init(mmc); usb_musb_init(&musb_board_data); @@ -622,7 +823,7 @@ static void __init omap_4430sdp_init(void) ARRAY_SIZE(sdp4430_spi_board_info)); } - status = omap4_keyboard_init(&sdp4430_keypad_data); + status = omap4_keyboard_init(&sdp4430_keypad_data, &keypad_data); if (status) pr_err("Keypad initialization failed: %d\n", status); diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 5f2b55f..933e935 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -45,8 +45,6 @@ static struct omap_board_config_kernel am3517_crane_config[] __initdata = { static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, }; -#else -#define board_mux NULL #endif static void __init am3517_crane_init_early(void) diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 35891d49..3af8aab 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -1,8 +1,9 @@ /* - * board-cm-t35.c (CompuLab CM-T35 module) + * CompuLab CM-T35/CM-T3730 modules support * - * Copyright (C) 2009 CompuLab, Ltd. - * Author: Mike Rapoport <mike@compulab.co.il> + * Copyright (C) 2009-2011 CompuLab, Ltd. + * Authors: Mike Rapoport <mike@compulab.co.il> + * Igor Grinberg <grinberg@compulab.co.il> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -13,11 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * */ #include <linux/kernel.h> @@ -149,12 +145,12 @@ static struct mtd_partition cm_t35_nand_partitions[] = { }, { .name = "linux", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */ .size = 32 * NAND_BLOCK_SIZE, }, { .name = "rootfs", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ + .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */ .size = MTDPART_SIZ_FULL, }, }; @@ -433,9 +429,9 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) { gpio_export(wlan_rst, 0); udelay(10); - gpio_set_value(wlan_rst, 0); + gpio_set_value_cansleep(wlan_rst, 0); udelay(10); - gpio_set_value(wlan_rst, 1); + gpio_set_value_cansleep(wlan_rst, 1); } else { pr_err("CM-T35: could not obtain gpio for WiFi reset\n"); } @@ -539,17 +535,11 @@ static struct omap_board_mux board_mux[] __initdata = { OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT), - /* DSS */ + /* common DSS */ OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), @@ -562,12 +552,6 @@ static struct omap_board_mux board_mux[] __initdata = { OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), - OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT), /* display controls */ OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), @@ -580,19 +564,53 @@ static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, }; + +static void __init cm_t3x_common_dss_mux_init(int mux_mode) +{ + omap_mux_init_signal("dss_data18", mux_mode); + omap_mux_init_signal("dss_data19", mux_mode); + omap_mux_init_signal("dss_data20", mux_mode); + omap_mux_init_signal("dss_data21", mux_mode); + omap_mux_init_signal("dss_data22", mux_mode); + omap_mux_init_signal("dss_data23", mux_mode); +} + +static void __init cm_t35_init_mux(void) +{ + omap_mux_init_signal("gpio_70", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_71", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_72", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_73", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_74", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("gpio_75", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); + cm_t3x_common_dss_mux_init(OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); +} + +static void __init cm_t3730_init_mux(void) +{ + omap_mux_init_signal("sys_boot0", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("sys_boot1", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("sys_boot3", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("sys_boot4", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("sys_boot5", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + omap_mux_init_signal("sys_boot6", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); + cm_t3x_common_dss_mux_init(OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); +} +#else +static inline void cm_t35_init_mux(void) {} +static inline void cm_t3730_init_mux(void) {} #endif static struct omap_board_config_kernel cm_t35_config[] __initdata = { }; -static void __init cm_t35_init(void) +static void __init cm_t3x_common_init(void) { omap_board_config = cm_t35_config; omap_board_config_size = ARRAY_SIZE(cm_t35_config); omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); omap_serial_init(); cm_t35_init_i2c(); - cm_t35_init_nand(); omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL); cm_t35_init_ethernet(); cm_t35_init_led(); @@ -602,6 +620,19 @@ static void __init cm_t35_init(void) usbhs_init(&usbhs_bdata); } +static void __init cm_t35_init(void) +{ + cm_t3x_common_init(); + cm_t35_init_mux(); + cm_t35_init_nand(); +} + +static void __init cm_t3730_init(void) +{ + cm_t3x_common_init(); + cm_t3730_init_mux(); +} + MACHINE_START(CM_T35, "Compulab CM-T35") .boot_params = 0x80000100, .reserve = omap_reserve, @@ -611,3 +642,13 @@ MACHINE_START(CM_T35, "Compulab CM-T35") .init_machine = cm_t35_init, .timer = &omap3_timer, MACHINE_END + +MACHINE_START(CM_T3730, "Compulab CM-T3730") + .boot_params = 0x80000100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = cm_t35_init_early, + .init_irq = omap3_init_irq, + .init_machine = cm_t3730_init, + .timer = &omap3_timer, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 34f8411..3ae16b4 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -60,7 +60,8 @@ * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1 * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0 * C4 = GPIO173, GPIO172, GPIO171: 1 0 1 - * XM = GPIO173, GPIO172, GPIO171: 0 0 0 + * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0 + * XMC = GPIO173, GPIO172, GPIO171: 0 1 0 */ enum { OMAP3BEAGLE_BOARD_UNKN = 0, @@ -68,14 +69,26 @@ enum { OMAP3BEAGLE_BOARD_C1_3, OMAP3BEAGLE_BOARD_C4, OMAP3BEAGLE_BOARD_XM, + OMAP3BEAGLE_BOARD_XMC, }; static u8 omap3_beagle_version; -static u8 omap3_beagle_get_rev(void) -{ - return omap3_beagle_version; -} +/* + * Board-specific configuration + * Defaults to BeagleBoard-xMC + */ +static struct { + int mmc1_gpio_wp; + int usb_pwr_level; + int reset_gpio; + int usr_button_gpio; +} beagle_config = { + .mmc1_gpio_wp = -EINVAL, + .usb_pwr_level = GPIOF_OUT_INIT_LOW, + .reset_gpio = 129, + .usr_button_gpio = 4, +}; static struct gpio omap3_beagle_rev_gpios[] __initdata = { { 171, GPIOF_IN, "rev_id_0" }, @@ -110,18 +123,32 @@ static void __init omap3_beagle_init_rev(void) case 7: printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX; + beagle_config.mmc1_gpio_wp = 29; + beagle_config.reset_gpio = 170; + beagle_config.usr_button_gpio = 7; break; case 6: printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3; + beagle_config.mmc1_gpio_wp = 23; + beagle_config.reset_gpio = 170; + beagle_config.usr_button_gpio = 7; break; case 5: printk(KERN_INFO "OMAP3 Beagle Rev: C4\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; + beagle_config.mmc1_gpio_wp = 23; + beagle_config.reset_gpio = 170; + beagle_config.usr_button_gpio = 7; break; case 0: - printk(KERN_INFO "OMAP3 Beagle Rev: xM\n"); + printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n"); omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; + beagle_config.usb_pwr_level = GPIOF_OUT_INIT_HIGH; + break; + case 2: + printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC; break; default: printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev); @@ -225,7 +252,7 @@ static struct omap2_hsmmc_info mmc[] = { { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_wp = 29, + .gpio_wp = -EINVAL, }, {} /* Terminator */ }; @@ -243,17 +270,11 @@ static struct gpio_led gpio_leds[]; static int beagle_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - int r, usb_pwr_level; - - if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { - mmc[0].gpio_wp = -EINVAL; - } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) || - (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) { - omap_mux_init_gpio(23, OMAP_PIN_INPUT); - mmc[0].gpio_wp = 23; - } else { - omap_mux_init_gpio(29, OMAP_PIN_INPUT); - } + int r; + + if (beagle_config.mmc1_gpio_wp != -EINVAL) + omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); + mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp; /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; omap2_hsmmc_init(mmc); @@ -263,9 +284,8 @@ static int beagle_twl_gpio_setup(struct device *dev, * high / others active low) * DVI reset GPIO is different between beagle revisions */ - if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { - usb_pwr_level = GPIOF_OUT_INIT_HIGH; - beagle_dvi_device.reset_gpio = 129; + /* Valid for all -xM revisions */ + if (cpu_is_omap3630()) { /* * gpio + 1 on Xm controls the TFP410's enable line (active low) * gpio + 2 control varies depending on the board rev as below: @@ -283,8 +303,6 @@ static int beagle_twl_gpio_setup(struct device *dev, pr_err("%s: unable to configure DVI_LDO_EN\n", __func__); } else { - usb_pwr_level = GPIOF_OUT_INIT_LOW; - beagle_dvi_device.reset_gpio = 170; /* * REVISIT: need ehci-omap hooks for external VBUS * power switch and overcurrent detect @@ -292,8 +310,10 @@ static int beagle_twl_gpio_setup(struct device *dev, if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) pr_err("%s: unable to configure EHCI_nOC\n", __func__); } + beagle_dvi_device.reset_gpio = beagle_config.reset_gpio; - gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR"); + gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, + "nEN_USB_PWR"); /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -404,7 +424,8 @@ static struct platform_device leds_gpio = { static struct gpio_keys_button gpio_buttons[] = { { .code = BTN_EXTRA, - .gpio = 7, + /* Dynamically assigned depending on board */ + .gpio = -EINVAL, .desc = "user", .wakeup = 1, }, @@ -468,25 +489,24 @@ static void __init beagle_opp_init(void) return; } - /* Custom OPP enabled for XM */ - if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { - struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); - struct omap_hwmod *dh = omap_hwmod_lookup("iva"); - struct device *dev; + /* Custom OPP enabled for all xM versions */ + if (cpu_is_omap3630()) { + struct device *mpu_dev, *iva_dev; - if (!mh || !dh) { + mpu_dev = omap2_get_mpuss_device(); + iva_dev = omap2_get_iva_device(); + + if (!mpu_dev || !iva_dev) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", - __func__, mh, dh); + __func__, mpu_dev, iva_dev); return; } /* Enable MPU 1GHz and lower opps */ - dev = &mh->od->pdev.dev; - r = opp_enable(dev, 800000000); + r = opp_enable(mpu_dev, 800000000); /* TODO: MPU 1GHz needs SR and ABB */ /* Enable IVA 800MHz and lower opps */ - dev = &dh->od->pdev.dev; - r |= opp_enable(dev, 660000000); + r |= opp_enable(iva_dev, 660000000); /* TODO: DSP 800MHz needs SR and ABB */ if (r) { pr_err("%s: failed to enable higher opp %d\n", @@ -495,10 +515,8 @@ static void __init beagle_opp_init(void) * Cleanup - disable the higher freqs - we dont care * about the results */ - dev = &mh->od->pdev.dev; - opp_disable(dev, 800000000); - dev = &dh->od->pdev.dev; - opp_disable(dev, 660000000); + opp_disable(mpu_dev, 800000000); + opp_disable(iva_dev, 660000000); } } return; @@ -509,6 +527,9 @@ static void __init omap3_beagle_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_beagle_init_rev(); omap3_beagle_i2c_init(); + + gpio_buttons[0].gpio = beagle_config.usr_button_gpio; + platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); omap_display_init(&beagle_dss_data); diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index f1f18d0..f949a99 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -519,7 +519,6 @@ static void __init overo_init(void) usb_musb_init(NULL); usbhs_init(&usbhs_bdata); overo_spi_init(); - overo_ads7846_init(); overo_init_smsc911x(); overo_display_init(); overo_init_led(); diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index bdb24db..5a886cd 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -39,6 +39,7 @@ #include <sound/tpa6130a2-plat.h> #include <media/radio-si4713.h> #include <media/si4713.h> +#include <linux/leds-lp5523.h> #include <../drivers/staging/iio/light/tsl2563.h> @@ -53,6 +54,7 @@ #define RX51_WL1251_IRQ_GPIO 42 #define RX51_FMTX_RESET_GPIO 163 #define RX51_FMTX_IRQ 53 +#define RX51_LP5523_CHIP_EN_GPIO 41 #define RX51_USB_TRANSCEIVER_RST_GPIO 67 @@ -71,6 +73,64 @@ static struct tsl2563_platform_data rx51_tsl2563_platform_data = { }; #endif +#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE) +static struct lp5523_led_config rx51_lp5523_led_config[] = { + { + .chan_nr = 0, + .led_current = 50, + }, { + .chan_nr = 1, + .led_current = 50, + }, { + .chan_nr = 2, + .led_current = 50, + }, { + .chan_nr = 3, + .led_current = 50, + }, { + .chan_nr = 4, + .led_current = 50, + }, { + .chan_nr = 5, + .led_current = 50, + }, { + .chan_nr = 6, + .led_current = 50, + }, { + .chan_nr = 7, + .led_current = 50, + }, { + .chan_nr = 8, + .led_current = 50, + } +}; + +static int rx51_lp5523_setup(void) +{ + return gpio_request_one(RX51_LP5523_CHIP_EN_GPIO, GPIOF_DIR_OUT, + "lp5523_enable"); +} + +static void rx51_lp5523_release(void) +{ + gpio_free(RX51_LP5523_CHIP_EN_GPIO); +} + +static void rx51_lp5523_enable(bool state) +{ + gpio_set_value(RX51_LP5523_CHIP_EN_GPIO, !!state); +} + +static struct lp5523_platform_data rx51_lp5523_platform_data = { + .led_config = rx51_lp5523_led_config, + .num_channels = ARRAY_SIZE(rx51_lp5523_led_config), + .clock_mode = LP5523_CLOCK_AUTO, + .setup_resources = rx51_lp5523_setup, + .release_resources = rx51_lp5523_release, + .enable = rx51_lp5523_enable, +}; +#endif + static struct omap2_mcspi_device_config wl1251_mcspi_config = { .turbo_mode = 0, .single_channel = 1, @@ -358,6 +418,10 @@ static struct regulator_consumer_supply rx51_vmmc1_supply[] = { REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), }; +static struct regulator_consumer_supply rx51_vaux2_supply[] = { + REGULATOR_SUPPLY("vdds_csib", "omap3isp"), +}; + static struct regulator_consumer_supply rx51_vaux3_supply[] = { REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), }; @@ -419,6 +483,8 @@ static struct regulator_init_data rx51_vaux2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(rx51_vaux2_supply), + .consumer_supplies = rx51_vaux2_supply, }; /* VAUX3 - adds more power to VIO_18 rail */ @@ -495,6 +561,32 @@ static struct regulator_init_data rx51_vmmc2 = { .consumer_supplies = rx51_vmmc2_supplies, }; +static struct regulator_init_data rx51_vpll1 = { + .constraints = { + .name = "VPLL", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vpll2 = { + .constraints = { + .name = "VSDI_CSI", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + static struct regulator_init_data rx51_vsim = { .constraints = { .name = "VMMC2_IO_18", @@ -524,6 +616,43 @@ static struct regulator_init_data rx51_vio = { .consumer_supplies = rx51_vio_supplies, }; +static struct regulator_init_data rx51_vintana1 = { + .constraints = { + .name = "VINTANA1", + .min_uV = 1500000, + .max_uV = 1500000, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vintana2 = { + .constraints = { + .name = "VINTANA2", + .min_uV = 2750000, + .max_uV = 2750000, + .apply_uV = true, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + +static struct regulator_init_data rx51_vintdig = { + .constraints = { + .name = "VINTDIG", + .min_uV = 1500000, + .max_uV = 1500000, + .always_on = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE, + }, +}; + static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = { .gpio_reset = RX51_FMTX_RESET_GPIO, }; @@ -741,11 +870,11 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = { .resource_config = twl4030_rconfig, }; -struct twl4030_codec_vibra_data rx51_vibra_data __initdata = { +struct twl4030_vibra_data rx51_vibra_data __initdata = { .coexist = 0, }; -struct twl4030_codec_data rx51_codec_data __initdata = { +struct twl4030_audio_data rx51_audio_data __initdata = { .audio_mclk = 26000000, .vibra = &rx51_vibra_data, }; @@ -755,13 +884,18 @@ static struct twl4030_platform_data rx51_twldata __initdata = { .gpio = &rx51_gpio_data, .keypad = &rx51_kp_data, .power = &rx51_t2scripts_data, - .codec = &rx51_codec_data, + .audio = &rx51_audio_data, .vaux1 = &rx51_vaux1, .vaux2 = &rx51_vaux2, .vaux4 = &rx51_vaux4, .vmmc1 = &rx51_vmmc1, + .vpll1 = &rx51_vpll1, + .vpll2 = &rx51_vpll2, .vsim = &rx51_vsim, + .vintana1 = &rx51_vintana1, + .vintana2 = &rx51_vintana2, + .vintdig = &rx51_vintdig, .vio = &rx51_vio, }; @@ -800,6 +934,12 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { .platform_data = &rx51_tsl2563_platform_data, }, #endif +#if defined(CONFIG_LEDS_LP5523) || defined(CONFIG_LEDS_LP5523_MODULE) + { + I2C_BOARD_INFO("lp5523", 0x32), + .platform_data = &rx51_lp5523_platform_data, + }, +#endif { I2C_BOARD_INFO("tpa6130a2", 0x60), .platform_data = &rx51_tpa6130a2_data, @@ -950,6 +1090,7 @@ error: void __init rx51_peripherals_init(void) { rx51_i2c_init(); + regulator_has_full_constraints(); gpmc_onenand_init(board_onenand_data); board_smc91x_init(); rx51_add_gpio_keys(); diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index 6402e78..369c2eb 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -23,6 +23,7 @@ #define ZOOM_SMSC911X_GPIO 158 #define ZOOM_QUADUART_CS 3 #define ZOOM_QUADUART_GPIO 102 +#define ZOOM_QUADUART_RST_GPIO 152 #define QUART_CLK 1843200 #define DEBUG_BASE 0x08000000 #define ZOOM_ETHR_START DEBUG_BASE @@ -67,6 +68,14 @@ static inline void __init zoom_init_quaduart(void) unsigned long cs_mem_base; int quart_gpio = 0; + if (gpio_request_one(ZOOM_QUADUART_RST_GPIO, + GPIOF_OUT_INIT_LOW, + "TL16CP754C GPIO") < 0) { + pr_err("Failed to request GPIO%d for TL16CP754C\n", + ZOOM_QUADUART_RST_GPIO); + return; + } + quart_cs = ZOOM_QUADUART_CS; if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) { diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 13a6442..6d0aa4f 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -274,12 +274,12 @@ static int __init omap_i2c_init(void) TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); if (machine_is_omap_zoom2()) { - struct twl4030_codec_audio_data *audio_data; - audio_data = zoom_twldata.codec->audio; + struct twl4030_codec_data *codec_data; + codec_data = zoom_twldata.audio->codec; - audio_data->ramp_delay_value = 3; /* 161 ms */ - audio_data->hs_extmute = 1; - audio_data->set_hs_extmute = zoom2_set_hs_extmute; + codec_data->ramp_delay_value = 3; /* 161 ms */ + codec_data->hs_extmute = 1; + codec_data->set_hs_extmute = zoom2_set_hs_extmute; } omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata); omap_register_i2c_bus(2, 400, NULL, 0); diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 180299e..1f3481f 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -38,6 +38,14 @@ u8 cpu_mask; /* + * clkdm_control: if true, then when a clock is enabled in the + * hardware, its clockdomain will first be enabled; and when a clock + * is disabled in the hardware, its clockdomain will be disabled + * afterwards. + */ +static bool clkdm_control = true; + +/* * OMAP2+ specific clock functions */ @@ -100,6 +108,19 @@ void omap2_init_clk_clkdm(struct clk *clk) } /** + * omap2_clk_disable_clkdm_control - disable clkdm control on clk enable/disable + * + * Prevent the OMAP clock code from calling into the clockdomain code + * when a hardware clock in that clockdomain is enabled or disabled. + * Intended to be called at init time from omap*_clk_init(). No + * return value. + */ +void __init omap2_clk_disable_clkdm_control(void) +{ + clkdm_control = false; +} + +/** * omap2_clk_dflt_find_companion - find companion clock to @clk * @clk: struct clk * to find the companion clock of * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in @@ -268,7 +289,7 @@ void omap2_clk_disable(struct clk *clk) clk->ops->disable(clk); } - if (clk->clkdm) + if (clkdm_control && clk->clkdm) clkdm_clk_disable(clk->clkdm, clk); if (clk->parent) @@ -308,7 +329,7 @@ int omap2_clk_enable(struct clk *clk) } } - if (clk->clkdm) { + if (clkdm_control && clk->clkdm) { ret = clkdm_clk_enable(clk->clkdm, clk); if (ret) { WARN(1, "clock: %s: could not enable clockdomain %s: " @@ -330,7 +351,7 @@ int omap2_clk_enable(struct clk *clk) return 0; oce_err3: - if (clk->clkdm) + if (clkdm_control && clk->clkdm) clkdm_clk_disable(clk->clkdm, clk); oce_err2: if (clk->parent) @@ -453,6 +474,7 @@ int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name) if (IS_ERR_VALUE(r)) { WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n", mpurate_ck->name, mpurate, r); + clk_put(mpurate_ck); return -EINVAL; } diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index e10ff2b..48ac568 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -16,6 +16,8 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H #define __ARCH_ARM_MACH_OMAP2_CLOCK_H +#include <linux/kernel.h> + #include <plat/clock.h> /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ @@ -72,6 +74,7 @@ void omap2_clk_disable_unused(struct clk *clk); #endif void omap2_init_clk_clkdm(struct clk *clk); +void __init omap2_clk_disable_clkdm_control(void); /* clkt_clksel.c public functions */ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 2926d02..debc040 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1805,9 +1805,9 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), /* DSS domain clocks */ CLK("omapdss_dss", "ick", &dss_ick, CK_242X), - CLK("omapdss_dss", "fck", &dss1_fck, CK_242X), - CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X), - CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X), + CLK(NULL, "dss1_fck", &dss1_fck, CK_242X), + CLK(NULL, "dss2_fck", &dss2_fck, CK_242X), + CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_242X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), @@ -1844,13 +1844,13 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gpt12_ick", &gpt12_ick, CK_242X), CLK(NULL, "gpt12_fck", &gpt12_fck, CK_242X), CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X), - CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_242X), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_242X), CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_242X), - CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_242X), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_242X), CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_242X), - CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_242X), + CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_242X), CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_242X), - CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_242X), + CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_242X), CLK(NULL, "uart1_ick", &uart1_ick, CK_242X), CLK(NULL, "uart1_fck", &uart1_fck, CK_242X), CLK(NULL, "uart2_ick", &uart2_ick, CK_242X), @@ -1860,7 +1860,7 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gpios_ick", &gpios_ick, CK_242X), CLK(NULL, "gpios_fck", &gpios_fck, CK_242X), CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_242X), - CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_242X), + CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_242X), CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_242X), CLK(NULL, "wdt1_ick", &wdt1_ick, CK_242X), CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_242X), @@ -1880,11 +1880,11 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "eac_ick", &eac_ick, CK_242X), CLK(NULL, "eac_fck", &eac_fck, CK_242X), CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X), - CLK("omap_hdq.1", "fck", &hdq_fck, CK_242X), + CLK("omap_hdq.0", "fck", &hdq_fck, CK_242X), CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X), - CLK("omap_i2c.1", "fck", &i2c1_fck, CK_242X), + CLK(NULL, "i2c1_fck", &i2c1_fck, CK_242X), CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X), - CLK("omap_i2c.2", "fck", &i2c2_fck, CK_242X), + CLK(NULL, "i2c2_fck", &i2c2_fck, CK_242X), CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X), CLK(NULL, "sdma_fck", &sdma_fck, CK_242X), CLK(NULL, "sdma_ick", &sdma_ick, CK_242X), diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 0c79d39..96a942e 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1895,9 +1895,9 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), /* DSS domain clocks */ CLK("omapdss_dss", "ick", &dss_ick, CK_243X), - CLK("omapdss_dss", "fck", &dss1_fck, CK_243X), - CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X), - CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X), + CLK(NULL, "dss1_fck", &dss1_fck, CK_243X), + CLK(NULL, "dss2_fck", &dss2_fck, CK_243X), + CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), @@ -1934,21 +1934,21 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X), CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X), CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X), - CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_243X), CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X), - CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_243X), CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X), - CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_243X), CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X), - CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X), + CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_243X), CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X), - CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X), + CLK(NULL, "mcbsp5_fck", &mcbsp5_fck, CK_243X), CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X), - CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X), + CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_243X), CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X), - CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X), + CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_243X), CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X), - CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X), + CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_243X), CLK(NULL, "uart1_ick", &uart1_ick, CK_243X), CLK(NULL, "uart1_fck", &uart1_fck, CK_243X), CLK(NULL, "uart2_ick", &uart2_ick, CK_243X), @@ -1958,7 +1958,7 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "gpios_ick", &gpios_ick, CK_243X), CLK(NULL, "gpios_fck", &gpios_fck, CK_243X), CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X), - CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X), + CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_243X), CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X), CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X), CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X), @@ -1975,9 +1975,9 @@ static struct omap_clk omap2430_clks[] = { CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X), CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X), CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X), - CLK("omap_i2c.1", "fck", &i2chs1_fck, CK_243X), + CLK(NULL, "i2chs1_fck", &i2chs1_fck, CK_243X), CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X), - CLK("omap_i2c.2", "fck", &i2chs2_fck, CK_243X), + CLK(NULL, "i2chs2_fck", &i2chs2_fck, CK_243X), CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X), CLK(NULL, "sdma_fck", &sdma_fck, CK_243X), CLK(NULL, "sdma_ick", &sdma_ick, CK_243X), @@ -1990,9 +1990,9 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "usb_fck", &usb_fck, CK_243X), CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X), CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X), - CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_243X), + CLK(NULL, "mmchs1_fck", &mmchs1_fck, CK_243X), CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X), - CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_243X), + CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_243X), CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X), CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X), CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 75b119b..b9b8446 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3078,6 +3078,7 @@ static struct clk gpt12_fck = { .name = "gpt12_fck", .ops = &clkops_null, .parent = &secure_32k_fck, + .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -3085,6 +3086,7 @@ static struct clk wdt1_fck = { .name = "wdt1_fck", .ops = &clkops_null, .parent = &secure_32k_fck, + .clkdm_name = "wkup_clkdm", .recalc = &followparent_recalc, }; @@ -3289,25 +3291,25 @@ static struct omap_clk omap3xxx_clks[] = { CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), - CLK("omap_hsmmc.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_3XXX), + CLK(NULL, "mmchs3_fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_3XXX), CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX), - CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_3XXX), - CLK("omap_i2c.3", "fck", &i2c3_fck, CK_3XXX), - CLK("omap_i2c.2", "fck", &i2c2_fck, CK_3XXX), - CLK("omap_i2c.1", "fck", &i2c1_fck, CK_3XXX), - CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_3XXX), - CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_3XXX), + CLK(NULL, "mmchs1_fck", &mmchs1_fck, CK_3XXX), + CLK(NULL, "i2c3_fck", &i2c3_fck, CK_3XXX), + CLK(NULL, "i2c2_fck", &i2c2_fck, CK_3XXX), + CLK(NULL, "i2c1_fck", &i2c1_fck, CK_3XXX), + CLK(NULL, "mcbsp5_fck", &mcbsp5_fck, CK_3XXX), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_3XXX), CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX), - CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_3XXX), - CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_3XXX), - CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_3XXX), - CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_3XXX), + CLK(NULL, "mcspi4_fck", &mcspi4_fck, CK_3XXX), + CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_3XXX), + CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_3XXX), + CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_3XXX), CLK(NULL, "uart2_fck", &uart2_fck, CK_3XXX), CLK(NULL, "uart1_fck", &uart1_fck, CK_3XXX), CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX), - CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX), + CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX), CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1), CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX), CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1), @@ -3356,11 +3358,11 @@ static struct omap_clk omap3xxx_clks[] = { CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), - CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1), - CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX), - CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX), - CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX), + CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), + CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_3XXX), + CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_3XXX), + CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_3XXX), CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1), CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), @@ -3385,7 +3387,7 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX), - CLK("omap_wdt", "fck", &wdt2_fck, CK_3XXX), + CLK(NULL, "wdt2_fck", &wdt2_fck, CK_3XXX), CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX), CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX), CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX), @@ -3436,9 +3438,9 @@ static struct omap_clk omap3xxx_clks[] = { CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX), CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX), CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX), - CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_3XXX), - CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_3XXX), - CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_3XXX), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_3XXX), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_3XXX), + CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_3XXX), CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX), CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX), CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX), diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 044df38..c0b6fbd 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -1397,6 +1397,40 @@ static struct clk dss_dss_clk = { .recalc = &followparent_recalc, }; +static const struct clksel_rate div3_8to32_rates[] = { + { .div = 8, .val = 0, .flags = RATE_IN_44XX }, + { .div = 16, .val = 1, .flags = RATE_IN_44XX }, + { .div = 32, .val = 2, .flags = RATE_IN_44XX }, + { .div = 0 }, +}; + +static const struct clksel div_ts_div[] = { + { .parent = &l4_wkup_clk_mux_ck, .rates = div3_8to32_rates }, + { .parent = NULL }, +}; + +static struct clk div_ts_ck = { + .name = "div_ts_ck", + .parent = &l4_wkup_clk_mux_ck, + .clksel = div_ts_div, + .clksel_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_24_25_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk bandgap_ts_fclk = { + .name = "bandgap_ts_fclk", + .ops = &clkops_omap2_dflt, + .enable_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, + .enable_bit = OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT, + .clkdm_name = "l4_wkup_clkdm", + .parent = &div_ts_ck, + .recalc = &followparent_recalc, +}; + static struct clk dss_48mhz_clk = { .name = "dss_48mhz_clk", .ops = &clkops_omap2_dflt, @@ -1605,6 +1639,7 @@ static struct clk gpmc_ick = { .ops = &clkops_omap2_dflt, .enable_reg = OMAP4430_CM_L3_2_GPMC_CLKCTRL, .enable_bit = OMAP4430_MODULEMODE_HWCTRL, + .flags = ENABLE_ON_INIT, .clkdm_name = "l3_2_clkdm", .parent = &l3_div_ck, .recalc = &followparent_recalc, @@ -2773,19 +2808,39 @@ static struct clk trace_clk_div_ck = { /* SCRM aux clk nodes */ -static const struct clksel auxclk_sel[] = { +static const struct clksel auxclk_src_sel[] = { { .parent = &sys_clkin_ck, .rates = div_1_0_rates }, { .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates }, { .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates }, { .parent = NULL }, }; -static struct clk auxclk0_ck = { - .name = "auxclk0_ck", +static const struct clksel_rate div16_1to16_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_4430 }, + { .div = 2, .val = 1, .flags = RATE_IN_4430 }, + { .div = 3, .val = 2, .flags = RATE_IN_4430 }, + { .div = 4, .val = 3, .flags = RATE_IN_4430 }, + { .div = 5, .val = 4, .flags = RATE_IN_4430 }, + { .div = 6, .val = 5, .flags = RATE_IN_4430 }, + { .div = 7, .val = 6, .flags = RATE_IN_4430 }, + { .div = 8, .val = 7, .flags = RATE_IN_4430 }, + { .div = 9, .val = 8, .flags = RATE_IN_4430 }, + { .div = 10, .val = 9, .flags = RATE_IN_4430 }, + { .div = 11, .val = 10, .flags = RATE_IN_4430 }, + { .div = 12, .val = 11, .flags = RATE_IN_4430 }, + { .div = 13, .val = 12, .flags = RATE_IN_4430 }, + { .div = 14, .val = 13, .flags = RATE_IN_4430 }, + { .div = 15, .val = 14, .flags = RATE_IN_4430 }, + { .div = 16, .val = 15, .flags = RATE_IN_4430 }, + { .div = 0 }, +}; + +static struct clk auxclk0_src_ck = { + .name = "auxclk0_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK0, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2793,12 +2848,29 @@ static struct clk auxclk0_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; -static struct clk auxclk1_ck = { - .name = "auxclk1_ck", +static const struct clksel auxclk0_sel[] = { + { .parent = &auxclk0_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk0_ck = { + .name = "auxclk0_ck", + .parent = &auxclk0_src_ck, + .clksel = auxclk0_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK0, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk auxclk1_src_ck = { + .name = "auxclk1_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK1, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2806,12 +2878,29 @@ static struct clk auxclk1_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; -static struct clk auxclk2_ck = { - .name = "auxclk2_ck", +static const struct clksel auxclk1_sel[] = { + { .parent = &auxclk1_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk1_ck = { + .name = "auxclk1_ck", + .parent = &auxclk1_src_ck, + .clksel = auxclk1_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK1, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk auxclk2_src_ck = { + .name = "auxclk2_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK2, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2819,12 +2908,29 @@ static struct clk auxclk2_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; -static struct clk auxclk3_ck = { - .name = "auxclk3_ck", +static const struct clksel auxclk2_sel[] = { + { .parent = &auxclk2_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk2_ck = { + .name = "auxclk2_ck", + .parent = &auxclk2_src_ck, + .clksel = auxclk2_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK2, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk auxclk3_src_ck = { + .name = "auxclk3_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK3, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2832,12 +2938,29 @@ static struct clk auxclk3_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; -static struct clk auxclk4_ck = { - .name = "auxclk4_ck", +static const struct clksel auxclk3_sel[] = { + { .parent = &auxclk3_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk3_ck = { + .name = "auxclk3_ck", + .parent = &auxclk3_src_ck, + .clksel = auxclk3_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK3, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk auxclk4_src_ck = { + .name = "auxclk4_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK4, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2845,12 +2968,29 @@ static struct clk auxclk4_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; -static struct clk auxclk5_ck = { - .name = "auxclk5_ck", +static const struct clksel auxclk4_sel[] = { + { .parent = &auxclk4_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk4_ck = { + .name = "auxclk4_ck", + .parent = &auxclk4_src_ck, + .clksel = auxclk4_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK4, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + +static struct clk auxclk5_src_ck = { + .name = "auxclk5_src_ck", .parent = &sys_clkin_ck, .init = &omap2_init_clksel_parent, .ops = &clkops_omap2_dflt, - .clksel = auxclk_sel, + .clksel = auxclk_src_sel, .clksel_reg = OMAP4_SCRM_AUXCLK5, .clksel_mask = OMAP4_SRCSELECT_MASK, .recalc = &omap2_clksel_recalc, @@ -2858,6 +2998,23 @@ static struct clk auxclk5_ck = { .enable_bit = OMAP4_ENABLE_SHIFT, }; +static const struct clksel auxclk5_sel[] = { + { .parent = &auxclk5_src_ck, .rates = div16_1to16_rates }, + { .parent = NULL }, +}; + +static struct clk auxclk5_ck = { + .name = "auxclk5_ck", + .parent = &auxclk5_src_ck, + .clksel = auxclk5_sel, + .clksel_reg = OMAP4_SCRM_AUXCLK5, + .clksel_mask = OMAP4_CLKDIV_MASK, + .ops = &clkops_null, + .recalc = &omap2_clksel_recalc, + .round_rate = &omap2_clksel_round_rate, + .set_rate = &omap2_clksel_set_rate, +}; + static const struct clksel auxclkreq_sel[] = { { .parent = &auxclk0_ck, .rates = div_1_0_rates }, { .parent = &auxclk1_ck, .rates = div_1_1_rates }, @@ -3028,14 +3185,16 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "aes2_fck", &aes2_fck, CK_443X), CLK(NULL, "aess_fck", &aess_fck, CK_443X), CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X), + CLK(NULL, "bandgap_ts_fclk", &bandgap_ts_fclk, CK_446X), CLK(NULL, "des3des_fck", &des3des_fck, CK_443X), + CLK(NULL, "div_ts_ck", &div_ts_ck, CK_446X), CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), - CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X), - CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X), - CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X), - CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X), + CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), + CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), + CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), + CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), CLK("omapdss_dss", "ick", &dss_fck, CK_443X), CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), @@ -3056,12 +3215,12 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X), CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X), CLK(NULL, "gpu_fck", &gpu_fck, CK_443X), - CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_443X), + CLK(NULL, "hdq1w_fck", &hdq1w_fck, CK_443X), CLK(NULL, "hsi_fck", &hsi_fck, CK_443X), - CLK("omap_i2c.1", "fck", &i2c1_fck, CK_443X), - CLK("omap_i2c.2", "fck", &i2c2_fck, CK_443X), - CLK("omap_i2c.3", "fck", &i2c3_fck, CK_443X), - CLK("omap_i2c.4", "fck", &i2c4_fck, CK_443X), + CLK(NULL, "i2c1_fck", &i2c1_fck, CK_443X), + CLK(NULL, "i2c2_fck", &i2c2_fck, CK_443X), + CLK(NULL, "i2c3_fck", &i2c3_fck, CK_443X), + CLK(NULL, "i2c4_fck", &i2c4_fck, CK_443X), CLK(NULL, "ipu_fck", &ipu_fck, CK_443X), CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X), CLK(NULL, "iss_fck", &iss_fck, CK_443X), @@ -3072,23 +3231,23 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X), CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X), CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X), - CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_443X), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_443X), CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X), - CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_443X), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_443X), CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X), - CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_443X), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_443X), CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X), - CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_443X), + CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_443X), CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X), - CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_443X), - CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_443X), - CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_443X), - CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_443X), - CLK("omap_hsmmc.0", "fck", &mmc1_fck, CK_443X), - CLK("omap_hsmmc.1", "fck", &mmc2_fck, CK_443X), - CLK("omap_hsmmc.2", "fck", &mmc3_fck, CK_443X), - CLK("omap_hsmmc.3", "fck", &mmc4_fck, CK_443X), - CLK("omap_hsmmc.4", "fck", &mmc5_fck, CK_443X), + CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_443X), + CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_443X), + CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_443X), + CLK(NULL, "mcspi4_fck", &mcspi4_fck, CK_443X), + CLK(NULL, "mmc1_fck", &mmc1_fck, CK_443X), + CLK(NULL, "mmc2_fck", &mmc2_fck, CK_443X), + CLK(NULL, "mmc3_fck", &mmc3_fck, CK_443X), + CLK(NULL, "mmc4_fck", &mmc4_fck, CK_443X), + CLK(NULL, "mmc5_fck", &mmc5_fck, CK_443X), CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X), CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X), @@ -3145,21 +3304,27 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "usim_ck", &usim_ck, CK_443X), CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), CLK(NULL, "usim_fck", &usim_fck, CK_443X), - CLK("omap_wdt", "fck", &wd_timer2_fck, CK_443X), + CLK(NULL, "wd_timer2_fck", &wd_timer2_fck, CK_443X), CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X), CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X), CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_443X), + CLK(NULL, "auxclk0_src_ck", &auxclk0_src_ck, CK_443X), CLK(NULL, "auxclk0_ck", &auxclk0_ck, CK_443X), - CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_443X), - CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_443X), - CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_443X), - CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_443X), - CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X), CLK(NULL, "auxclkreq0_ck", &auxclkreq0_ck, CK_443X), + CLK(NULL, "auxclk1_src_ck", &auxclk1_src_ck, CK_443X), + CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_443X), CLK(NULL, "auxclkreq1_ck", &auxclkreq1_ck, CK_443X), + CLK(NULL, "auxclk2_src_ck", &auxclk2_src_ck, CK_443X), + CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_443X), CLK(NULL, "auxclkreq2_ck", &auxclkreq2_ck, CK_443X), + CLK(NULL, "auxclk3_src_ck", &auxclk3_src_ck, CK_443X), + CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_443X), CLK(NULL, "auxclkreq3_ck", &auxclkreq3_ck, CK_443X), + CLK(NULL, "auxclk4_src_ck", &auxclk4_src_ck, CK_443X), + CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_443X), CLK(NULL, "auxclkreq4_ck", &auxclkreq4_ck, CK_443X), + CLK(NULL, "auxclk5_src_ck", &auxclk5_src_ck, CK_443X), + CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X), CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X), CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X), CLK(NULL, "gpt1_ick", &dummy_ck, CK_443X), @@ -3208,10 +3373,22 @@ int __init omap4xxx_clk_init(void) if (cpu_is_omap44xx()) { cpu_mask = RATE_IN_4430; cpu_clkflg = CK_443X; + } else if (cpu_is_omap446x()) { + cpu_mask = RATE_IN_4460; + cpu_clkflg = CK_446X; + } else { + return 0; } clk_init(&omap2_clk_functions); + /* + * Must stay commented until all OMAP SoC drivers are + * converted to runtime PM, or drivers may start crashing + * + * omap2_clk_disable_clkdm_control(); + */ + for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks); c++) clk_preinit(c->lk.clk); diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 6cb6c03..8f08906 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -1,8 +1,8 @@ /* * OMAP2/3/4 clockdomain framework functions * - * Copyright (C) 2008-2010 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2011 Nokia Corporation * * Written by Paul Walmsley and Jouni Högander * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> @@ -92,6 +92,8 @@ static int _clkdm_register(struct clockdomain *clkdm) pwrdm_add_clkdm(pwrdm, clkdm); + spin_lock_init(&clkdm->lock); + pr_debug("clockdomain: registered %s\n", clkdm->name); return 0; @@ -690,6 +692,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) */ int clkdm_sleep(struct clockdomain *clkdm) { + int ret; + unsigned long flags; + if (!clkdm) return -EINVAL; @@ -704,7 +709,11 @@ int clkdm_sleep(struct clockdomain *clkdm) pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - return arch_clkdm->clkdm_sleep(clkdm); + spin_lock_irqsave(&clkdm->lock, flags); + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; + ret = arch_clkdm->clkdm_sleep(clkdm); + spin_unlock_irqrestore(&clkdm->lock, flags); + return ret; } /** @@ -718,6 +727,9 @@ int clkdm_sleep(struct clockdomain *clkdm) */ int clkdm_wakeup(struct clockdomain *clkdm) { + int ret; + unsigned long flags; + if (!clkdm) return -EINVAL; @@ -732,7 +744,12 @@ int clkdm_wakeup(struct clockdomain *clkdm) pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - return arch_clkdm->clkdm_wakeup(clkdm); + spin_lock_irqsave(&clkdm->lock, flags); + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; + ret = arch_clkdm->clkdm_wakeup(clkdm); + ret |= pwrdm_state_switch(clkdm->pwrdm.ptr); + spin_unlock_irqrestore(&clkdm->lock, flags); + return ret; } /** @@ -747,6 +764,8 @@ int clkdm_wakeup(struct clockdomain *clkdm) */ void clkdm_allow_idle(struct clockdomain *clkdm) { + unsigned long flags; + if (!clkdm) return; @@ -762,8 +781,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm) pr_debug("clockdomain: enabling automatic idle transitions for %s\n", clkdm->name); + spin_lock_irqsave(&clkdm->lock, flags); + clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; arch_clkdm->clkdm_allow_idle(clkdm); pwrdm_clkdm_state_switch(clkdm); + spin_unlock_irqrestore(&clkdm->lock, flags); } /** @@ -777,6 +799,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm) */ void clkdm_deny_idle(struct clockdomain *clkdm) { + unsigned long flags; + if (!clkdm) return; @@ -792,11 +816,91 @@ void clkdm_deny_idle(struct clockdomain *clkdm) pr_debug("clockdomain: disabling automatic idle transitions for %s\n", clkdm->name); + spin_lock_irqsave(&clkdm->lock, flags); + clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED; arch_clkdm->clkdm_deny_idle(clkdm); + pwrdm_state_switch(clkdm->pwrdm.ptr); + spin_unlock_irqrestore(&clkdm->lock, flags); +} + +/** + * clkdm_in_hwsup - is clockdomain @clkdm have hardware-supervised idle enabled? + * @clkdm: struct clockdomain * + * + * Returns true if clockdomain @clkdm currently has + * hardware-supervised idle enabled, or false if it does not or if + * @clkdm is NULL. It is only valid to call this function after + * clkdm_init() has been called. This function does not actually read + * bits from the hardware; it instead tests an in-memory flag that is + * changed whenever the clockdomain code changes the auto-idle mode. + */ +bool clkdm_in_hwsup(struct clockdomain *clkdm) +{ + bool ret; + unsigned long flags; + + if (!clkdm) + return false; + + spin_lock_irqsave(&clkdm->lock, flags); + ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; + spin_unlock_irqrestore(&clkdm->lock, flags); + + return ret; +} + +/* Clockdomain-to-clock/hwmod framework interface code */ + +static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) +{ + unsigned long flags; + + if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) + return -EINVAL; + + /* + * For arch's with no autodeps, clkcm_clk_enable + * should be called for every clock instance or hwmod that is + * enabled, so the clkdm can be force woken up. + */ + if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) + return 0; + + spin_lock_irqsave(&clkdm->lock, flags); + arch_clkdm->clkdm_clk_enable(clkdm); + pwrdm_wait_transition(clkdm->pwrdm.ptr); + pwrdm_clkdm_state_switch(clkdm); + spin_unlock_irqrestore(&clkdm->lock, flags); + + pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name); + + return 0; } +static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm) +{ + unsigned long flags; + + if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) + return -EINVAL; + + if (atomic_read(&clkdm->usecount) == 0) { + WARN_ON(1); /* underflow */ + return -ERANGE; + } + + if (atomic_dec_return(&clkdm->usecount) > 0) + return 0; + + spin_lock_irqsave(&clkdm->lock, flags); + arch_clkdm->clkdm_clk_disable(clkdm); + pwrdm_clkdm_state_switch(clkdm); + spin_unlock_irqrestore(&clkdm->lock, flags); -/* Clockdomain-to-clock framework interface code */ + pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name); + + return 0; +} /** * clkdm_clk_enable - add an enabled downstream clock to this clkdm @@ -819,25 +923,10 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clk) return -EINVAL; - if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable) - return -EINVAL; - - if (atomic_inc_return(&clkdm->usecount) > 1) - return 0; - - /* Clockdomain now has one enabled downstream clock */ - - pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name, - clk->name); - - arch_clkdm->clkdm_clk_enable(clkdm); - pwrdm_wait_transition(clkdm->pwrdm.ptr); - pwrdm_clkdm_state_switch(clkdm); - - return 0; + return _clkdm_clk_hwmod_enable(clkdm); } /** @@ -850,9 +939,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) * clockdomain usecount goes to 0, put the clockdomain to sleep * (software-supervised mode) or remove the clkdm autodependencies * (hardware-supervised mode). Returns -EINVAL if passed null - * pointers; -ERANGE if the @clkdm usecount underflows and debugging - * is enabled; or returns 0 upon success or if the clockdomain is in - * hwsup idle mode. + * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0 + * upon success or if the clockdomain is in hwsup idle mode. */ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) { @@ -861,30 +949,72 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clk) return -EINVAL; - if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable) + return _clkdm_clk_hwmod_disable(clkdm); +} + +/** + * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm + * @clkdm: struct clockdomain * + * @oh: struct omap_hwmod * of the enabled downstream hwmod + * + * Increment the usecount of the clockdomain @clkdm and ensure that it + * is awake before @oh is enabled. Intended to be called by + * module_enable() code. + * If the clockdomain is in software-supervised idle mode, force the + * clockdomain to wake. If the clockdomain is in hardware-supervised idle + * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the + * clockdomain can be read from/written to by on-chip processors. + * Returns -EINVAL if passed null pointers; + * returns 0 upon success or if the clockdomain is in hwsup idle mode. + */ +int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh) +{ + /* The clkdm attribute does not exist yet prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return 0; + + /* + * XXX Rewrite this code to maintain a list of enabled + * downstream hwmods for debugging purposes? + */ + + if (!oh) return -EINVAL; -#ifdef DEBUG - if (atomic_read(&clkdm->usecount) == 0) { - WARN_ON(1); /* underflow */ - return -ERANGE; - } -#endif + return _clkdm_clk_hwmod_enable(clkdm); +} - if (atomic_dec_return(&clkdm->usecount) > 0) +/** + * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm + * @clkdm: struct clockdomain * + * @oh: struct omap_hwmod * of the disabled downstream hwmod + * + * Decrement the usecount of this clockdomain @clkdm when @oh is + * disabled. Intended to be called by module_disable() code. + * If the clockdomain usecount goes to 0, put the clockdomain to sleep + * (software-supervised mode) or remove the clkdm autodependencies + * (hardware-supervised mode). + * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount + * underflows; or returns 0 upon success or if the clockdomain is in hwsup + * idle mode. + */ +int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) +{ + /* The clkdm attribute does not exist yet prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) return 0; - /* All downstream clocks of this clockdomain are now disabled */ - - pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, - clk->name); + /* + * XXX Rewrite this code to maintain a list of enabled + * downstream hwmods for debugging purposes? + */ - arch_clkdm->clkdm_clk_disable(clkdm); - pwrdm_clkdm_state_switch(clkdm); + if (!oh) + return -EINVAL; - return 0; + return _clkdm_clk_hwmod_disable(clkdm); } diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 5823584..1e50c88 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -17,9 +17,11 @@ #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H #include <linux/init.h> +#include <linux/spinlock.h> #include "powerdomain.h" #include <plat/clock.h> +#include <plat/omap_hwmod.h> #include <plat/cpu.h> /* @@ -82,6 +84,9 @@ struct clkdm_dep { const struct omap_chip_id omap_chip; }; +/* Possible flags for struct clockdomain._flags */ +#define _CLKDM_FLAG_HWSUP_ENABLED BIT(0) + /** * struct clockdomain - OMAP clockdomain * @name: clockdomain name @@ -89,6 +94,7 @@ struct clkdm_dep { * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg * @flags: Clockdomain capability flags + * @_flags: Flags for use only by internal clockdomain code * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers * @cm_inst: (OMAP4 only) CM instance register offset @@ -113,6 +119,7 @@ struct clockdomain { } pwrdm; const u16 clktrctrl_mask; const u8 flags; + u8 _flags; const u8 dep_bit; const u8 prcm_partition; const s16 cm_inst; @@ -122,6 +129,7 @@ struct clockdomain { const struct omap_chip_id omap_chip; atomic_t usecount; struct list_head node; + spinlock_t lock; }; /** @@ -177,12 +185,15 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); void clkdm_allow_idle(struct clockdomain *clkdm); void clkdm_deny_idle(struct clockdomain *clkdm); +bool clkdm_in_hwsup(struct clockdomain *clkdm); int clkdm_wakeup(struct clockdomain *clkdm); int clkdm_sleep(struct clockdomain *clkdm); int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); +int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); +int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); extern void __init omap2xxx_clockdomains_init(void); extern void __init omap3xxx_clockdomains_init(void); diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c index 48d0db7..f740edb 100644 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c @@ -183,7 +183,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm) _clkdm_add_autodeps(clkdm); _enable_hwsup(clkdm); } else { - clkdm_wakeup(clkdm); + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + omap2_clkdm_wakeup(clkdm); } return 0; @@ -205,7 +206,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm) _clkdm_del_autodeps(clkdm); _enable_hwsup(clkdm); } else { - clkdm_sleep(clkdm); + if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) + omap2_clkdm_sleep(clkdm); } return 0; diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c index a1a4ecd..b43706a 100644 --- a/arch/arm/mach-omap2/clockdomain44xx.c +++ b/arch/arm/mach-omap2/clockdomain44xx.c @@ -95,13 +95,8 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) { - bool hwsup = false; - - hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, - clkdm->cm_inst, clkdm->clkdm_offs); - - if (!hwsup) - clkdm_wakeup(clkdm); + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + return omap4_clkdm_wakeup(clkdm); return 0; } @@ -113,8 +108,8 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, clkdm->cm_inst, clkdm->clkdm_offs); - if (!hwsup) - clkdm_sleep(clkdm); + if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) + omap4_clkdm_sleep(clkdm); return 0; } diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 66090f2..dccc651 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -565,7 +565,7 @@ static struct clockdomain ducati_44xx_clkdm = { }; static struct clockdomain mpu_44xx_clkdm = { - .name = "mpu_clkdm", + .name = "mpuss_clkdm", .pwrdm = { .name = "mpu_pwrdm" }, .prcm_partition = OMAP4430_CM1_PARTITION, .cm_inst = OMAP4430_CM1_MPU_INST, diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h index 0e77945..65597a7 100644 --- a/arch/arm/mach-omap2/cm-regbits-44xx.h +++ b/arch/arm/mach-omap2/cm-regbits-44xx.h @@ -101,6 +101,10 @@ #define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT 9 #define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK (1 << 9) +/* Used by CM_L4CFG_CLKSTCTRL */ +#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_SHIFT 9 +#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_MASK (1 << 9) + /* Used by CM_CEFUSE_CLKSTCTRL */ #define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9 #define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9) @@ -413,6 +417,10 @@ #define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT 11 #define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK (1 << 11) +/* Used by CM_WKUP_CLKSTCTRL */ +#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_SHIFT 13 +#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_MASK (1 << 13) + /* * Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, * CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, @@ -444,6 +452,10 @@ #define OMAP4430_CLKSEL_60M_SHIFT 24 #define OMAP4430_CLKSEL_60M_MASK (1 << 24) +/* Used by CM_MPU_MPU_CLKCTRL */ +#define OMAP4460_CLKSEL_ABE_DIV_MODE_SHIFT 25 +#define OMAP4460_CLKSEL_ABE_DIV_MODE_MASK (1 << 25) + /* Used by CM1_ABE_AESS_CLKCTRL */ #define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24 #define OMAP4430_CLKSEL_AESS_FCLK_MASK (1 << 24) @@ -460,6 +472,10 @@ #define OMAP4430_CLKSEL_DIV_SHIFT 24 #define OMAP4430_CLKSEL_DIV_MASK (1 << 24) +/* Used by CM_MPU_MPU_CLKCTRL */ +#define OMAP4460_CLKSEL_EMIF_DIV_MODE_SHIFT 24 +#define OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK (1 << 24) + /* Used by CM_CAM_FDIF_CLKCTRL */ #define OMAP4430_CLKSEL_FCLK_SHIFT 24 #define OMAP4430_CLKSEL_FCLK_MASK (0x3 << 24) @@ -555,6 +571,14 @@ #define OMAP4430_D2D_STATDEP_SHIFT 18 #define OMAP4430_D2D_STATDEP_MASK (1 << 18) +/* Used by CM_CLKSEL_DPLL_MPU */ +#define OMAP4460_DCC_COUNT_MAX_SHIFT 24 +#define OMAP4460_DCC_COUNT_MAX_MASK (0xff << 24) + +/* Used by CM_CLKSEL_DPLL_MPU */ +#define OMAP4460_DCC_EN_SHIFT 22 +#define OMAP4460_DCC_EN_MASK (1 << 22) + /* * Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE, * CM_SSC_DELTAMSTEP_DPLL_DDRPHY, CM_SSC_DELTAMSTEP_DPLL_IVA, @@ -564,6 +588,10 @@ #define OMAP4430_DELTAMSTEP_SHIFT 0 #define OMAP4430_DELTAMSTEP_MASK (0xfffff << 0) +/* Renamed from DELTAMSTEP Used by CM_SSC_DELTAMSTEP_DPLL_USB */ +#define OMAP4460_DELTAMSTEP_0_20_SHIFT 0 +#define OMAP4460_DELTAMSTEP_0_20_MASK (0x1fffff << 0) + /* Used by CM_DLL_CTRL */ #define OMAP4430_DLL_OVERRIDE_SHIFT 0 #define OMAP4430_DLL_OVERRIDE_MASK (1 << 0) @@ -1106,6 +1134,10 @@ #define OMAP4430_MODULEMODE_SHIFT 0 #define OMAP4430_MODULEMODE_MASK (0x3 << 0) +/* Used by CM_L4CFG_DYNAMICDEP */ +#define OMAP4460_MPU_DYNDEP_SHIFT 19 +#define OMAP4460_MPU_DYNDEP_MASK (1 << 19) + /* Used by CM_DSS_DSS_CLKCTRL */ #define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9 #define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK (1 << 9) @@ -1198,6 +1230,10 @@ #define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10 #define OMAP4430_OPTFCLKEN_SYS_CLK_MASK (1 << 10) +/* Used by CM_WKUP_BANDGAP_CLKCTRL */ +#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT 8 +#define OMAP4460_OPTFCLKEN_TS_FCLK_MASK (1 << 8) + /* Used by CM_DSS_DSS_CLKCTRL */ #define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11 #define OMAP4430_OPTFCLKEN_TV_CLK_MASK (1 << 11) diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index 0b87ec8..3380bee 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h @@ -1,7 +1,7 @@ /* * OMAP4 Clock Management (CM) definitions * - * Copyright (C) 2007-2009 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Texas Instruments, Inc. * Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley @@ -23,10 +23,4 @@ #define OMAP4_CM_CLKSTCTRL 0x0000 #define OMAP4_CM_STATICDEP 0x0004 -/* Function prototypes */ -# ifndef __ASSEMBLER__ - -extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg); - -# endif #endif diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index a482bfa..eb2a472 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -2,6 +2,7 @@ * OMAP4 CM instance functions * * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. * Paul Walmsley * * This program is free software; you can redistribute it and/or modify @@ -32,6 +33,22 @@ #include "prm44xx.h" #include "prcm_mpu44xx.h" +/* + * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: + * + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed + * + */ +#define CLKCTRL_IDLEST_FUNCTIONAL 0x0 +#define CLKCTRL_IDLEST_INTRANSITION 0x1 +#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 +#define CLKCTRL_IDLEST_DISABLED 0x3 + static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { [OMAP4430_INVALID_PRCM_PARTITION] = 0, [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE, @@ -41,6 +58,48 @@ static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE, }; +/* Private functions */ + +/** + * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to + * bit 0. + */ +static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= OMAP4430_IDLEST_MASK; + v >>= OMAP4430_IDLEST_SHIFT; + return v; +} + +/** + * _is_module_ready - can module registers be accessed without causing an abort? + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either + * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. + */ +static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) +{ + u32 v; + + v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs); + + return (v == CLKCTRL_IDLEST_FUNCTIONAL || + v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; +} + +/* Public functions */ + /* Read a register in a CM instance */ u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) { @@ -200,36 +259,93 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs) */ /** - * omap4_cm_wait_module_ready - wait for a module to be in 'func' state - * @clkctrl_reg: CLKCTRL module address + * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * * Wait for the module IDLEST to be functional. If the idle state is in any * the non functional state (trans, idle or disabled), module and thus the * sysconfig cannot be accessed and will probably lead to an "imprecise * external abort" + */ +int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + int i = 0; + + if (!clkctrl_offs) + return 0; + + omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; +} + +/** + * omap4_cminst_wait_module_idle - wait for a module to be in 'disabled' + * state + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) * - * Module idle state: - * 0x0 func: Module is fully functional, including OCP - * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep - * abortion - * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if - * using separate functional clock - * 0x3 disabled: Module is disabled and cannot be accessed - * + * Wait for the module IDLEST to be disabled. Some PRCM transition, + * like reset assertion or parent clock de-activation must wait the + * module to be fully disabled. */ -int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg) +int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) { int i = 0; - if (!clkctrl_reg) + if (!clkctrl_offs) return 0; - omap_test_timeout(( - ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) || - (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >> - OMAP4430_IDLEST_SHIFT) == 0x2)), - MAX_MODULE_READY_TIME, i); + omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == + CLKCTRL_IDLEST_DISABLED), + MAX_MODULE_READY_TIME, i); return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; } +/** + * omap4_cminst_module_enable - Enable the modulemode inside CLKCTRL + * @mode: Module mode (SW or HW) + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= ~OMAP4430_MODULEMODE_MASK; + v |= mode << OMAP4430_MODULEMODE_SHIFT; + omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); +} + +/** + * omap4_cminst_module_disable - Disable the module inside CLKCTRL + * @part: PRCM partition ID that the CM_CLKCTRL register exists in + * @inst: CM instance register offset (*_INST macro) + * @cdoffs: Clockdomain register offset (*_CDOFFS macro) + * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) + * + * No return value. + */ +void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); + v &= ~OMAP4430_MODULEMODE_MASK; + omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs); +} diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h index 2b32c18..a018a73 100644 --- a/arch/arm/mach-omap2/cminst44xx.h +++ b/arch/arm/mach-omap2/cminst44xx.h @@ -17,6 +17,37 @@ extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs); extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs); extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); +extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); + +# ifdef CONFIG_ARCH_OMAP4 +extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); + +extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); +extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs); + +# else + +static inline int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ + return 0; +} + +static inline void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, + s16 cdoffs, u16 clkctrl_offs) +{ +} + +static inline void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, + u16 clkctrl_offs) +{ +} + +# endif + /* * In an ideal world, we would not export these low-level functions, * but this will probably take some time to fix properly @@ -32,6 +63,4 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask); -extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg); - #endif diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 5b8ca68..1077ad6 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -230,7 +230,7 @@ struct omap_device_pm_latency omap_keyboard_latency[] = { }; int __init omap4_keyboard_init(struct omap4_keypad_platform_data - *sdp4430_keypad_data) + *sdp4430_keypad_data, struct omap_board_data *bdata) { struct omap_device *od; struct omap_hwmod *oh; @@ -257,6 +257,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data name, oh->name); return PTR_ERR(od); } + oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); return 0; } diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 543fcb8..a5b7a236 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -25,6 +25,7 @@ #include <video/omapdss.h> #include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> static struct platform_device omap_display_device = { .name = "omapdss", @@ -42,20 +43,6 @@ static struct omap_device_pm_latency omap_dss_latency[] = { }, }; -/* oh_core is used for getting opt-clocks */ -static struct omap_hwmod *oh_core; - -static bool opt_clock_available(const char *clk_role) -{ - int i; - - for (i = 0; i < oh_core->opt_clks_cnt; i++) { - if (!strcmp(oh_core->opt_clks[i].role, clk_role)) - return true; - } - return false; -} - struct omap_dss_hwmod_data { const char *oh_name; const char *dev_name; @@ -109,16 +96,9 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); } - /* opt_clks are always associated with dss hwmod */ - oh_core = omap_hwmod_lookup("dss_core"); - if (!oh_core) { - pr_err("Could not look up dss_core.\n"); - return -ENODEV; - } - pdata.board_data = board_data; - pdata.board_data->get_last_off_on_transaction_id = NULL; - pdata.opt_clock_available = opt_clock_available; + pdata.board_data->get_context_loss_count = + omap_pm_get_dev_context_loss_count; for (i = 0; i < oh_count; i++) { oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 66868c5..a9b45c7 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -13,6 +13,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/delay.h> +#include <linux/gpio.h> #include <mach/hardware.h> #include <plat/mmc.h> #include <plat/omap-pm.h> @@ -213,12 +214,10 @@ static int nop_mmc_set_power(struct device *dev, int slot, int power_on, static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, int controller_nr) { - if ((mmc_controller->slots[0].switch_pin > 0) && \ - (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) + if (gpio_is_valid(mmc_controller->slots[0].switch_pin)) omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, OMAP_PIN_INPUT_PULLUP); - if ((mmc_controller->slots[0].gpio_wp > 0) && \ - (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) + if (gpio_is_valid(mmc_controller->slots[0].gpio_wp)) omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, OMAP_PIN_INPUT_PULLUP); if (cpu_is_omap34xx()) { diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index 79c478c..ace9994 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -21,9 +21,19 @@ #include <plat/cpu.h> #include <plat/i2c.h> +#include <plat/common.h> +#include <plat/omap_hwmod.h> #include "mux.h" +/* In register I2C_CON, Bit 15 is the I2C enable bit */ +#define I2C_EN BIT(15) +#define OMAP2_I2C_CON_OFFSET 0x24 +#define OMAP4_I2C_CON_OFFSET 0xA4 + +/* Maximum microseconds to wait for OMAP module to softreset */ +#define MAX_MODULE_SOFTRESET_WAIT 10000 + void __init omap2_i2c_mux_pins(int bus_id) { char mux_name[sizeof("i2c2_scl.i2c2_scl")]; @@ -37,3 +47,61 @@ void __init omap2_i2c_mux_pins(int bus_id) sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id); omap_mux_init_signal(mux_name, OMAP_PIN_INPUT); } + +/** + * omap_i2c_reset - reset the omap i2c module. + * @oh: struct omap_hwmod * + * + * The i2c moudle in omap2, omap3 had a special sequence to reset. The + * sequence is: + * - Disable the I2C. + * - Write to SOFTRESET bit. + * - Enable the I2C. + * - Poll on the RESETDONE bit. + * The sequence is implemented in below function. This is called for 2420, + * 2430 and omap3. + */ +int omap_i2c_reset(struct omap_hwmod *oh) +{ + u32 v; + u16 i2c_con; + int c = 0; + + if (oh->class->rev == OMAP_I2C_IP_VERSION_2) { + i2c_con = OMAP4_I2C_CON_OFFSET; + } else if (oh->class->rev == OMAP_I2C_IP_VERSION_1) { + i2c_con = OMAP2_I2C_CON_OFFSET; + } else { + WARN(1, "Cannot reset I2C block %s: unsupported revision\n", + oh->name); + return -EINVAL; + } + + /* Disable I2C */ + v = omap_hwmod_read(oh, i2c_con); + v &= ~I2C_EN; + omap_hwmod_write(v, oh, i2c_con); + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable I2C */ + v = omap_hwmod_read(oh, i2c_con); + v |= I2C_EN; + omap_hwmod_write(v, oh, i2c_con); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return 0; +} diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 2537090..37efb86 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -31,7 +31,7 @@ static struct omap_chip_id omap_chip; static unsigned int omap_revision; -u32 omap3_features; +u32 omap_features; unsigned int omap_rev(void) { @@ -183,14 +183,14 @@ static void __init omap24xx_check_revision(void) #define OMAP3_CHECK_FEATURE(status,feat) \ if (((status & OMAP3_ ##feat## _MASK) \ >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ - omap3_features |= OMAP3_HAS_ ##feat; \ + omap_features |= OMAP3_HAS_ ##feat; \ } static void __init omap3_check_features(void) { u32 status; - omap3_features = 0; + omap_features = 0; status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS); @@ -200,11 +200,11 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, NEON); OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) - omap3_features |= OMAP3_HAS_192MHZ_CLK; + omap_features |= OMAP3_HAS_192MHZ_CLK; if (!cpu_is_omap3505() && !cpu_is_omap3517()) - omap3_features |= OMAP3_HAS_IO_WAKEUP; + omap_features |= OMAP3_HAS_IO_WAKEUP; - omap3_features |= OMAP3_HAS_SDRC; + omap_features |= OMAP3_HAS_SDRC; /* * TODO: Get additional info (where applicable) @@ -212,9 +212,34 @@ static void __init omap3_check_features(void) */ } +static void __init omap4_check_features(void) +{ + u32 si_type; + + if (cpu_is_omap443x()) + omap_features |= OMAP4_HAS_MPU_1GHZ; + + + if (cpu_is_omap446x()) { + si_type = + read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1); + switch ((si_type & (3 << 16)) >> 16) { + case 2: + /* High performance device */ + omap_features |= OMAP4_HAS_MPU_1_5GHZ; + break; + case 1: + default: + /* Standard device */ + omap_features |= OMAP4_HAS_MPU_1_2GHZ; + break; + } + } +} + static void __init ti816x_check_features(void) { - omap3_features = OMAP3_HAS_NEON; + omap_features = OMAP3_HAS_NEON; } static void __init omap3_check_revision(void) @@ -344,10 +369,10 @@ static void __init omap4_check_revision(void) rev = (idcode >> 28) & 0xf; /* - * Few initial ES2.0 samples IDCODE is same as ES1.0 + * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 * Use ARM register to detect the correct ES version */ - if (!rev) { + if (!rev && (hawkeye != 0xb94e)) { idcode = read_cpuid(CPUID_ID); rev = (idcode & 0xf) - 1; } @@ -377,6 +402,15 @@ static void __init omap4_check_revision(void) omap_chip.oc |= CHIP_IS_OMAP4430ES2_2; } break; + case 0xb94e: + switch (rev) { + case 0: + default: + omap_revision = OMAP4460_REV_ES1_0; + omap_chip.oc |= CHIP_IS_OMAP4460ES1_0; + break; + } + break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP4430_REV_ES2_2; @@ -518,6 +552,7 @@ void __init omap2_check_revision(void) return; } else if (cpu_is_omap44xx()) { omap4_check_revision(); + omap4_check_features(); return; } else { pr_err("OMAP revision unknown, please fix!\n"); diff --git a/arch/arm/mach-omap2/include/mach/clkdev.h b/arch/arm/mach-omap2/include/mach/clkdev.h deleted file mode 100644 index 53b0274..0000000 --- a/arch/arm/mach-omap2/include/mach/clkdev.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/clkdev.h - */ - -#include <plat/clkdev.h> diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index adb083e..f286012 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -225,8 +225,8 @@ static u32 omap2_get_pte_attr(struct iotlb_entry *e) attr = e->mixed << 5; attr |= e->endian; attr |= e->elsz >> 3; - attr <<= ((e->pgsz & MMU_CAM_PGSZ_4K) ? 0 : 6); - + attr <<= (((e->pgsz == MMU_CAM_PGSZ_4K) || + (e->pgsz == MMU_CAM_PGSZ_64K)) ? 0 : 6); return attr; } diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index c7fb22a..655e948 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -821,11 +821,10 @@ static void __init omap_mux_set_cmdline_signals(void) if (!omap_mux_options) return; - options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL); + options = kstrdup(omap_mux_options, GFP_KERNEL); if (!options) return; - strcpy(options, omap_mux_options); next_opt = options; while ((token = strsep(&next_opt, ",")) != NULL) { @@ -855,24 +854,19 @@ static int __init omap_mux_copy_names(struct omap_mux *src, for (i = 0; i < OMAP_MUX_NR_MODES; i++) { if (src->muxnames[i]) { - dst->muxnames[i] = - kmalloc(strlen(src->muxnames[i]) + 1, - GFP_KERNEL); + dst->muxnames[i] = kstrdup(src->muxnames[i], + GFP_KERNEL); if (!dst->muxnames[i]) goto free; - strcpy(dst->muxnames[i], src->muxnames[i]); } } #ifdef CONFIG_DEBUG_FS for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { if (src->balls[i]) { - dst->balls[i] = - kmalloc(strlen(src->balls[i]) + 1, - GFP_KERNEL); + dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL); if (!dst->balls[i]) goto free; - strcpy(dst->balls[i], src->balls[i]); } } #endif diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 3fc5dc7..e61fead 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -67,7 +67,7 @@ static struct iommu_device omap4_devices[] = { .pdata = { .name = "ducati", .nr_tlb_entries = 32, - .clk_name = "ducati_ick", + .clk_name = "ipu_fck", .da_start = 0x0, .da_end = 0xFFFFF000, }, diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 7d242c9..84cc0bd 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -146,9 +146,10 @@ #include <plat/prcm.h> #include "cm2xxx_3xxx.h" -#include "cm44xx.h" +#include "cminst44xx.h" #include "prm2xxx_3xxx.h" #include "prm44xx.h" +#include "prminst44xx.h" #include "mux.h" /* Maximum microseconds to wait for OMAP module to softreset */ @@ -679,6 +680,56 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) } /** + * _enable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Enables the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _enable_module(struct omap_hwmod *oh) +{ + /* The module mode does not exist prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: _enable_module: %d\n", + oh->name, oh->prcm.omap4.modulemode); + + omap4_cminst_module_enable(oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _disable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Disable the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _disable_module(struct omap_hwmod *oh) +{ + /* The module mode does not exist prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: _disable_module\n", oh->name); + + omap4_cminst_module_disable(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh * @oh: struct omap_hwmod *oh * @@ -990,9 +1041,40 @@ static struct omap_hwmod *_lookup(const char *name) return oh; } +/** + * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod + * @oh: struct omap_hwmod * + * + * Convert a clockdomain name stored in a struct omap_hwmod into a + * clockdomain pointer, and save it into the struct omap_hwmod. + * return -EINVAL if clkdm_name does not exist or if the lookup failed. + */ +static int _init_clkdm(struct omap_hwmod *oh) +{ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return 0; + + if (!oh->clkdm_name) { + pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name); + return -EINVAL; + } + + oh->clkdm = clkdm_lookup(oh->clkdm_name); + if (!oh->clkdm) { + pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n", + oh->name, oh->clkdm_name); + return -EINVAL; + } + + pr_debug("omap_hwmod: %s: associated to clkdm %s\n", + oh->name, oh->clkdm_name); + + return 0; +} /** - * _init_clocks - clk_get() all clocks associated with this hwmod + * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as + * well the clockdomain. * @oh: struct omap_hwmod * * @data: not used; pass NULL * @@ -1012,6 +1094,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data) ret |= _init_main_clk(oh); ret |= _init_interface_clks(oh); ret |= _init_opt_clks(oh); + ret |= _init_clkdm(oh); if (!ret) oh->_state = _HWMOD_STATE_CLKS_INITED; @@ -1028,7 +1111,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data) * Wait for a module @oh to leave slave idle. Returns 0 if the module * does not have an IDLEST bit or if the module successfully leaves * slave idle; otherwise, pass along the return value of the - * appropriate *_cm_wait_module_ready() function. + * appropriate *_cm*_wait_module_ready() function. */ static int _wait_target_ready(struct omap_hwmod *oh) { @@ -1055,7 +1138,13 @@ static int _wait_target_ready(struct omap_hwmod *oh) oh->prcm.omap2.idlest_reg_id, oh->prcm.omap2.idlest_idle_bit); } else if (cpu_is_omap44xx()) { - ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg); + if (!oh->clkdm) + return -EINVAL; + + ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); } else { BUG(); }; @@ -1064,6 +1153,36 @@ static int _wait_target_ready(struct omap_hwmod *oh) } /** + * _wait_target_disable - wait for a module to be disabled + * @oh: struct omap_hwmod * + * + * Wait for a module @oh to enter slave idle. Returns 0 if the module + * does not have an IDLEST bit or if the module successfully enters + * slave idle; otherwise, pass along the return value of the + * appropriate *_cm*_wait_module_idle() function. + */ +static int _wait_target_disable(struct omap_hwmod *oh) +{ + /* TODO: For now just handle OMAP4+ */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return 0; + + if (!oh) + return -EINVAL; + + if (oh->_int_flags & _HWMOD_NO_MPU_PORT) + return 0; + + if (oh->flags & HWMOD_NO_IDLEST) + return 0; + + return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** * _lookup_hardreset - fill register bit info for this hwmod/reset line * @oh: struct omap_hwmod * * @name: name of the reset line in the context of this hwmod @@ -1119,8 +1238,10 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name) return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, ohri.rst_shift); else if (cpu_is_omap44xx()) - return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg, - ohri.rst_shift); + return omap4_prminst_assert_hardreset(ohri.rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); else return -EINVAL; } @@ -1155,8 +1276,10 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) if (ohri.st_shift) pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", oh->name, name); - ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg, - ohri.rst_shift); + ret = omap4_prminst_deassert_hardreset(ohri.rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } else { return -EINVAL; } @@ -1191,8 +1314,10 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name) return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, ohri.st_shift); } else if (cpu_is_omap44xx()) { - return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg, - ohri.rst_shift); + return omap4_prminst_is_hardreset_asserted(ohri.rst_shift, + oh->clkdm->pwrdm.ptr->prcm_partition, + oh->clkdm->pwrdm.ptr->prcm_offs, + oh->prcm.omap4.rstctrl_offs); } else { return -EINVAL; } @@ -1312,6 +1437,7 @@ static int _reset(struct omap_hwmod *oh) static int _enable(struct omap_hwmod *oh) { int r; + int hwsup = 0; pr_debug("omap_hwmod: %s: enabling\n", oh->name); @@ -1323,14 +1449,6 @@ static int _enable(struct omap_hwmod *oh) return -EINVAL; } - /* Mux pins for device runtime if populated */ - if (oh->mux && (!oh->mux->enabled || - ((oh->_state == _HWMOD_STATE_IDLE) && - oh->mux->pads_dynamic))) - omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); - - _add_initiator_dep(oh, mpu_oh); - _enable_clocks(oh); /* * If an IP contains only one HW reset line, then de-assert it in order @@ -1341,22 +1459,56 @@ static int _enable(struct omap_hwmod *oh) oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1) _deassert_hardreset(oh, oh->rst_lines[0].name); - r = _wait_target_ready(oh); - if (r) { - pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", - oh->name, r); - _disable_clocks(oh); + /* Mux pins for device runtime if populated */ + if (oh->mux && (!oh->mux->enabled || + ((oh->_state == _HWMOD_STATE_IDLE) && + oh->mux->pads_dynamic))) + omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); + + _add_initiator_dep(oh, mpu_oh); - return r; + if (oh->clkdm) { + /* + * A clockdomain must be in SW_SUP before enabling + * completely the module. The clockdomain can be set + * in HW_AUTO only when the module become ready. + */ + hwsup = clkdm_in_hwsup(oh->clkdm); + r = clkdm_hwmod_enable(oh->clkdm, oh); + if (r) { + WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n", + oh->name, oh->clkdm->name, r); + return r; + } } - oh->_state = _HWMOD_STATE_ENABLED; + _enable_clocks(oh); + _enable_module(oh); + + r = _wait_target_ready(oh); + if (!r) { + /* + * Set the clockdomain to HW_AUTO only if the target is ready, + * assuming that the previous state was HW_AUTO + */ + if (oh->clkdm && hwsup) + clkdm_allow_idle(oh->clkdm); + + oh->_state = _HWMOD_STATE_ENABLED; - /* Access the sysconfig only if the target is ready */ - if (oh->class->sysc) { - if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) - _update_sysc_cache(oh); - _enable_sysc(oh); + /* Access the sysconfig only if the target is ready */ + if (oh->class->sysc) { + if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) + _update_sysc_cache(oh); + _enable_sysc(oh); + } + } else { + _disable_clocks(oh); + pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", + oh->name, r); + + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); } return r; @@ -1372,6 +1524,8 @@ static int _enable(struct omap_hwmod *oh) */ static int _idle(struct omap_hwmod *oh) { + int ret; + pr_debug("omap_hwmod: %s: idling\n", oh->name); if (oh->_state != _HWMOD_STATE_ENABLED) { @@ -1383,7 +1537,20 @@ static int _idle(struct omap_hwmod *oh) if (oh->class->sysc) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); + _disable_module(oh); + ret = _wait_target_disable(oh); + if (ret) + pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", + oh->name); + /* + * The module must be in idle mode before disabling any parents + * clocks. Otherwise, the parent clock might be disabled before + * the module transition is done, and thus will prevent the + * transition to complete properly. + */ _disable_clocks(oh); + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); /* Mux pins for device idle if populated */ if (oh->mux && oh->mux->pads_dynamic) @@ -1475,7 +1642,14 @@ static int _shutdown(struct omap_hwmod *oh) if (oh->_state == _HWMOD_STATE_ENABLED) { _del_initiator_dep(oh, mpu_oh); /* XXX what about the other system initiators here? dma, dsp */ + _disable_module(oh); + ret = _wait_target_disable(oh); + if (ret) + pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", + oh->name); _disable_clocks(oh); + if (oh->clkdm) + clkdm_hwmod_disable(oh->clkdm, oh); } /* XXX Should this code also force-disable the optional clocks? */ @@ -1656,6 +1830,33 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) } /** + * omap_hwmod_softreset - reset a module via SYSCONFIG.SOFTRESET bit + * @oh: struct omap_hwmod * + * + * This is a public function exposed to drivers. Some drivers may need to do + * some settings before and after resetting the device. Those drivers after + * doing the necessary settings could use this function to start a reset by + * setting the SYSCONFIG.SOFTRESET bit. + */ +int omap_hwmod_softreset(struct omap_hwmod *oh) +{ + u32 v; + int ret; + + if (!oh || !(oh->_sysc_cache)) + return -EINVAL; + + v = oh->_sysc_cache; + ret = _set_softreset(oh, &v); + if (ret) + goto error; + _write_sysconfig(v, oh); + +error: + return ret; +} + +/** * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode * @oh: struct omap_hwmod * * @idlemode: SIDLEMODE field bits (shifted to bit 0) diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index f3901ab..a015c69 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1029,9 +1029,16 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { static struct omap_hwmod_class i2c_class = { .name = "i2c", .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, }; -static struct omap_i2c_dev_attr i2c_dev_attr; +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_NO_FIFO | + OMAP_I2C_FLAG_SIMPLE_CLOCK | + OMAP_I2C_FLAG_16BIT_DATA_REG | + OMAP_I2C_FLAG_BUS_SHIFT_2, +}; /* I2C1 */ diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 2a52f02..408193d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -192,6 +192,7 @@ static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = { .pa_end = OMAP243X_HS_BASE + SZ_4K - 1, .flags = ADDR_TYPE_RT }, + { } }; /* l4_core ->usbhsotg interface */ @@ -1078,10 +1079,15 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { static struct omap_hwmod_class i2c_class = { .name = "i2c", .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, }; static struct omap_i2c_dev_attr i2c_dev_attr = { .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | + OMAP_I2C_FLAG_BUS_SHIFT_2 | + OMAP_I2C_FLAG_FORCE_19200_INT_CLK, }; /* I2C1 */ @@ -1092,6 +1098,7 @@ static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = { static struct omap_hwmod omap2430_i2c1_hwmod = { .name = "i2c1", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap2_i2c1_mpu_irqs, .sdma_reqs = omap2_i2c1_sdma_reqs, .main_clk = "i2chs1_fck", @@ -1127,6 +1134,7 @@ static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = { static struct omap_hwmod omap2430_i2c2_hwmod = { .name = "i2c2", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap2_i2c2_mpu_irqs, .sdma_reqs = omap2_i2c2_sdma_reqs, .main_clk = "i2chs2_fck", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 1a52716..25bf43b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1306,8 +1306,10 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = { }; static struct omap_hwmod_class i2c_class = { - .name = "i2c", - .sysc = &i2c_sysc, + .name = "i2c", + .sysc = &i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_1, + .reset = &omap_i2c_reset, }; static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = { @@ -1607,6 +1609,9 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | + OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = { @@ -1615,6 +1620,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = { static struct omap_hwmod omap3xxx_i2c1_hwmod = { .name = "i2c1", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap2_i2c1_mpu_irqs, .sdma_reqs = omap2_i2c1_sdma_reqs, .main_clk = "i2c1_fck", @@ -1638,6 +1644,9 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { static struct omap_i2c_dev_attr i2c2_dev_attr = { .fifo_depth = 8, /* bytes */ + .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | + OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = { @@ -1646,6 +1655,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = { static struct omap_hwmod omap3xxx_i2c2_hwmod = { .name = "i2c2", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap2_i2c2_mpu_irqs, .sdma_reqs = omap2_i2c2_sdma_reqs, .main_clk = "i2c2_fck", @@ -1669,6 +1679,9 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { static struct omap_i2c_dev_attr i2c3_dev_attr = { .fifo_depth = 64, /* bytes */ + .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | + OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = { @@ -1688,6 +1701,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = { static struct omap_hwmod omap3xxx_i2c3_hwmod = { .name = "i2c3", + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c3_mpu_irqs, .sdma_reqs = i2c3_sdma_reqs, .main_clk = "i2c3_fck", diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index e011437..6201422c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -22,11 +22,13 @@ #include <plat/omap_hwmod.h> #include <plat/cpu.h> +#include <plat/i2c.h> #include <plat/gpio.h> #include <plat/dma.h> #include <plat/mcspi.h> #include <plat/mcbsp.h> #include <plat/mmc.h> +#include <plat/i2c.h> #include "omap_hwmod_common_data.h" @@ -121,9 +123,16 @@ static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = { static struct omap_hwmod omap44xx_dmm_hwmod = { .name = "dmm", .class = &omap44xx_dmm_hwmod_class, - .mpu_irqs = omap44xx_dmm_irqs, + .clkdm_name = "l3_emif_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_dmm_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves), + .mpu_irqs = omap44xx_dmm_irqs, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -171,6 +180,13 @@ static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = { static struct omap_hwmod omap44xx_emif_fw_hwmod = { .name = "emif_fw", .class = &omap44xx_emif_fw_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_emif_fw_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -210,6 +226,14 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = { static struct omap_hwmod omap44xx_l3_instr_hwmod = { .name = "l3_instr", .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, .slaves = omap44xx_l3_instr_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -302,7 +326,14 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = { static struct omap_hwmod omap44xx_l3_main_1_hwmod = { .name = "l3_main_1", .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_1_clkdm", .mpu_irqs = omap44xx_l3_main_1_irqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_l3_main_1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -398,6 +429,13 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = { static struct omap_hwmod omap44xx_l3_main_2_hwmod = { .name = "l3_main_2", .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_l3_main_2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -448,6 +486,14 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = { static struct omap_hwmod omap44xx_l3_main_3_hwmod = { .name = "l3_main_3", .class = &omap44xx_l3_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, .slaves = omap44xx_l3_main_3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -505,6 +551,12 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = { static struct omap_hwmod omap44xx_l4_abe_hwmod = { .name = "l4_abe", .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "abe_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET, + }, + }, .slaves = omap44xx_l4_abe_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -527,6 +579,13 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = { static struct omap_hwmod omap44xx_l4_cfg_hwmod = { .name = "l4_cfg", .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_l4_cfg_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -549,6 +608,13 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = { static struct omap_hwmod omap44xx_l4_per_hwmod = { .name = "l4_per", .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_l4_per_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -571,6 +637,13 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = { static struct omap_hwmod omap44xx_l4_wkup_hwmod = { .name = "l4_wkup", .class = &omap44xx_l4_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET, + }, + }, .slaves = omap44xx_l4_wkup_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -601,6 +674,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = { static struct omap_hwmod omap44xx_mpu_private_hwmod = { .name = "mpu_private", .class = &omap44xx_mpu_bus_hwmod_class, + .clkdm_name = "mpuss_clkdm", .slaves = omap44xx_mpu_private_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -739,12 +813,15 @@ static struct omap_hwmod_ocp_if *omap44xx_aess_slaves[] = { static struct omap_hwmod omap44xx_aess_hwmod = { .name = "aess", .class = &omap44xx_aess_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_aess_irqs, .sdma_reqs = omap44xx_aess_sdma_reqs, .main_clk = "aess_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_aess_slaves, @@ -771,9 +848,10 @@ static struct omap_hwmod_opt_clk bandgap_opt_clks[] = { static struct omap_hwmod omap44xx_bandgap_hwmod = { .name = "bandgap", .class = &omap44xx_bandgap_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET, }, }, .opt_clks = bandgap_opt_clks, @@ -828,11 +906,13 @@ static struct omap_hwmod_ocp_if *omap44xx_counter_32k_slaves[] = { static struct omap_hwmod omap44xx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap44xx_counter_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .flags = HWMOD_SWSUP_SIDLE, .main_clk = "sys_32k_ck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET, }, }, .slaves = omap44xx_counter_32k_slaves, @@ -911,11 +991,13 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_slaves[] = { static struct omap_hwmod omap44xx_dma_system_hwmod = { .name = "dma_system", .class = &omap44xx_dma_hwmod_class, + .clkdm_name = "l3_dma_clkdm", .mpu_irqs = omap44xx_dma_system_irqs, .main_clk = "l3_div_ck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL, + .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET, }, }, .dev_attr = &dma_dev_attr, @@ -1003,12 +1085,15 @@ static struct omap_hwmod_ocp_if *omap44xx_dmic_slaves[] = { static struct omap_hwmod omap44xx_dmic_hwmod = { .name = "dmic", .class = &omap44xx_dmic_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_dmic_irqs, .sdma_reqs = omap44xx_dmic_sdma_reqs, .main_clk = "dmic_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_dmic_slaves, @@ -1070,12 +1155,13 @@ static struct omap_hwmod_ocp_if *omap44xx_dsp_slaves[] = { static struct omap_hwmod omap44xx_dsp_c0_hwmod = { .name = "dsp_c0", .class = &omap44xx_dsp_hwmod_class, + .clkdm_name = "tesla_clkdm", .flags = HWMOD_INIT_NO_RESET, .rst_lines = omap44xx_dsp_c0_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_c0_resets), .prcm = { .omap4 = { - .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL, + .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, }, }, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1084,14 +1170,17 @@ static struct omap_hwmod omap44xx_dsp_c0_hwmod = { static struct omap_hwmod omap44xx_dsp_hwmod = { .name = "dsp", .class = &omap44xx_dsp_hwmod_class, + .clkdm_name = "tesla_clkdm", .mpu_irqs = omap44xx_dsp_irqs, .rst_lines = omap44xx_dsp_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets), .main_clk = "dsp_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL, - .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL, + .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .slaves = omap44xx_dsp_slaves, @@ -1136,7 +1225,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1175,10 +1264,12 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = { static struct omap_hwmod omap44xx_dss_hwmod = { .name = "dss_core", .class = &omap44xx_dss_hwmod_class, - .main_clk = "dss_fck", + .clkdm_name = "l3_dss_clkdm", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, .opt_clks = dss_opt_clks, @@ -1238,7 +1329,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dispc_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_dispc_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1267,17 +1358,27 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = { &omap44xx_l4_per__dss_dispc, }; +static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "tv_clk", .clk = "dss_tv_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, +}; + static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .name = "dss_dispc", .class = &omap44xx_dispc_hwmod_class, + .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dispc_irqs, .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, - .main_clk = "dss_fck", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .opt_clks = dss_dispc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), .slaves = omap44xx_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1329,7 +1430,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dsi1_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_dsi1_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1358,17 +1459,25 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = { &omap44xx_l4_per__dss_dsi1, }; +static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { .name = "dss_dsi1", .class = &omap44xx_dsi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi1_irqs, .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, - .main_clk = "dss_fck", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .opt_clks = dss_dsi1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), .slaves = omap44xx_dss_dsi1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1399,7 +1508,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_dsi2_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_dsi2_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1428,17 +1537,25 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = { &omap44xx_l4_per__dss_dsi2, }; +static struct omap_hwmod_opt_clk dss_dsi2_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { .name = "dss_dsi2", .class = &omap44xx_dsi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi2_irqs, .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, - .main_clk = "dss_fck", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .opt_clks = dss_dsi2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), .slaves = omap44xx_dss_dsi2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1489,7 +1606,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_hdmi_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_hdmi_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1518,17 +1635,25 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = { &omap44xx_l4_per__dss_hdmi, }; +static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, +}; + static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .name = "dss_hdmi", .class = &omap44xx_hdmi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, - .main_clk = "dss_fck", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .opt_clks = dss_hdmi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), .slaves = omap44xx_dss_hdmi_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1574,7 +1699,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_rfbi_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_rfbi_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1603,16 +1728,24 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = { &omap44xx_l4_per__dss_rfbi, }; +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_fck" }, +}; + static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap44xx_rfbi_hwmod_class, + .clkdm_name = "l3_dss_clkdm", .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, - .main_clk = "dss_fck", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), .slaves = omap44xx_dss_rfbi_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -1642,7 +1775,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { .master = &omap44xx_l3_main_2_hwmod, .slave = &omap44xx_dss_venc_hwmod, - .clk = "l3_div_ck", + .clk = "dss_fck", .addr = omap44xx_dss_venc_dma_addrs, .user = OCP_USER_SDMA, }; @@ -1674,10 +1807,12 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = { static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, - .main_clk = "dss_fck", + .clkdm_name = "l3_dss_clkdm", + .main_clk = "dss_dss_clk", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, .slaves = omap44xx_dss_venc_slaves, @@ -1751,11 +1886,14 @@ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { static struct omap_hwmod omap44xx_gpio1_hwmod = { .name = "gpio1", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .mpu_irqs = omap44xx_gpio1_irqs, .main_clk = "gpio1_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio1_opt_clks, @@ -1803,12 +1941,15 @@ static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { static struct omap_hwmod omap44xx_gpio2_hwmod = { .name = "gpio2", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio2_irqs, .main_clk = "gpio2_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio2_opt_clks, @@ -1856,12 +1997,15 @@ static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { static struct omap_hwmod omap44xx_gpio3_hwmod = { .name = "gpio3", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio3_irqs, .main_clk = "gpio3_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio3_opt_clks, @@ -1909,12 +2053,15 @@ static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { static struct omap_hwmod omap44xx_gpio4_hwmod = { .name = "gpio4", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio4_irqs, .main_clk = "gpio4_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio4_opt_clks, @@ -1962,12 +2109,15 @@ static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { static struct omap_hwmod omap44xx_gpio5_hwmod = { .name = "gpio5", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio5_irqs, .main_clk = "gpio5_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio5_opt_clks, @@ -2015,12 +2165,15 @@ static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { static struct omap_hwmod omap44xx_gpio6_hwmod = { .name = "gpio6", .class = &omap44xx_gpio_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .mpu_irqs = omap44xx_gpio6_irqs, .main_clk = "gpio6_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = gpio6_opt_clks, @@ -2094,11 +2247,14 @@ static struct omap_hwmod_ocp_if *omap44xx_hsi_slaves[] = { static struct omap_hwmod omap44xx_hsi_hwmod = { .name = "hsi", .class = &omap44xx_hsi_hwmod_class, + .clkdm_name = "l3_init_clkdm", .mpu_irqs = omap44xx_hsi_irqs, .main_clk = "hsi_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .slaves = omap44xx_hsi_slaves, @@ -2127,6 +2283,12 @@ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { .name = "i2c", .sysc = &omap44xx_i2c_sysc, + .rev = OMAP_I2C_IP_VERSION_2, + .reset = &omap_i2c_reset, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr = { + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ @@ -2168,17 +2330,21 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { static struct omap_hwmod omap44xx_i2c1_hwmod = { .name = "i2c1", .class = &omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap44xx_i2c1_irqs, .sdma_reqs = omap44xx_i2c1_sdma_reqs, .main_clk = "i2c1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_i2c1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves), + .dev_attr = &i2c_dev_attr, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -2221,17 +2387,21 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { static struct omap_hwmod omap44xx_i2c2_hwmod = { .name = "i2c2", .class = &omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap44xx_i2c2_irqs, .sdma_reqs = omap44xx_i2c2_sdma_reqs, .main_clk = "i2c2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_i2c2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves), + .dev_attr = &i2c_dev_attr, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -2274,17 +2444,21 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { static struct omap_hwmod omap44xx_i2c3_hwmod = { .name = "i2c3", .class = &omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap44xx_i2c3_irqs, .sdma_reqs = omap44xx_i2c3_sdma_reqs, .main_clk = "i2c3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_i2c3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves), + .dev_attr = &i2c_dev_attr, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -2327,17 +2501,21 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = { static struct omap_hwmod omap44xx_i2c4_hwmod = { .name = "i2c4", .class = &omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_16BIT_REG, .mpu_irqs = omap44xx_i2c4_irqs, .sdma_reqs = omap44xx_i2c4_sdma_reqs, .main_clk = "i2c4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_i2c4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves), + .dev_attr = &i2c_dev_attr, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -2390,12 +2568,13 @@ static struct omap_hwmod_ocp_if *omap44xx_ipu_slaves[] = { static struct omap_hwmod omap44xx_ipu_c0_hwmod = { .name = "ipu_c0", .class = &omap44xx_ipu_hwmod_class, + .clkdm_name = "ducati_clkdm", .flags = HWMOD_INIT_NO_RESET, .rst_lines = omap44xx_ipu_c0_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c0_resets), .prcm = { .omap4 = { - .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, + .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, }, }, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2405,12 +2584,13 @@ static struct omap_hwmod omap44xx_ipu_c0_hwmod = { static struct omap_hwmod omap44xx_ipu_c1_hwmod = { .name = "ipu_c1", .class = &omap44xx_ipu_hwmod_class, + .clkdm_name = "ducati_clkdm", .flags = HWMOD_INIT_NO_RESET, .rst_lines = omap44xx_ipu_c1_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c1_resets), .prcm = { .omap4 = { - .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, + .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, }, }, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2419,14 +2599,17 @@ static struct omap_hwmod omap44xx_ipu_c1_hwmod = { static struct omap_hwmod omap44xx_ipu_hwmod = { .name = "ipu", .class = &omap44xx_ipu_hwmod_class, + .clkdm_name = "ducati_clkdm", .mpu_irqs = omap44xx_ipu_irqs, .rst_lines = omap44xx_ipu_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), .main_clk = "ipu_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL, - .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, + .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .slaves = omap44xx_ipu_slaves, @@ -2506,12 +2689,15 @@ static struct omap_hwmod_opt_clk iss_opt_clks[] = { static struct omap_hwmod omap44xx_iss_hwmod = { .name = "iss", .class = &omap44xx_iss_hwmod_class, + .clkdm_name = "iss_clkdm", .mpu_irqs = omap44xx_iss_irqs, .sdma_reqs = omap44xx_iss_sdma_reqs, .main_clk = "iss_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_CAM_ISS_CLKCTRL, + .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_CAM_ISS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .opt_clks = iss_opt_clks, @@ -2586,12 +2772,13 @@ static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = { static struct omap_hwmod omap44xx_iva_seq0_hwmod = { .name = "iva_seq0", .class = &omap44xx_iva_hwmod_class, + .clkdm_name = "ivahd_clkdm", .flags = HWMOD_INIT_NO_RESET, .rst_lines = omap44xx_iva_seq0_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets), .prcm = { .omap4 = { - .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, + .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET, }, }, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2601,12 +2788,13 @@ static struct omap_hwmod omap44xx_iva_seq0_hwmod = { static struct omap_hwmod omap44xx_iva_seq1_hwmod = { .name = "iva_seq1", .class = &omap44xx_iva_hwmod_class, + .clkdm_name = "ivahd_clkdm", .flags = HWMOD_INIT_NO_RESET, .rst_lines = omap44xx_iva_seq1_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets), .prcm = { .omap4 = { - .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, + .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET, }, }, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2615,14 +2803,17 @@ static struct omap_hwmod omap44xx_iva_seq1_hwmod = { static struct omap_hwmod omap44xx_iva_hwmod = { .name = "iva", .class = &omap44xx_iva_hwmod_class, + .clkdm_name = "ivahd_clkdm", .mpu_irqs = omap44xx_iva_irqs, .rst_lines = omap44xx_iva_resets, .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), .main_clk = "iva_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, - .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, + .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, + .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET, + .context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .slaves = omap44xx_iva_slaves, @@ -2687,11 +2878,14 @@ static struct omap_hwmod_ocp_if *omap44xx_kbd_slaves[] = { static struct omap_hwmod omap44xx_kbd_hwmod = { .name = "kbd", .class = &omap44xx_kbd_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .mpu_irqs = omap44xx_kbd_irqs, .main_clk = "kbd_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_kbd_slaves, @@ -2752,10 +2946,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mailbox_slaves[] = { static struct omap_hwmod omap44xx_mailbox_hwmod = { .name = "mailbox", .class = &omap44xx_mailbox_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", .mpu_irqs = omap44xx_mailbox_irqs, .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET, }, }, .slaves = omap44xx_mailbox_slaves, @@ -2842,12 +3038,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = { static struct omap_hwmod omap44xx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_mcbsp1_irqs, .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, .main_clk = "mcbsp1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mcbsp1_slaves, @@ -2915,12 +3114,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = { static struct omap_hwmod omap44xx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_mcbsp2_irqs, .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, .main_clk = "mcbsp2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mcbsp2_slaves, @@ -2988,12 +3190,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = { static struct omap_hwmod omap44xx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_mcbsp3_irqs, .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, .main_clk = "mcbsp3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mcbsp3_slaves, @@ -3040,12 +3245,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = { static struct omap_hwmod omap44xx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap44xx_mcbsp_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mcbsp4_irqs, .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, .main_clk = "mcbsp4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mcbsp4_slaves, @@ -3132,12 +3340,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mcpdm_slaves[] = { static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mcpdm_slaves, @@ -3217,12 +3428,15 @@ static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { static struct omap_hwmod omap44xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mcspi1_irqs, .sdma_reqs = omap44xx_mcspi1_sdma_reqs, .main_clk = "mcspi1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .dev_attr = &mcspi1_dev_attr, @@ -3277,12 +3491,15 @@ static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { static struct omap_hwmod omap44xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mcspi2_irqs, .sdma_reqs = omap44xx_mcspi2_sdma_reqs, .main_clk = "mcspi2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .dev_attr = &mcspi2_dev_attr, @@ -3337,12 +3554,15 @@ static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { static struct omap_hwmod omap44xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mcspi3_irqs, .sdma_reqs = omap44xx_mcspi3_sdma_reqs, .main_clk = "mcspi3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .dev_attr = &mcspi3_dev_attr, @@ -3395,12 +3615,15 @@ static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { static struct omap_hwmod omap44xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap44xx_mcspi_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mcspi4_irqs, .sdma_reqs = omap44xx_mcspi4_sdma_reqs, .main_clk = "mcspi4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .dev_attr = &mcspi4_dev_attr, @@ -3479,12 +3702,15 @@ static struct omap_mmc_dev_attr mmc1_dev_attr = { static struct omap_hwmod omap44xx_mmc1_hwmod = { .name = "mmc1", .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l3_init_clkdm", .mpu_irqs = omap44xx_mmc1_irqs, .sdma_reqs = omap44xx_mmc1_sdma_reqs, .main_clk = "mmc1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .dev_attr = &mmc1_dev_attr, @@ -3538,12 +3764,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc2_slaves[] = { static struct omap_hwmod omap44xx_mmc2_hwmod = { .name = "mmc2", .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l3_init_clkdm", .mpu_irqs = omap44xx_mmc2_irqs, .sdma_reqs = omap44xx_mmc2_sdma_reqs, .main_clk = "mmc2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mmc2_slaves, @@ -3592,12 +3821,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc3_slaves[] = { static struct omap_hwmod omap44xx_mmc3_hwmod = { .name = "mmc3", .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mmc3_irqs, .sdma_reqs = omap44xx_mmc3_sdma_reqs, .main_clk = "mmc3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mmc3_slaves, @@ -3644,13 +3876,16 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc4_slaves[] = { static struct omap_hwmod omap44xx_mmc4_hwmod = { .name = "mmc4", .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mmc4_irqs, .sdma_reqs = omap44xx_mmc4_sdma_reqs, .main_clk = "mmc4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mmc4_slaves, @@ -3697,12 +3932,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc5_slaves[] = { static struct omap_hwmod omap44xx_mmc5_hwmod = { .name = "mmc5", .class = &omap44xx_mmc_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_mmc5_irqs, .sdma_reqs = omap44xx_mmc5_sdma_reqs, .main_clk = "mmc5_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_mmc5_slaves, @@ -3737,12 +3975,14 @@ static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = { static struct omap_hwmod omap44xx_mpu_hwmod = { .name = "mpu", .class = &omap44xx_mpu_hwmod_class, + .clkdm_name = "mpuss_clkdm", .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_mpu_irqs, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL, + .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, }, }, .masters = omap44xx_mpu_masters, @@ -3809,13 +4049,16 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = { static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .name = "smartreflex_core", .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", .vdd_name = "core", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, + .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_smartreflex_core_slaves, @@ -3856,12 +4099,15 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = { static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .name = "smartreflex_iva", .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", .vdd_name = "iva", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL, + .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_smartreflex_iva_slaves, @@ -3902,12 +4148,15 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = { static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .name = "smartreflex_mpu", .class = &omap44xx_smartreflex_hwmod_class, + .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", .vdd_name = "mpu", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL, + .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_smartreflex_mpu_slaves, @@ -3966,9 +4215,11 @@ static struct omap_hwmod_ocp_if *omap44xx_spinlock_slaves[] = { static struct omap_hwmod omap44xx_spinlock_hwmod = { .name = "spinlock", .class = &omap44xx_spinlock_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET, }, }, .slaves = omap44xx_spinlock_slaves, @@ -4047,11 +4298,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer1_slaves[] = { static struct omap_hwmod omap44xx_timer1_hwmod = { .name = "timer1", .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .mpu_irqs = omap44xx_timer1_irqs, .main_clk = "timer1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer1_slaves, @@ -4092,11 +4346,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer2_slaves[] = { static struct omap_hwmod omap44xx_timer2_hwmod = { .name = "timer2", .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer2_irqs, .main_clk = "timer2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer2_slaves, @@ -4137,11 +4394,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer3_slaves[] = { static struct omap_hwmod omap44xx_timer3_hwmod = { .name = "timer3", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer3_irqs, .main_clk = "timer3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer3_slaves, @@ -4182,11 +4442,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer4_slaves[] = { static struct omap_hwmod omap44xx_timer4_hwmod = { .name = "timer4", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer4_irqs, .main_clk = "timer4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer4_slaves, @@ -4246,11 +4509,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer5_slaves[] = { static struct omap_hwmod omap44xx_timer5_hwmod = { .name = "timer5", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_timer5_irqs, .main_clk = "timer5_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer5_slaves, @@ -4310,12 +4576,15 @@ static struct omap_hwmod_ocp_if *omap44xx_timer6_slaves[] = { static struct omap_hwmod omap44xx_timer6_hwmod = { .name = "timer6", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_timer6_irqs, .main_clk = "timer6_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer6_slaves, @@ -4375,11 +4644,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer7_slaves[] = { static struct omap_hwmod omap44xx_timer7_hwmod = { .name = "timer7", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_timer7_irqs, .main_clk = "timer7_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer7_slaves, @@ -4439,11 +4711,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer8_slaves[] = { static struct omap_hwmod omap44xx_timer8_hwmod = { .name = "timer8", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_timer8_irqs, .main_clk = "timer8_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer8_slaves, @@ -4484,11 +4759,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer9_slaves[] = { static struct omap_hwmod omap44xx_timer9_hwmod = { .name = "timer9", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer9_irqs, .main_clk = "timer9_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer9_slaves, @@ -4529,11 +4807,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer10_slaves[] = { static struct omap_hwmod omap44xx_timer10_hwmod = { .name = "timer10", .class = &omap44xx_timer_1ms_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer10_irqs, .main_clk = "timer10_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer10_slaves, @@ -4574,11 +4855,14 @@ static struct omap_hwmod_ocp_if *omap44xx_timer11_slaves[] = { static struct omap_hwmod omap44xx_timer11_hwmod = { .name = "timer11", .class = &omap44xx_timer_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_timer11_irqs, .main_clk = "timer11_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_timer11_slaves, @@ -4647,12 +4931,15 @@ static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = { static struct omap_hwmod omap44xx_uart1_hwmod = { .name = "uart1", .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_uart1_irqs, .sdma_reqs = omap44xx_uart1_sdma_reqs, .main_clk = "uart1_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_uart1_slaves, @@ -4699,12 +4986,15 @@ static struct omap_hwmod_ocp_if *omap44xx_uart2_slaves[] = { static struct omap_hwmod omap44xx_uart2_hwmod = { .name = "uart2", .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_uart2_irqs, .sdma_reqs = omap44xx_uart2_sdma_reqs, .main_clk = "uart2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_uart2_slaves, @@ -4751,13 +5041,16 @@ static struct omap_hwmod_ocp_if *omap44xx_uart3_slaves[] = { static struct omap_hwmod omap44xx_uart3_hwmod = { .name = "uart3", .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_uart3_irqs, .sdma_reqs = omap44xx_uart3_sdma_reqs, .main_clk = "uart3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_uart3_slaves, @@ -4804,12 +5097,15 @@ static struct omap_hwmod_ocp_if *omap44xx_uart4_slaves[] = { static struct omap_hwmod omap44xx_uart4_hwmod = { .name = "uart4", .class = &omap44xx_uart_hwmod_class, + .clkdm_name = "l4_per_clkdm", .mpu_irqs = omap44xx_uart4_irqs, .sdma_reqs = omap44xx_uart4_sdma_reqs, .main_clk = "uart4_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_uart4_slaves, @@ -4882,12 +5178,15 @@ static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = { static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { .name = "usb_otg_hs", .class = &omap44xx_usb_otg_hs_hwmod_class, + .clkdm_name = "l3_init_clkdm", .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, .mpu_irqs = omap44xx_usb_otg_hs_irqs, .main_clk = "usb_otg_hs_ick", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL, + .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, }, }, .opt_clks = usb_otg_hs_opt_clks, @@ -4955,11 +5254,14 @@ static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = { static struct omap_hwmod omap44xx_wd_timer2_hwmod = { .name = "wd_timer2", .class = &omap44xx_wd_timer_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", .mpu_irqs = omap44xx_wd_timer2_irqs, .main_clk = "wd_timer2_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL, + .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_wd_timer2_slaves, @@ -5019,11 +5321,14 @@ static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = { static struct omap_hwmod omap44xx_wd_timer3_hwmod = { .name = "wd_timer3", .class = &omap44xx_wd_timer_hwmod_class, + .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_wd_timer3_irqs, .main_clk = "wd_timer3_fck", .prcm = { .omap4 = { - .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL, + .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, }, }, .slaves = omap44xx_wd_timer3_slaves, diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 49486f5..472bf22 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -106,8 +106,9 @@ static void omap2_init_processor_devices(void) int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) { u32 cur_state; - int sleep_switch = 0; + int sleep_switch = -1; int ret = 0; + int hwsup = 0; if (pwrdm == NULL || IS_ERR(pwrdm)) return -EINVAL; @@ -127,8 +128,8 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { sleep_switch = LOWPOWERSTATE_SWITCH; } else { + hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); - pwrdm_wait_transition(pwrdm); sleep_switch = FORCEWAKEUP_SWITCH; } } @@ -142,7 +143,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) switch (sleep_switch) { case FORCEWAKEUP_SWITCH: - if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO) + if (hwsup) clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); else clkdm_sleep(pwrdm->pwrdm_clkdms[0]); @@ -154,7 +155,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) return ret; } - pwrdm_wait_transition(pwrdm); pwrdm_state_switch(pwrdm); err: return ret; diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 9af0847..ef71fdd 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -195,28 +195,35 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) /** * pwrdm_init - set up the powerdomain layer - * @pwrdm_list: array of struct powerdomain pointers to register + * @pwrdms: array of struct powerdomain pointers to register * @custom_funcs: func pointers for arch specific implementations * - * Loop through the array of powerdomains @pwrdm_list, registering all - * that are available on the current CPU. If pwrdm_list is supplied - * and not null, all of the referenced powerdomains will be - * registered. No return value. XXX pwrdm_list is not really a - * "list"; it is an array. Rename appropriately. + * Loop through the array of powerdomains @pwrdms, registering all + * that are available on the current CPU. Also, program all + * powerdomain target state as ON; this is to prevent domains from + * hitting low power states (if bootloader has target states set to + * something other than ON) and potentially even losing context while + * PM is not fully initialized. The PM late init code can then program + * the desired target state for all the power domains. No return + * value. */ -void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs) +void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs) { struct powerdomain **p = NULL; + struct powerdomain *temp_p; if (!custom_funcs) WARN(1, "powerdomain: No custom pwrdm functions registered\n"); else arch_pwrdm = custom_funcs; - if (pwrdm_list) { - for (p = pwrdm_list; *p; p++) + if (pwrdms) { + for (p = pwrdms; *p; p++) _pwrdm_register(*p); } + + list_for_each_entry(temp_p, &pwrdm_list, node) + pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON); } /** diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c index 3a7e678..247e794 100644 --- a/arch/arm/mach-omap2/powerdomains44xx_data.c +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c @@ -1,7 +1,7 @@ /* * OMAP4 Power domains framework * - * Copyright (C) 2009-2010 Texas Instruments, Inc. + * Copyright (C) 2009-2011 Texas Instruments, Inc. * Copyright (C) 2009-2011 Nokia Corporation * * Abhijit Pagare (abhijitpagare@ti.com) @@ -41,14 +41,14 @@ static struct powerdomain core_44xx_pwrdm = { .banks = 5, .pwrsts_mem_ret = { [0] = PWRSTS_OFF, /* core_nret_bank */ - [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [1] = PWRSTS_RET, /* core_ocmram */ [2] = PWRSTS_RET, /* core_other_bank */ [3] = PWRSTS_OFF_RET, /* ducati_l2ram */ [4] = PWRSTS_OFF_RET, /* ducati_unicache */ }, .pwrsts_mem_on = { [0] = PWRSTS_ON, /* core_nret_bank */ - [1] = PWRSTS_OFF_RET, /* core_ocmram */ + [1] = PWRSTS_ON, /* core_ocmram */ [2] = PWRSTS_ON, /* core_other_bank */ [3] = PWRSTS_ON, /* ducati_l2ram */ [4] = PWRSTS_ON, /* ducati_unicache */ @@ -205,7 +205,7 @@ static struct powerdomain mpu_44xx_pwrdm = { .prcm_offs = OMAP4430_PRM_MPU_INST, .prcm_partition = OMAP4430_PRM_PARTITION, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3, .pwrsts_mem_ret = { @@ -318,6 +318,7 @@ static struct powerdomain cefuse_44xx_pwrdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), .pwrsts = PWRSTS_OFF_ON, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; /* diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 6be1438..2e40a5c 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -70,7 +70,7 @@ static void omap_prcm_arch_reset(char mode, const char *cmd) prcm_offs = OMAP3430_GR_MOD; omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); } else if (cpu_is_omap44xx()) { - omap4_prm_global_warm_sw_reset(); /* never returns */ + omap4_prminst_global_warm_sw_reset(); /* never returns */ } else { WARN_ON(1); } diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h index 6d2776f..3cb247b 100644 --- a/arch/arm/mach-omap2/prm-regbits-44xx.h +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -283,6 +283,14 @@ #define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT 10 #define OMAP4430_DUCATI_UNICACHE_STATEST_MASK (0x3 << 10) +/* Used by PRM_DEVICE_OFF_CTRL */ +#define OMAP4460_EMIF1_OFFWKUP_DISABLE_SHIFT 8 +#define OMAP4460_EMIF1_OFFWKUP_DISABLE_MASK (1 << 8) + +/* Used by PRM_DEVICE_OFF_CTRL */ +#define OMAP4460_EMIF2_OFFWKUP_DISABLE_SHIFT 9 +#define OMAP4460_EMIF2_OFFWKUP_DISABLE_MASK (1 << 9) + /* Used by RM_MPU_RSTST */ #define OMAP4430_EMULATION_RST_SHIFT 0 #define OMAP4430_EMULATION_RST_MASK (1 << 0) diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index a2a04bfa..0016555 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -1,7 +1,7 @@ /* * OMAP4 PRM module functions * - * Copyright (C) 2010 Texas Instruments, Inc. + * Copyright (C) 2011 Texas Instruments, Inc. * Copyright (C) 2010 Nokia Corporation * Benoît Cousson * Paul Walmsley @@ -24,12 +24,6 @@ #include "prm44xx.h" #include "prm-regbits-44xx.h" -/* - * Address offset (in bytes) between the reset control and the reset - * status registers: 4 bytes on OMAP4 - */ -#define OMAP4_RST_CTRL_ST_OFFSET 4 - /* PRM low-level functions */ /* Read a register in a CM/PRM instance in the PRM module */ @@ -56,140 +50,3 @@ u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) return v; } - -/* Read a PRM register, AND it, and shift the result down to bit 0 */ -/* XXX deprecated */ -u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask) -{ - u32 v; - - v = __raw_readl(reg); - v &= mask; - v >>= __ffs(mask); - - return v; -} - -/* Read-modify-write a register in a PRM module. Caller must lock */ -/* XXX deprecated */ -u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg) -{ - u32 v; - - v = __raw_readl(reg); - v &= ~mask; - v |= bits; - __raw_writel(v, reg); - - return v; -} - -u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 reg) -{ - return omap4_prm_rmw_inst_reg_bits(bits, bits, inst, reg); -} - -u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg) -{ - return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg); -} - -/** - * omap4_prm_is_hardreset_asserted - read the HW reset line state of - * submodules contained in the hwmod module - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to check - * - * Returns 1 if the (sub)module hardreset line is currently asserted, - * 0 if the (sub)module hardreset line is not currently asserted, or - * -EINVAL upon parameter error. - */ -int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift) -{ - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift)); -} - -/** - * omap4_prm_assert_hardreset - assert the HW reset line of a submodule - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to assert - * - * Some IPs like dsp, ipu or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * place the submodule into reset. Returns 0 upon success or -EINVAL - * upon an argument error. - */ -int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift) -{ - u32 mask; - - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - mask = 1 << shift; - omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg); - - return 0; -} - -/** - * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait - * @rstctrl_reg: RM_RSTCTRL register address for this module - * @shift: register bit shift corresponding to the reset line to deassert - * - * Some IPs like dsp, ipu or iva contain processors that require an HW - * reset line to be asserted / deasserted in order to fully enable the - * IP. These modules may have multiple hard-reset lines that reset - * different 'submodules' inside the IP block. This function will - * take the submodule out of reset and wait until the PRCM indicates - * that the reset has completed before returning. Returns 0 upon success or - * -EINVAL upon an argument error, -EEXIST if the submodule was already out - * of reset, or -EBUSY if the submodule did not exit reset promptly. - */ -int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift) -{ - u32 mask; - void __iomem *rstst_reg; - int c; - - if (!cpu_is_omap44xx() || !rstctrl_reg) - return -EINVAL; - - rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET; - - mask = 1 << shift; - - /* Check the current status to avoid de-asserting the line twice */ - if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0) - return -EEXIST; - - /* Clear the reset status by writing 1 to the status bit */ - omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg); - /* de-assert the reset control line */ - omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg); - /* wait the status to be set */ - omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask), - MAX_MODULE_HARDRESET_WAIT, c); - - return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; -} - -void omap4_prm_global_warm_sw_reset(void) -{ - u32 v; - - v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, - OMAP4_RM_RSTCTRL); - v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; - omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST, - OMAP4_RM_RSTCTRL); - - /* OCP barrier */ - v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, - OMAP4_RM_RSTCTRL); -} diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index 6e53120..7dfa379 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h @@ -750,16 +750,6 @@ extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx); extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx); extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); -extern u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg); -extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx); -extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx); -extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask); - -extern int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift); -extern int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift); -extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift); - -extern void omap4_prm_global_warm_sw_reset(void); # endif diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index a303242..3a7bab1 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -2,6 +2,7 @@ * OMAP4 PRM instance functions * * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. * Paul Walmsley * * This program is free software; you can redistribute it and/or modify @@ -53,7 +54,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) /* Read-modify-write a register in PRM. Caller must lock */ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, - s16 idx) + u16 idx) { u32 v; @@ -64,3 +65,112 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, return v; } + +/* + * Address offset (in bytes) between the reset control and the reset + * status registers: 4 bytes on OMAP4 + */ +#define OMAP4_RST_CTRL_ST_OFFSET 4 + +/** + * omap4_prminst_is_hardreset_asserted - read the HW reset line state of + * submodules contained in the hwmod module + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to check + * + * Returns 1 if the (sub)module hardreset line is currently asserted, + * 0 if the (sub)module hardreset line is not currently asserted, or + * -EINVAL upon parameter error. + */ +int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs); + v &= 1 << shift; + v >>= shift; + + return v; +} + +/** + * omap4_prminst_assert_hardreset - assert the HW reset line of a submodule + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to assert + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * place the submodule into reset. Returns 0 upon success or -EINVAL + * upon an argument error. + */ +int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + u32 mask = 1 << shift; + + omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs); + + return 0; +} + +/** + * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and + * wait + * @rstctrl_reg: RM_RSTCTRL register address for this module + * @shift: register bit shift corresponding to the reset line to deassert + * + * Some IPs like dsp, ipu or iva contain processors that require an HW + * reset line to be asserted / deasserted in order to fully enable the + * IP. These modules may have multiple hard-reset lines that reset + * different 'submodules' inside the IP block. This function will + * take the submodule out of reset and wait until the PRCM indicates + * that the reset has completed before returning. Returns 0 upon success or + * -EINVAL upon an argument error, -EEXIST if the submodule was already out + * of reset, or -EBUSY if the submodule did not exit reset promptly. + */ +int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs) +{ + int c; + u32 mask = 1 << shift; + u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET; + + /* Check the current status to avoid de-asserting the line twice */ + if (omap4_prminst_is_hardreset_asserted(shift, part, inst, + rstctrl_offs) == 0) + return -EEXIST; + + /* Clear the reset status by writing 1 to the status bit */ + omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst, + rstst_offs); + /* de-assert the reset control line */ + omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs); + /* wait the status to be set */ + omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst, + rstst_offs), + MAX_MODULE_HARDRESET_WAIT, c); + + return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; +} + + +void omap4_prminst_global_warm_sw_reset(void) +{ + u32 v; + + v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_RSTCTRL_OFFSET); + v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; + omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_RSTCTRL_OFFSET); + + /* OCP barrier */ + v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + OMAP4430_PRM_DEVICE_INST, + OMAP4_PRM_RSTCTRL_OFFSET); +} diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h index 02dd66d..46f2efb 100644 --- a/arch/arm/mach-omap2/prminst44xx.h +++ b/arch/arm/mach-omap2/prminst44xx.h @@ -2,6 +2,7 @@ * OMAP4 Power/Reset Management (PRM) function prototypes * * Copyright (C) 2010 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. * Paul Walmsley * * This program is free software; you can redistribute it and/or modify @@ -18,8 +19,15 @@ extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx); extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, - s16 inst, s16 idx); + s16 inst, u16 idx); -extern void omap4_prm_global_warm_sw_reset(void); +extern void omap4_prminst_global_warm_sw_reset(void); + +extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); +extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); +extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, + u16 rstctrl_offs); #endif diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index f56b1bd..f49804f 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -621,7 +621,7 @@ void sr_disable(struct voltagedomain *voltdm) sr_v2_disable(sr); } - pm_runtime_put_sync(&sr->pdev->dev); + pm_runtime_put_sync_suspend(&sr->pdev->dev); } /** @@ -860,6 +860,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(&pdev->dev); + pm_runtime_irq_safe(&pdev->dev); sr_info->pdev = pdev; sr_info->srid = pdev->id; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index e964072..cf1de7d 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -293,7 +293,8 @@ static void __init omap2_gp_clocksource_init(int gptimer_id, pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", gptimer_id, clksrc.rate); - __omap_dm_timer_load_start(clksrc.io_base, OMAP_TIMER_CTRL_ST, 0, 1); + __omap_dm_timer_load_start(clksrc.io_base, + OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 3aaa46f..daa056e 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -48,14 +48,7 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } -static struct twl4030_usb_data omap4_usb_pdata = { - .phy_init = omap4430_phy_init, - .phy_exit = omap4430_phy_exit, - .phy_power = omap4430_phy_power, - .phy_set_clock = omap4430_phy_set_clk, - .phy_suspend = omap4430_phy_suspend, -}; - +#if defined(CONFIG_ARCH_OMAP3) static struct twl4030_usb_data omap3_usb_pdata = { .usb_mode = T2_USB_MODE_ULPI, }; @@ -80,11 +73,11 @@ static struct twl4030_madc_platform_data omap3_madc_pdata = { .irq_line = 1, }; -static struct twl4030_codec_audio_data omap3_audio; +static struct twl4030_codec_data omap3_codec; -static struct twl4030_codec_data omap3_codec_pdata = { +static struct twl4030_audio_data omap3_audio_pdata = { .audio_mclk = 26000000, - .audio = &omap3_audio, + .codec = &omap3_codec, }; static struct regulator_consumer_supply omap3_vdda_dac_supplies[] = { @@ -122,6 +115,45 @@ static struct regulator_init_data omap3_vpll2_idata = { .consumer_supplies = omap3_vpll2_supplies, }; +void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags) +{ + if (!pmic_data->irq_base) + pmic_data->irq_base = TWL4030_IRQ_BASE; + if (!pmic_data->irq_end) + pmic_data->irq_end = TWL4030_IRQ_END; + + /* Common platform data configurations */ + if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) + pmic_data->usb = &omap3_usb_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci) + pmic_data->bci = &omap3_bci_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) + pmic_data->madc = &omap3_madc_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio) + pmic_data->audio = &omap3_audio_pdata; + + /* Common regulator configurations */ + if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) + pmic_data->vdac = &omap3_vdac_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2) + pmic_data->vpll2 = &omap3_vpll2_idata; +} +#endif /* CONFIG_ARCH_OMAP3 */ + +#if defined(CONFIG_ARCH_OMAP4) +static struct twl4030_usb_data omap4_usb_pdata = { + .phy_init = omap4430_phy_init, + .phy_exit = omap4430_phy_exit, + .phy_power = omap4430_phy_power, + .phy_set_clock = omap4430_phy_set_clk, + .phy_suspend = omap4430_phy_suspend, +}; + static struct regulator_init_data omap4_vdac_idata = { .constraints = { .min_uV = 1800000, @@ -273,32 +305,4 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, !pmic_data->clk32kg) pmic_data->clk32kg = &omap4_clk32kg_idata; } - -void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, - u32 pdata_flags, u32 regulators_flags) -{ - if (!pmic_data->irq_base) - pmic_data->irq_base = TWL4030_IRQ_BASE; - if (!pmic_data->irq_end) - pmic_data->irq_end = TWL4030_IRQ_END; - - /* Common platform data configurations */ - if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) - pmic_data->usb = &omap3_usb_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci) - pmic_data->bci = &omap3_bci_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) - pmic_data->madc = &omap3_madc_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->codec) - pmic_data->codec = &omap3_codec_pdata; - - /* Common regulator configurations */ - if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) - pmic_data->vdac = &omap3_vdac_idata; - - if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2) - pmic_data->vpll2 = &omap3_vpll2_idata; -} +#endif /* CONFIG_ARCH_OMAP4 */ diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index f2b2b35..3e5499d 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -51,7 +51,7 @@ void orion5x_pci_disable(void); void orion5x_pci_set_cardbus_mode(void); int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); -int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); +int orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); struct machine_desc; struct meminfo; diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index f95d3cb..a3e3e9e 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -237,7 +237,8 @@ void __init db88f5281_pci_preinit(void) } } -static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init db88f5281_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 855e0e7..c105556 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -70,7 +70,7 @@ enum { * PCI setup */ -static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/include/mach/hardware.h b/arch/arm/mach-orion5x/include/mach/hardware.h index e51aaf4..3957354 100644 --- a/arch/arm/mach-orion5x/include/mach/hardware.h +++ b/arch/arm/mach-orion5x/include/mach/hardware.h @@ -11,11 +11,4 @@ #include "orion5x.h" -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x00001000 -#define PCIBIOS_MIN_MEM 0x01000000 -#define PCIMEM_BASE ORION5X_PCIE_MEM_PHYS_BASE - - #endif diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index c0eb646..0038124 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -119,7 +119,8 @@ static struct platform_device kurobox_pro_nor_flash = { * PCI ****************************************************************************/ -static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init kurobox_pro_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c index 59263b7..ef3bb8e 100644 --- a/arch/arm/mach-orion5x/mss2-setup.c +++ b/arch/arm/mach-orion5x/mss2-setup.c @@ -73,7 +73,7 @@ static struct platform_device mss2_nor_flash = { /**************************************************************************** * PCI setup ****************************************************************************/ -static int __init mss2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init mss2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index e8706f1..bc4a920 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -14,6 +14,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/mbus.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> #include <plat/pcie.h> @@ -560,6 +561,8 @@ int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) { int ret = 0; + vga_base = ORION5X_PCIE_MEM_PHYS_BASE; + if (nr == 0) { orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr); ret = pcie_setup(sys); @@ -587,7 +590,7 @@ struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys return bus; } -int __init orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int bus = dev->bus->number; diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c index 9eec7c2..291d22b 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -131,7 +131,7 @@ static void __init rd88f5181l_fxo_init(void) } static int __init -rd88f5181l_fxo_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rd88f5181l_fxo_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c index 0cc90bbf..3f02362 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -140,7 +140,7 @@ static void __init rd88f5181l_ge_init(void) } static int __init -rd88f5181l_ge_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rd88f5181l_ge_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c index 48da39b..27fd38e 100644 --- a/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -172,7 +172,8 @@ void __init rd88f5182_pci_preinit(void) } } -static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init rd88f5182_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c index 29ce826..a34e4fa 100644 --- a/arch/arm/mach-orion5x/terastation_pro2-setup.c +++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -100,7 +100,7 @@ void __init tsp2_pci_preinit(void) } } -static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init tsp2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 47162fd..c983161 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -143,7 +143,8 @@ void __init qnap_ts209_pci_preinit(void) } } -static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init qnap_ts209_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c index 5aacc7a..cc33b22 100644 --- a/arch/arm/mach-orion5x/ts409-setup.c +++ b/arch/arm/mach-orion5x/ts409-setup.c @@ -121,7 +121,8 @@ static struct platform_device qnap_ts409_nor_flash = { * PCI ****************************************************************************/ -static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c index 444a1c7..2653595 100644 --- a/arch/arm/mach-orion5x/wnr854t-setup.c +++ b/arch/arm/mach-orion5x/wnr854t-setup.c @@ -133,7 +133,8 @@ static void __init wnr854t_init(void) platform_device_register(&wnr854t_nor_flash); } -static int __init wnr854t_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init wnr854t_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index d1952be..251ef15 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -221,7 +221,8 @@ static void __init wrt350n_v2_init(void) platform_device_register(&wrt350n_v2_button_device); } -static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init wrt350n_v2_pci_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { int irq; diff --git a/arch/arm/mach-pnx4008/include/mach/clkdev.h b/arch/arm/mach-pnx4008/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-pnx4008/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile new file mode 100644 index 0000000..7af7fc0 --- /dev/null +++ b/arch/arm/mach-prima2/Makefile @@ -0,0 +1,7 @@ +obj-y := timer.o +obj-y += irq.o +obj-y += clock.o +obj-y += rstc.o +obj-y += prima2.o +obj-$(CONFIG_DEBUG_LL) += lluart.o +obj-$(CONFIG_CACHE_L2X0) += l2x0.o diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot new file mode 100644 index 0000000..d023db3 --- /dev/null +++ b/arch/arm/mach-prima2/Makefile.boot @@ -0,0 +1,3 @@ +zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c new file mode 100644 index 0000000..615a4e7 --- /dev/null +++ b/arch/arm/mach-prima2/clock.c @@ -0,0 +1,510 @@ +/* + * Clock tree for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/clkdev.h> +#include <linux/clk.h> +#include <linux/spinlock.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <asm/mach/map.h> +#include <mach/map.h> + +#define SIRFSOC_CLKC_CLK_EN0 0x0000 +#define SIRFSOC_CLKC_CLK_EN1 0x0004 +#define SIRFSOC_CLKC_REF_CFG 0x0014 +#define SIRFSOC_CLKC_CPU_CFG 0x0018 +#define SIRFSOC_CLKC_MEM_CFG 0x001c +#define SIRFSOC_CLKC_SYS_CFG 0x0020 +#define SIRFSOC_CLKC_IO_CFG 0x0024 +#define SIRFSOC_CLKC_DSP_CFG 0x0028 +#define SIRFSOC_CLKC_GFX_CFG 0x002c +#define SIRFSOC_CLKC_MM_CFG 0x0030 +#define SIRFSOC_LKC_LCD_CFG 0x0034 +#define SIRFSOC_CLKC_MMC_CFG 0x0038 +#define SIRFSOC_CLKC_PLL1_CFG0 0x0040 +#define SIRFSOC_CLKC_PLL2_CFG0 0x0044 +#define SIRFSOC_CLKC_PLL3_CFG0 0x0048 +#define SIRFSOC_CLKC_PLL1_CFG1 0x004c +#define SIRFSOC_CLKC_PLL2_CFG1 0x0050 +#define SIRFSOC_CLKC_PLL3_CFG1 0x0054 +#define SIRFSOC_CLKC_PLL1_CFG2 0x0058 +#define SIRFSOC_CLKC_PLL2_CFG2 0x005c +#define SIRFSOC_CLKC_PLL3_CFG2 0x0060 + +#define SIRFSOC_CLOCK_VA_BASE SIRFSOC_VA(0x005000) + +#define KHZ 1000 +#define MHZ (KHZ * KHZ) + +struct clk_ops { + unsigned long (*get_rate)(struct clk *clk); + long (*round_rate)(struct clk *clk, unsigned long rate); + int (*set_rate)(struct clk *clk, unsigned long rate); + int (*enable)(struct clk *clk); + int (*disable)(struct clk *clk); + struct clk *(*get_parent)(struct clk *clk); + int (*set_parent)(struct clk *clk, struct clk *parent); +}; + +struct clk { + struct clk *parent; /* parent clk */ + unsigned long rate; /* clock rate in Hz */ + signed char usage; /* clock enable count */ + signed char enable_bit; /* enable bit: 0 ~ 63 */ + unsigned short regofs; /* register offset */ + struct clk_ops *ops; /* clock operation */ +}; + +static DEFINE_SPINLOCK(clocks_lock); + +static inline unsigned long clkc_readl(unsigned reg) +{ + return readl(SIRFSOC_CLOCK_VA_BASE + reg); +} + +static inline void clkc_writel(u32 val, unsigned reg) +{ + writel(val, SIRFSOC_CLOCK_VA_BASE + reg); +} + +/* + * osc_rtc - real time oscillator - 32.768KHz + * osc_sys - high speed oscillator - 26MHz + */ + +static struct clk clk_rtc = { + .rate = 32768, +}; + +static struct clk clk_osc = { + .rate = 26 * MHZ, +}; + +/* + * std pll + */ +static unsigned long std_pll_get_rate(struct clk *clk) +{ + unsigned long fin = clk_get_rate(clk->parent); + u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - + SIRFSOC_CLKC_PLL1_CFG0; + + if (clkc_readl(regcfg2) & BIT(2)) { + /* pll bypass mode */ + clk->rate = fin; + } else { + /* fout = fin * nf / nr / od */ + u32 cfg0 = clkc_readl(clk->regofs); + u32 nf = (cfg0 & (BIT(13) - 1)) + 1; + u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1; + u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1; + WARN_ON(fin % MHZ); + clk->rate = fin / MHZ * nf / nr / od * MHZ; + } + + return clk->rate; +} + +static int std_pll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long fin, nf, nr, od, reg; + + /* + * fout = fin * nf / (nr * od); + * set od = 1, nr = fin/MHz, so fout = nf * MHz + */ + + nf = rate / MHZ; + if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1)) + return -EINVAL; + + fin = clk_get_rate(clk->parent); + BUG_ON(fin < MHZ); + + nr = fin / MHZ; + BUG_ON((fin % MHZ) || nr > BIT(6)); + + od = 1; + + reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19); + clkc_writel(reg, clk->regofs); + + reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0; + clkc_writel((nf >> 1) - 1, reg); + + reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0; + while (!(clkc_readl(reg) & BIT(6))) + cpu_relax(); + + clk->rate = 0; /* set to zero will force recalculation */ + return 0; +} + +static struct clk_ops std_pll_ops = { + .get_rate = std_pll_get_rate, + .set_rate = std_pll_set_rate, +}; + +static struct clk clk_pll1 = { + .parent = &clk_osc, + .regofs = SIRFSOC_CLKC_PLL1_CFG0, + .ops = &std_pll_ops, +}; + +static struct clk clk_pll2 = { + .parent = &clk_osc, + .regofs = SIRFSOC_CLKC_PLL2_CFG0, + .ops = &std_pll_ops, +}; + +static struct clk clk_pll3 = { + .parent = &clk_osc, + .regofs = SIRFSOC_CLKC_PLL3_CFG0, + .ops = &std_pll_ops, +}; + +/* + * clock domains - cpu, mem, sys/io + */ + +static struct clk clk_mem; + +static struct clk *dmn_get_parent(struct clk *clk) +{ + struct clk *clks[] = { + &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3 + }; + u32 cfg = clkc_readl(clk->regofs); + WARN_ON((cfg & (BIT(3) - 1)) > 4); + return clks[cfg & (BIT(3) - 1)]; +} + +static int dmn_set_parent(struct clk *clk, struct clk *parent) +{ + const struct clk *clks[] = { + &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3 + }; + u32 cfg = clkc_readl(clk->regofs); + int i; + for (i = 0; i < ARRAY_SIZE(clks); i++) { + if (clks[i] == parent) { + cfg &= ~(BIT(3) - 1); + clkc_writel(cfg | i, clk->regofs); + /* BIT(3) - switching status: 1 - busy, 0 - done */ + while (clkc_readl(clk->regofs) & BIT(3)) + cpu_relax(); + return 0; + } + } + return -EINVAL; +} + +static unsigned long dmn_get_rate(struct clk *clk) +{ + unsigned long fin = clk_get_rate(clk->parent); + u32 cfg = clkc_readl(clk->regofs); + if (cfg & BIT(24)) { + /* fcd bypass mode */ + clk->rate = fin; + } else { + /* + * wait count: bit[19:16], hold count: bit[23:20] + */ + u32 wait = (cfg >> 16) & (BIT(4) - 1); + u32 hold = (cfg >> 20) & (BIT(4) - 1); + + clk->rate = fin / (wait + hold + 2); + } + + return clk->rate; +} + +static int dmn_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long fin; + unsigned ratio, wait, hold, reg; + unsigned bits = (clk == &clk_mem) ? 3 : 4; + + fin = clk_get_rate(clk->parent); + ratio = fin / rate; + + if (unlikely(ratio < 2 || ratio > BIT(bits + 1))) + return -EINVAL; + + WARN_ON(fin % rate); + + wait = (ratio >> 1) - 1; + hold = ratio - wait - 2; + + reg = clkc_readl(clk->regofs); + reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20)); + reg |= (wait << 16) | (hold << 20) | BIT(25); + clkc_writel(reg, clk->regofs); + + /* waiting FCD been effective */ + while (clkc_readl(clk->regofs) & BIT(25)) + cpu_relax(); + + clk->rate = 0; /* set to zero will force recalculation */ + + return 0; +} + +/* + * cpu clock has no FCD register in Prima2, can only change pll + */ +static int cpu_set_rate(struct clk *clk, unsigned long rate) +{ + int ret1, ret2; + struct clk *cur_parent, *tmp_parent; + + cur_parent = dmn_get_parent(clk); + BUG_ON(cur_parent == NULL || cur_parent->usage > 1); + + /* switch to tmp pll before setting parent clock's rate */ + tmp_parent = cur_parent == &clk_pll1 ? &clk_pll2 : &clk_pll1; + ret1 = dmn_set_parent(clk, tmp_parent); + BUG_ON(ret1); + + ret2 = clk_set_rate(cur_parent, rate); + + ret1 = dmn_set_parent(clk, cur_parent); + + clk->rate = 0; /* set to zero will force recalculation */ + + return ret2 ? ret2 : ret1; +} + +static struct clk_ops cpu_ops = { + .get_parent = dmn_get_parent, + .set_parent = dmn_set_parent, + .set_rate = cpu_set_rate, +}; + +static struct clk clk_cpu = { + .parent = &clk_pll1, + .regofs = SIRFSOC_CLKC_CPU_CFG, + .ops = &cpu_ops, +}; + + +static struct clk_ops msi_ops = { + .set_rate = dmn_set_rate, + .get_rate = dmn_get_rate, + .set_parent = dmn_set_parent, + .get_parent = dmn_get_parent, +}; + +static struct clk clk_mem = { + .parent = &clk_pll2, + .regofs = SIRFSOC_CLKC_MEM_CFG, + .ops = &msi_ops, +}; + +static struct clk clk_sys = { + .parent = &clk_pll3, + .regofs = SIRFSOC_CLKC_SYS_CFG, + .ops = &msi_ops, +}; + +static struct clk clk_io = { + .parent = &clk_pll3, + .regofs = SIRFSOC_CLKC_IO_CFG, + .ops = &msi_ops, +}; + +/* + * on-chip clock sets + */ +static struct clk_lookup onchip_clks[] = { + { + .dev_id = "rtc", + .clk = &clk_rtc, + }, { + .dev_id = "osc", + .clk = &clk_osc, + }, { + .dev_id = "pll1", + .clk = &clk_pll1, + }, { + .dev_id = "pll2", + .clk = &clk_pll2, + }, { + .dev_id = "pll3", + .clk = &clk_pll3, + }, { + .dev_id = "cpu", + .clk = &clk_cpu, + }, { + .dev_id = "mem", + .clk = &clk_mem, + }, { + .dev_id = "sys", + .clk = &clk_sys, + }, { + .dev_id = "io", + .clk = &clk_io, + }, +}; + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + if (unlikely(IS_ERR_OR_NULL(clk))) + return -EINVAL; + + if (clk->parent) + clk_enable(clk->parent); + + spin_lock_irqsave(&clocks_lock, flags); + if (!clk->usage++ && clk->ops && clk->ops->enable) + clk->ops->enable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + if (unlikely(IS_ERR_OR_NULL(clk))) + return; + + WARN_ON(!clk->usage); + + spin_lock_irqsave(&clocks_lock, flags); + if (--clk->usage == 0 && clk->ops && clk->ops->disable) + clk->ops->disable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + + if (clk->parent) + clk_disable(clk->parent); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + if (unlikely(IS_ERR_OR_NULL(clk))) + return 0; + + if (clk->rate) + return clk->rate; + + if (clk->ops && clk->ops->get_rate) + return clk->ops->get_rate(clk); + + return clk_get_rate(clk->parent); +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (unlikely(IS_ERR_OR_NULL(clk))) + return 0; + + if (clk->ops && clk->ops->round_rate) + return clk->ops->round_rate(clk, rate); + + return 0; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + if (unlikely(IS_ERR_OR_NULL(clk))) + return -EINVAL; + + if (!clk->ops || !clk->ops->set_rate) + return -EINVAL; + + return clk->ops->set_rate(clk, rate); +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int ret; + unsigned long flags; + + if (unlikely(IS_ERR_OR_NULL(clk))) + return -EINVAL; + + if (!clk->ops || !clk->ops->set_parent) + return -EINVAL; + + spin_lock_irqsave(&clocks_lock, flags); + ret = clk->ops->set_parent(clk, parent); + if (!ret) { + parent->usage += clk->usage; + clk->parent->usage -= clk->usage; + BUG_ON(clk->parent->usage < 0); + clk->parent = parent; + } + spin_unlock_irqrestore(&clocks_lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + unsigned long flags; + + if (unlikely(IS_ERR_OR_NULL(clk))) + return NULL; + + if (!clk->ops || !clk->ops->get_parent) + return clk->parent; + + spin_lock_irqsave(&clocks_lock, flags); + clk->parent = clk->ops->get_parent(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +static void __init sirfsoc_clk_init(void) +{ + clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks)); +} + +static struct of_device_id clkc_ids[] = { + { .compatible = "sirf,prima2-clkc" }, + {}, +}; + +void __init sirfsoc_of_clk_init(void) +{ + struct device_node *np; + struct resource res; + struct map_desc sirfsoc_clkc_iodesc = { + .virtual = SIRFSOC_CLOCK_VA_BASE, + .type = MT_DEVICE, + }; + + np = of_find_matching_node(NULL, clkc_ids); + if (!np) + panic("unable to find compatible clkc node in dtb\n"); + + if (of_address_to_resource(np, 0, &res)) + panic("unable to find clkc range in dtb"); + of_node_put(np); + + sirfsoc_clkc_iodesc.pfn = __phys_to_pfn(res.start); + sirfsoc_clkc_iodesc.length = 1 + res.end - res.start; + + iotable_init(&sirfsoc_clkc_iodesc, 1); + + sirfsoc_clk_init(); +} diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h new file mode 100644 index 0000000..83e5d212 --- /dev/null +++ b/arch/arm/mach-prima2/common.h @@ -0,0 +1,26 @@ +/* + * This file contains common function prototypes to avoid externs in the c files. + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_PRIMA2_COMMON_H__ +#define __MACH_PRIMA2_COMMON_H__ + +#include <linux/init.h> +#include <asm/mach/time.h> + +extern struct sys_timer sirfsoc_timer; + +extern void __init sirfsoc_of_irq_init(void); +extern void __init sirfsoc_of_clk_init(void); + +#ifndef CONFIG_DEBUG_LL +static inline void sirfsoc_map_lluart(void) {} +#else +extern void __init sirfsoc_map_lluart(void); +#endif + +#endif diff --git a/arch/arm/mach-prima2/include/mach/clkdev.h b/arch/arm/mach-prima2/include/mach/clkdev.h new file mode 100644 index 0000000..6693251 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/clkdev.h @@ -0,0 +1,15 @@ +/* + * arch/arm/mach-prima2/include/mach/clkdev.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-prima2/include/mach/debug-macro.S b/arch/arm/mach-prima2/include/mach/debug-macro.S new file mode 100644 index 0000000..bf75106 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/debug-macro.S @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-prima2/include/mach/debug-macro.S + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <mach/hardware.h> +#include <mach/uart.h> + + .macro addruart, rp, rv + ldr \rp, =SIRFSOC_UART1_PA_BASE @ physical + ldr \rv, =SIRFSOC_UART1_VA_BASE @ virtual + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #SIRFSOC_UART_TXFIFO_DATA] + .endm + + .macro busyuart,rd,rx + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #SIRFSOC_UART_TXFIFO_STATUS] + tst \rd, #SIRFSOC_UART1_TXFIFO_EMPTY + beq 1001b + .endm + diff --git a/arch/arm/mach-prima2/include/mach/entry-macro.S b/arch/arm/mach-prima2/include/mach/entry-macro.S new file mode 100644 index 0000000..1c8a50f --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/entry-macro.S @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-prima2/include/mach/entry-macro.S + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <mach/hardware.h> + +#define SIRFSOC_INT_ID 0x38 + + .macro get_irqnr_preamble, base, tmp + ldr \base, =sirfsoc_intc_base + ldr \base, [\base] + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqnr, [\base, #SIRFSOC_INT_ID] @ Get the highest priority irq + cmp \irqnr, #0x40 @ the irq num can't be larger than 0x3f + movges \irqnr, #0 + .endm + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + diff --git a/arch/arm/mach-prima2/include/mach/hardware.h b/arch/arm/mach-prima2/include/mach/hardware.h new file mode 100644 index 0000000..105b969 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/hardware.h @@ -0,0 +1,15 @@ +/* + * arch/arm/mach-prima2/include/mach/hardware.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_HARDWARE_H__ +#define __MACH_HARDWARE_H__ + +#include <asm/sizes.h> +#include <mach/map.h> + +#endif diff --git a/arch/arm/mach-prima2/include/mach/io.h b/arch/arm/mach-prima2/include/mach/io.h new file mode 100644 index 0000000..6c31e9e --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/io.h @@ -0,0 +1,16 @@ +/* + * arch/arm/mach-prima2/include/mach/io.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_PRIMA2_IO_H +#define __MACH_PRIMA2_IO_H + +#define IO_SPACE_LIMIT ((resource_size_t)0) + +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h new file mode 100644 index 0000000..bb354f9 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/irqs.h @@ -0,0 +1,17 @@ +/* + * arch/arm/mach-prima2/include/mach/irqs.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + +#define SIRFSOC_INTENAL_IRQ_START 0 +#define SIRFSOC_INTENAL_IRQ_END 59 + +#define NR_IRQS 220 + +#endif diff --git a/arch/arm/mach-prima2/include/mach/map.h b/arch/arm/mach-prima2/include/mach/map.h new file mode 100644 index 0000000..66b1ae2 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/map.h @@ -0,0 +1,16 @@ +/* + * memory & I/O static mapping definitions for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_PRIMA2_MAP_H__ +#define __MACH_PRIMA2_MAP_H__ + +#include <mach/vmalloc.h> + +#define SIRFSOC_VA(x) (VMALLOC_END + ((x) & 0x00FFF000)) + +#endif diff --git a/arch/arm/mach-prima2/include/mach/memory.h b/arch/arm/mach-prima2/include/mach/memory.h new file mode 100644 index 0000000..368cd5a --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/memory.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-prima2/include/mach/memory.h + * + * Copyright (c) 2010 – 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PLAT_PHYS_OFFSET UL(0x00000000) + +/* + * Restrict DMA-able region to workaround silicon limitation. + * The limitation restricts buffers available for DMA to SD/MMC + * hardware to be below 256MB + */ +#define ARM_DMA_ZONE_SIZE (SZ_256M) + +#endif diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h new file mode 100644 index 0000000..0dbd257 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/system.h @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-prima2/include/mach/system.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_SYSTEM_H__ +#define __MACH_SYSTEM_H__ + +#include <linux/bitops.h> +#include <mach/hardware.h> + +#define SIRFSOC_SYS_RST_BIT BIT(31) + +extern void __iomem *sirfsoc_rstc_base; + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ + writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base); +} + +#endif diff --git a/arch/arm/mach-prima2/include/mach/timex.h b/arch/arm/mach-prima2/include/mach/timex.h new file mode 100644 index 0000000..d6f98a7 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/timex.h @@ -0,0 +1,14 @@ +/* + * arch/arm/mach-prima2/include/mach/timex.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_TIMEX_H__ +#define __MACH_TIMEX_H__ + +#define CLOCK_TICK_RATE 1000000 + +#endif diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h new file mode 100644 index 0000000..c98b4d5 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/uart.h @@ -0,0 +1,23 @@ +/* + * arch/arm/mach-prima2/include/mach/uart.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_PRIMA2_SIRFSOC_UART_H +#define __MACH_PRIMA2_SIRFSOC_UART_H + +/* UART-1: used as serial debug port */ +#define SIRFSOC_UART1_PA_BASE 0xb0060000 +#define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) +#define SIRFSOC_UART1_SIZE SZ_4K + +#define SIRFSOC_UART_TXFIFO_STATUS 0x0114 +#define SIRFSOC_UART_TXFIFO_DATA 0x0118 + +#define SIRFSOC_UART1_TXFIFO_FULL (1 << 5) +#define SIRFSOC_UART1_TXFIFO_EMPTY (1 << 6) + +#endif diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h new file mode 100644 index 0000000..83125c6 --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/uncompress.h @@ -0,0 +1,40 @@ +/* + * arch/arm/mach-prima2/include/mach/uncompress.h + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __ASM_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/uart.h> + +void arch_decomp_setup(void) +{ +} + +#define arch_decomp_wdog() + +static __inline__ void putc(char c) +{ + /* + * during kernel decompression, all mappings are flat: + * virt_addr == phys_addr + */ + while (__raw_readl(SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) + & SIRFSOC_UART1_TXFIFO_FULL) + barrier(); + + __raw_writel(c, SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_DATA); +} + +static inline void flush(void) +{ +} + +#endif + diff --git a/arch/arm/mach-prima2/include/mach/vmalloc.h b/arch/arm/mach-prima2/include/mach/vmalloc.h new file mode 100644 index 0000000..c9f90fe --- /dev/null +++ b/arch/arm/mach-prima2/include/mach/vmalloc.h @@ -0,0 +1,16 @@ +/* + * arch/arm/ach-prima2/include/mach/vmalloc.h + * + * Copyright (c) 2010 – 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#ifndef __MACH_VMALLOC_H +#define __MACH_VMALLOC_H + +#include <linux/const.h> + +#define VMALLOC_END _AC(0xFEC00000, UL) + +#endif diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c new file mode 100644 index 0000000..7af254d --- /dev/null +++ b/arch/arm/mach-prima2/irq.c @@ -0,0 +1,72 @@ +/* + * interrupt controller support for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <mach/hardware.h> +#include <asm/mach/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#define SIRFSOC_INT_RISC_MASK0 0x0018 +#define SIRFSOC_INT_RISC_MASK1 0x001C +#define SIRFSOC_INT_RISC_LEVEL0 0x0020 +#define SIRFSOC_INT_RISC_LEVEL1 0x0024 + +void __iomem *sirfsoc_intc_base; + +static __init void +sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) +{ + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + gc = irq_alloc_generic_chip("SIRFINTC", 1, irq_start, base, handle_level_irq); + ct = gc->chip_types; + + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + ct->regs.mask = SIRFSOC_INT_RISC_MASK0; + + irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0); +} + +static __init void sirfsoc_irq_init(void) +{ + sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32); + sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32); + + writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0); + writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1); + + writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0); + writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); +} + +static struct of_device_id intc_ids[] = { + { .compatible = "sirf,prima2-intc" }, + {}, +}; + +void __init sirfsoc_of_irq_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, intc_ids); + if (!np) + panic("unable to find compatible intc node in dtb\n"); + + sirfsoc_intc_base = of_iomap(np, 0); + if (!sirfsoc_intc_base) + panic("unable to map intc cpu registers\n"); + + of_node_put(np); + + sirfsoc_irq_init(); +} diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c new file mode 100644 index 0000000..9cda205 --- /dev/null +++ b/arch/arm/mach-prima2/l2x0.c @@ -0,0 +1,59 @@ +/* + * l2 cache initialization for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/errno.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <asm/hardware/cache-l2x0.h> +#include <mach/memory.h> + +#define L2X0_ADDR_FILTERING_START 0xC00 +#define L2X0_ADDR_FILTERING_END 0xC04 + +static struct of_device_id l2x_ids[] = { + { .compatible = "arm,pl310-cache" }, +}; + +static int __init sirfsoc_of_l2x_init(void) +{ + struct device_node *np; + void __iomem *sirfsoc_l2x_base; + + np = of_find_matching_node(NULL, l2x_ids); + if (!np) + panic("unable to find compatible l2x node in dtb\n"); + + sirfsoc_l2x_base = of_iomap(np, 0); + if (!sirfsoc_l2x_base) + panic("unable to map l2x cpu registers\n"); + + of_node_put(np); + + if (!(readl_relaxed(sirfsoc_l2x_base + L2X0_CTRL) & 1)) { + /* + * set the physical memory windows L2 cache will cover + */ + writel_relaxed(PLAT_PHYS_OFFSET + 1024 * 1024 * 1024, + sirfsoc_l2x_base + L2X0_ADDR_FILTERING_END); + writel_relaxed(PLAT_PHYS_OFFSET | 0x1, + sirfsoc_l2x_base + L2X0_ADDR_FILTERING_START); + + writel_relaxed(0, + sirfsoc_l2x_base + L2X0_TAG_LATENCY_CTRL); + writel_relaxed(0, + sirfsoc_l2x_base + L2X0_DATA_LATENCY_CTRL); + } + l2x0_init((void __iomem *)sirfsoc_l2x_base, 0x00040000, + 0x00000000); + + return 0; +} +early_initcall(sirfsoc_of_l2x_init); diff --git a/arch/arm/mach-prima2/lluart.c b/arch/arm/mach-prima2/lluart.c new file mode 100644 index 0000000..a89f9b3 --- /dev/null +++ b/arch/arm/mach-prima2/lluart.c @@ -0,0 +1,25 @@ +/* + * Static memory mapping for DEBUG_LL + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/kernel.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <mach/map.h> +#include <mach/uart.h> + +void __init sirfsoc_map_lluart(void) +{ + struct map_desc sirfsoc_lluart_map = { + .virtual = SIRFSOC_UART1_VA_BASE, + .pfn = __phys_to_pfn(SIRFSOC_UART1_PA_BASE), + .length = SIRFSOC_UART1_SIZE, + .type = MT_DEVICE, + }; + + iotable_init(&sirfsoc_lluart_map, 1); +} diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c new file mode 100644 index 0000000..f57124b --- /dev/null +++ b/arch/arm/mach-prima2/prima2.c @@ -0,0 +1,41 @@ +/* + * Defines machines for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include "common.h" + +static struct of_device_id sirfsoc_of_bus_ids[] __initdata = { + { .compatible = "simple-bus", }, + {}, +}; + +void __init sirfsoc_mach_init(void) +{ + of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL); +} + +static const char *prima2cb_dt_match[] __initdata = { + "sirf,prima2-cb", + NULL +}; + +MACHINE_START(PRIMA2_EVB, "prima2cb") + /* Maintainer: Barry Song <baohua.song@csr.com> */ + .boot_params = 0x00000100, + .init_early = sirfsoc_of_clk_init, + .map_io = sirfsoc_map_lluart, + .init_irq = sirfsoc_of_irq_init, + .timer = &sirfsoc_timer, + .init_machine = sirfsoc_mach_init, + .dt_compat = prima2cb_dt_match, +MACHINE_END diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c new file mode 100644 index 0000000..492cfa8 --- /dev/null +++ b/arch/arm/mach-prima2/rstc.c @@ -0,0 +1,70 @@ +/* + * reset controller for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/kernel.h> +#include <linux/mutex.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/of.h> +#include <linux/of_address.h> + +void __iomem *sirfsoc_rstc_base; +static DEFINE_MUTEX(rstc_lock); + +static struct of_device_id rstc_ids[] = { + { .compatible = "sirf,prima2-rstc" }, + {}, +}; + +static int __init sirfsoc_of_rstc_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, rstc_ids); + if (!np) + panic("unable to find compatible rstc node in dtb\n"); + + sirfsoc_rstc_base = of_iomap(np, 0); + if (!sirfsoc_rstc_base) + panic("unable to map rstc cpu registers\n"); + + of_node_put(np); + + return 0; +} +early_initcall(sirfsoc_of_rstc_init); + +int sirfsoc_reset_device(struct device *dev) +{ + const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL); + unsigned int reset_bit; + + if (!prop) + return -ENODEV; + + reset_bit = be32_to_cpup(prop); + + mutex_lock(&rstc_lock); + + /* + * Writing 1 to this bit resets corresponding block. Writing 0 to this + * bit de-asserts reset signal of the corresponding block. + * datasheet doesn't require explicit delay between the set and clear + * of reset bit. it could be shorter if tests pass. + */ + writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, + sirfsoc_rstc_base + (reset_bit / 32) * 4); + msleep(10); + writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, + sirfsoc_rstc_base + (reset_bit / 32) * 4); + + mutex_unlock(&rstc_lock); + + return 0; +} diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c new file mode 100644 index 0000000..ed7ec48 --- /dev/null +++ b/arch/arm/mach-prima2/timer.c @@ -0,0 +1,218 @@ +/* + * System timer for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/clockchips.h> +#include <linux/clocksource.h> +#include <linux/bitops.h> +#include <linux/irq.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <mach/map.h> +#include <asm/mach/time.h> + +#define SIRFSOC_TIMER_COUNTER_LO 0x0000 +#define SIRFSOC_TIMER_COUNTER_HI 0x0004 +#define SIRFSOC_TIMER_MATCH_0 0x0008 +#define SIRFSOC_TIMER_MATCH_1 0x000C +#define SIRFSOC_TIMER_MATCH_2 0x0010 +#define SIRFSOC_TIMER_MATCH_3 0x0014 +#define SIRFSOC_TIMER_MATCH_4 0x0018 +#define SIRFSOC_TIMER_MATCH_5 0x001C +#define SIRFSOC_TIMER_STATUS 0x0020 +#define SIRFSOC_TIMER_INT_EN 0x0024 +#define SIRFSOC_TIMER_WATCHDOG_EN 0x0028 +#define SIRFSOC_TIMER_DIV 0x002C +#define SIRFSOC_TIMER_LATCH 0x0030 +#define SIRFSOC_TIMER_LATCHED_LO 0x0034 +#define SIRFSOC_TIMER_LATCHED_HI 0x0038 + +#define SIRFSOC_TIMER_WDT_INDEX 5 + +#define SIRFSOC_TIMER_LATCH_BIT BIT(0) + +static void __iomem *sirfsoc_timer_base; +static void __init sirfsoc_of_timer_map(void); + +/* timer0 interrupt handler */ +static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *ce = dev_id; + + WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & BIT(0))); + + /* clear timer0 interrupt */ + writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); + + ce->event_handler(ce); + + return IRQ_HANDLED; +} + +/* read 64-bit timer counter */ +static cycle_t sirfsoc_timer_read(struct clocksource *cs) +{ + u64 cycles; + + /* latch the 64-bit timer counter */ + writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); + cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI); + cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); + + return cycles; +} + +static int sirfsoc_timer_set_next_event(unsigned long delta, + struct clock_event_device *ce) +{ + unsigned long now, next; + + writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); + now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); + next = now + delta; + writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0); + writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); + now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); + + return next - now > delta ? -ETIME : 0; +} + +static void sirfsoc_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *ce) +{ + u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + WARN_ON(1); + break; + case CLOCK_EVT_MODE_ONESHOT: + writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + writel_relaxed(val & ~BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static struct clock_event_device sirfsoc_clockevent = { + .name = "sirfsoc_clockevent", + .rating = 200, + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_mode = sirfsoc_timer_set_mode, + .set_next_event = sirfsoc_timer_set_next_event, +}; + +static struct clocksource sirfsoc_clocksource = { + .name = "sirfsoc_clocksource", + .rating = 200, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .read = sirfsoc_timer_read, +}; + +static struct irqaction sirfsoc_timer_irq = { + .name = "sirfsoc_timer0", + .flags = IRQF_TIMER, + .irq = 0, + .handler = sirfsoc_timer_interrupt, + .dev_id = &sirfsoc_clockevent, +}; + +/* Overwrite weak default sched_clock with more precise one */ +unsigned long long notrace sched_clock(void) +{ + static int is_mapped = 0; + + /* + * sched_clock is called earlier than .init of sys_timer + * if we map timer memory in .init of sys_timer, system + * will panic due to illegal memory access + */ + if(!is_mapped) { + sirfsoc_of_timer_map(); + is_mapped = 1; + } + + return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE); +} + +static void __init sirfsoc_clockevent_init(void) +{ + clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); + + sirfsoc_clockevent.max_delta_ns = + clockevent_delta2ns(-2, &sirfsoc_clockevent); + sirfsoc_clockevent.min_delta_ns = + clockevent_delta2ns(2, &sirfsoc_clockevent); + + sirfsoc_clockevent.cpumask = cpumask_of(0); + clockevents_register_device(&sirfsoc_clockevent); +} + +/* initialize the kernel jiffy timer source */ +static void __init sirfsoc_timer_init(void) +{ + unsigned long rate; + + /* timer's input clock is io clock */ + struct clk *clk = clk_get_sys("io", NULL); + + BUG_ON(IS_ERR(clk)); + + rate = clk_get_rate(clk); + + BUG_ON(rate < CLOCK_TICK_RATE); + BUG_ON(rate % CLOCK_TICK_RATE); + + writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); + writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); + writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); + writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); + + BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); + + BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); + + sirfsoc_clockevent_init(); +} + +static struct of_device_id timer_ids[] = { + { .compatible = "sirf,prima2-tick" }, + {}, +}; + +static void __init sirfsoc_of_timer_map(void) +{ + struct device_node *np; + const unsigned int *intspec; + + np = of_find_matching_node(NULL, timer_ids); + if (!np) + panic("unable to find compatible timer node in dtb\n"); + sirfsoc_timer_base = of_iomap(np, 0); + if (!sirfsoc_timer_base) + panic("unable to map timer cpu registers\n"); + + /* Get the interrupts property */ + intspec = of_get_property(np, "interrupts", NULL); + BUG_ON(!intspec); + sirfsoc_timer_irq.irq = be32_to_cpup(intspec); + + of_node_put(np); +} + +struct sys_timer sirfsoc_timer = { + .init = sirfsoc_timer_init, +}; diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 810a982..ef3e8b1 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -825,6 +825,7 @@ MACHINE_START(BALLOON3, "Balloon3") .map_io = balloon3_map_io, .nr_irqs = BALLOON3_NR_IRQS, .init_irq = balloon3_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = balloon3_init, .boot_params = PLAT_PHYS_OFFSET + 0x100, diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index 4284513..648b0ab 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c @@ -151,6 +151,7 @@ MACHINE_START(CAPC7117, .boot_params = 0xa0000100, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = capc7117_init MACHINE_END diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index d515222..4d46610 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -53,6 +53,21 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long flags; + int ret = -EINVAL; + + if (clk->ops->setrate) { + spin_lock_irqsave(&clocks_lock, flags); + ret = clk->ops->setrate(clk, rate); + spin_unlock_irqrestore(&clocks_lock, flags); + } + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + void clk_dummy_enable(struct clk *clk) { } diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index 1f2fb9c..3a258b1 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -5,6 +5,7 @@ struct clkops { void (*enable)(struct clk *); void (*disable)(struct clk *); unsigned long (*getrate)(struct clk *); + int (*setrate)(struct clk *, unsigned long); }; struct clk { diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c index 1afc0fb..6bf479d 100644 --- a/arch/arm/mach-pxa/cm-x2xx-pci.c +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -77,7 +77,7 @@ void cmx2xx_pci_resume(void) {} #endif /* PCI IRQ mapping*/ -static int __init cmx2xx_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init cmx2xx_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; @@ -125,6 +125,9 @@ static void cmx2xx_pci_preinit(void) { pr_info("Initializing CM-X2XX PCI subsystem\n"); + pcibios_min_io = 0; + pcibios_min_mem = 0; + __raw_writel(0x800, IT8152_PCI_CFG_ADDR); if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) { pr_info("PCI Bridge found.\n"); diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index bc55d07..13cf518 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -21,7 +21,8 @@ #include <asm/mach-types.h> #include <asm/mach/map.h> -#include <mach/pxa2xx-regs.h> +#include <mach/pxa25x.h> +#include <mach/pxa27x.h> #include <mach/audio.h> #include <mach/pxafb.h> #include <mach/smemc.h> @@ -516,6 +517,8 @@ MACHINE_START(ARMCORE, "Compulab CM-X2XX") .map_io = cmx2xx_map_io, .nr_irqs = CMX2XX_NR_IRQS, .init_irq = cmx2xx_init_irq, + /* NOTE: pxa25x_handle_irq() works on PXA27x w/o camera support */ + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = cmx2xx_init, #ifdef CONFIG_PCI diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index b199596..b6a5134 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -855,6 +855,7 @@ MACHINE_START(CM_X300, "CM-X300 module") .boot_params = 0xa0000100, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = cm_x300_init, .fixup = cm_x300_fixup, diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index 7545a48..8709209 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270") .init_machine = colibri_pxa270_init, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, MACHINE_END @@ -318,6 +319,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") .init_machine = colibri_pxa270_income_init, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index 66dd81c..60a6781 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -187,6 +187,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") .init_machine = colibri_pxa300_init, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index ff9ff5f..d2c6631 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -23,8 +23,7 @@ #include <asm/mach/arch.h> #include <asm/mach/irq.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa320.h> +#include <mach/pxa320.h> #include <mach/colibri.h> #include <mach/pxafb.h> #include <mach/ohci.h> @@ -258,6 +257,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") .init_machine = colibri_pxa320_init, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 3a5507e..185a37c 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -722,6 +722,7 @@ MACHINE_START(CORGI, "SHARP Corgi") .fixup = fixup_corgi, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, .timer = &pxa_timer, MACHINE_END @@ -732,6 +733,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd") .fixup = fixup_corgi, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, .timer = &pxa_timer, MACHINE_END @@ -742,6 +744,7 @@ MACHINE_START(HUSKY, "SHARP Husky") .fixup = fixup_corgi, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index 0481c29..fe812ea 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -22,10 +22,9 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/csb726.h> -#include <mach/mfp-pxa27x.h> +#include <mach/pxa27x.h> #include <mach/mmc.h> #include <mach/ohci.h> -#include <mach/pxa2xx-regs.h> #include <mach/audio.h> #include <mach/smemc.h> @@ -276,6 +275,7 @@ MACHINE_START(CSB726, "Cogent CSB726") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = csb726_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index f8a6e9d..2e37ea5 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -1302,6 +1302,7 @@ MACHINE_START(EM_X270, "Compulab EM-X270") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = em_x270_init, MACHINE_END @@ -1310,6 +1311,7 @@ MACHINE_START(EXEDA, "Compulab eXeda") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = em_x270_init, MACHINE_END diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 2e3970f..b4599ec 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -193,6 +193,7 @@ MACHINE_START(E330, "Toshiba e330") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e330_init, .timer = &pxa_timer, @@ -242,6 +243,7 @@ MACHINE_START(E350, "Toshiba e350") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e350_init, .timer = &pxa_timer, @@ -364,6 +366,7 @@ MACHINE_START(E400, "Toshiba e400") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e400_init, .timer = &pxa_timer, @@ -552,6 +555,7 @@ MACHINE_START(E740, "Toshiba e740") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e740_init, .timer = &pxa_timer, @@ -743,6 +747,7 @@ MACHINE_START(E750, "Toshiba e750") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e750_init, .timer = &pxa_timer, @@ -947,6 +952,7 @@ MACHINE_START(E800, "Toshiba e800") .map_io = pxa25x_map_io, .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .fixup = eseries_fixup, .init_machine = e800_init, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index d88aed8..b73eadb 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -801,6 +801,7 @@ MACHINE_START(EZX_A780, "Motorola EZX A780") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = a780_init, MACHINE_END @@ -866,6 +867,7 @@ MACHINE_START(EZX_E680, "Motorola EZX E680") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = e680_init, MACHINE_END @@ -931,6 +933,7 @@ MACHINE_START(EZX_A1200, "Motorola EZX A1200") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = a1200_init, MACHINE_END @@ -1121,6 +1124,7 @@ MACHINE_START(EZX_A910, "Motorola EZX A910") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = a910_init, MACHINE_END @@ -1186,6 +1190,7 @@ MACHINE_START(EZX_E6, "Motorola EZX E6") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = e6_init, MACHINE_END @@ -1225,6 +1230,7 @@ MACHINE_START(EZX_E2, "Motorola EZX E2") .map_io = pxa27x_map_io, .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = e2_init, MACHINE_END diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index e6c9344..92a2e85 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -13,21 +13,8 @@ struct irq_data; struct sys_timer; extern struct sys_timer pxa_timer; -extern void __init pxa_init_irq(int irq_nr, - int (*set_wake)(struct irq_data *, - unsigned int)); -extern void __init pxa25x_init_irq(void); -#ifdef CONFIG_CPU_PXA26x -extern void __init pxa26x_init_irq(void); -#endif -extern void __init pxa27x_init_irq(void); -extern void __init pxa3xx_init_irq(void); -extern void __init pxa95x_init_irq(void); extern void __init pxa_map_io(void); -extern void __init pxa25x_map_io(void); -extern void __init pxa27x_map_io(void); -extern void __init pxa3xx_map_io(void); extern unsigned int get_clk_frequency_khz(int info); diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index d65e4bd..deaa111 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -236,6 +236,7 @@ MACHINE_START(GUMSTIX, "Gumstix") .boot_params = 0xa0000100, /* match u-boot bi_boot_params */ .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = gumstix_init, MACHINE_END diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c index 657db46..0a235128 100644 --- a/arch/arm/mach-pxa/h5000.c +++ b/arch/arm/mach-pxa/h5000.c @@ -28,6 +28,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/irq.h> #include <mach/pxa25x.h> #include <mach/h5000.h> @@ -205,6 +206,7 @@ MACHINE_START(H5400, "HP iPAQ H5000") .boot_params = 0xa0000100, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = h5000_init, MACHINE_END diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c index e8603eb..a997d0ab 100644 --- a/arch/arm/mach-pxa/himalaya.c +++ b/arch/arm/mach-pxa/himalaya.c @@ -24,8 +24,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/mfp-pxa25x.h> -#include <mach/hardware.h> +#include <mach/pxa25x.h> #include "generic.h" @@ -162,6 +161,7 @@ MACHINE_START(HIMALAYA, "HTC Himalaya") .boot_params = 0xa0000100, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = himalaya_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 99960a1..c748a47 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -842,6 +842,7 @@ MACHINE_START(H4700, "HP iPAQ HX4700") .map_io = pxa27x_map_io, .nr_irqs = HX4700_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = hx4700_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index 6cedc81..d427429 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -194,6 +194,7 @@ MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") .boot_params = 0xa0000100, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = icontrol_init MACHINE_END diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index f7fb64f..ddf20e5 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -196,6 +196,7 @@ MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") /* Maintainer: Vibren Technologies */ .map_io = idp_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = idp_init, MACHINE_END diff --git a/arch/arm/mach-pxa/include/mach/clkdev.h b/arch/arm/mach-pxa/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-pxa/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 6957ba5..de63ca3 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -337,9 +337,6 @@ extern unsigned long get_clock_tick_rate(void); #endif #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -#define PCIBIOS_MIN_IO 0 -#define PCIBIOS_MIN_MEM 0 -#define pcibios_assign_all_busses() 1 #define ARCH_HAS_DMA_SET_COHERENT_MASK #endif diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 0384024..7cc5a78 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -104,4 +104,16 @@ #define NR_IRQS (IRQ_BOARD_START) +#ifndef __ASSEMBLY__ +struct irq_data; +struct pt_regs; + +void pxa_mask_irq(struct irq_data *); +void pxa_unmask_irq(struct irq_data *); +void icip_handle_irq(struct pt_regs *); +void ichp_handle_irq(struct pt_regs *); + +void pxa_init_irq(int irq_nr, int (*set_wake)(struct irq_data *, unsigned int)); +#endif + #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h index 508c3ba..3ac0baa 100644 --- a/arch/arm/mach-pxa/include/mach/pxa25x.h +++ b/arch/arm/mach-pxa/include/mach/pxa25x.h @@ -4,5 +4,14 @@ #include <mach/hardware.h> #include <mach/pxa2xx-regs.h> #include <mach/mfp-pxa25x.h> +#include <mach/irqs.h> + +extern void __init pxa25x_map_io(void); +extern void __init pxa25x_init_irq(void); +#ifdef CONFIG_CPU_PXA26x +extern void __init pxa26x_init_irq(void); +#endif + +#define pxa25x_handle_irq icip_handle_irq #endif /* __MACH_PXA25x_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h index 0b70269..b9b1bdc 100644 --- a/arch/arm/mach-pxa/include/mach/pxa27x.h +++ b/arch/arm/mach-pxa/include/mach/pxa27x.h @@ -4,6 +4,7 @@ #include <mach/hardware.h> #include <mach/pxa2xx-regs.h> #include <mach/mfp-pxa27x.h> +#include <mach/irqs.h> #define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */ @@ -17,6 +18,10 @@ #define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ #define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ +extern void __init pxa27x_map_io(void); +extern void __init pxa27x_init_irq(void); extern int __init pxa27x_set_pwrmode(unsigned int mode); +#define pxa27x_handle_irq ichp_handle_irq + #endif /* __MACH_PXA27x_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h index 2f33076..733b641 100644 --- a/arch/arm/mach-pxa/include/mach/pxa300.h +++ b/arch/arm/mach-pxa/include/mach/pxa300.h @@ -1,8 +1,7 @@ #ifndef __MACH_PXA300_H #define __MACH_PXA300_H -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> +#include <mach/pxa3xx.h> #include <mach/mfp-pxa300.h> #endif /* __MACH_PXA300_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa320.h b/arch/arm/mach-pxa/include/mach/pxa320.h index cab78e9..b6204e4 100644 --- a/arch/arm/mach-pxa/include/mach/pxa320.h +++ b/arch/arm/mach-pxa/include/mach/pxa320.h @@ -1,8 +1,7 @@ #ifndef __MACH_PXA320_H #define __MACH_PXA320_H -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> +#include <mach/pxa3xx.h> #include <mach/mfp-pxa320.h> #endif /* __MACH_PXA320_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h new file mode 100644 index 0000000..cd3e57f --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa3xx.h @@ -0,0 +1,14 @@ +#ifndef __MACH_PXA3XX_H +#define __MACH_PXA3XX_H + +#include <mach/hardware.h> +#include <mach/pxa3xx-regs.h> +#include <mach/irqs.h> + +extern void __init pxa3xx_map_io(void); +extern void __init pxa3xx_init_irq(void); +extern void __init pxa95x_init_irq(void); + +#define pxa3xx_handle_irq ichp_handle_irq + +#endif /* __MACH_PXA3XX_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h index d45f76a..190363b 100644 --- a/arch/arm/mach-pxa/include/mach/pxa930.h +++ b/arch/arm/mach-pxa/include/mach/pxa930.h @@ -1,8 +1,7 @@ #ifndef __MACH_PXA930_H #define __MACH_PXA930_H -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> +#include <mach/pxa3xx.h> #include <mach/mfp-pxa930.h> #endif /* __MACH_PXA930_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h deleted file mode 100644 index 662288e..0000000 --- a/arch/arm/mach-pxa/include/mach/regs-intc.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __ASM_MACH_REGS_INTC_H -#define __ASM_MACH_REGS_INTC_H - -#include <mach/hardware.h> - -/* - * Interrupt Controller - */ - -#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */ -#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */ -#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */ -#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */ -#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */ -#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */ -#define ICHP __REG(0x40D00018) /* Interrupt Controller Highest Priority Register */ - -#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */ -#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */ -#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */ -#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */ -#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */ - -#define ICIP3 __REG(0x40D00130) /* Interrupt Controller IRQ Pending Register 3 */ -#define ICMR3 __REG(0x40D00134) /* Interrupt Controller Mask Register 3 */ -#define ICLR3 __REG(0x40D00138) /* Interrupt Controller Level Register 3 */ -#define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */ -#define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */ - -#endif /* __ASM_MACH_REGS_INTC_H */ diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 32ed551..b09e848 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -37,6 +37,8 @@ #define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \ ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \ (0x144 + (((i) - 64) << 2))) +#define ICHP_VAL_IRQ (1 << 31) +#define ICHP_IRQ(i) (((i) >> 16) & 0x7fff) #define IPR_VALID (1 << 31) #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) @@ -64,7 +66,7 @@ static inline void __iomem *irq_base(int i) return (void __iomem *)io_p2v(phys_base[i]); } -static void pxa_mask_irq(struct irq_data *d) +void pxa_mask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); uint32_t icmr = __raw_readl(base + ICMR); @@ -73,7 +75,7 @@ static void pxa_mask_irq(struct irq_data *d) __raw_writel(icmr, base + ICMR); } -static void pxa_unmask_irq(struct irq_data *d) +void pxa_unmask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); uint32_t icmr = __raw_readl(base + ICMR); @@ -127,6 +129,36 @@ static struct irq_chip pxa_low_gpio_chip = { .irq_set_type = pxa_set_low_gpio_type, }; +asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs) +{ + uint32_t icip, icmr, mask; + + do { + icip = __raw_readl(IRQ_BASE + ICIP); + icmr = __raw_readl(IRQ_BASE + ICMR); + mask = icip & icmr; + + if (mask == 0) + break; + + handle_IRQ(PXA_IRQ(fls(mask) - 1), regs); + } while (1); +} + +asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs) +{ + uint32_t ichp; + + do { + __asm__ __volatile__("mrc p6, 0, %0, c5, c0, 0\n": "=r"(ichp)); + + if ((ichp & ICHP_VAL_IRQ) == 0) + break; + + handle_IRQ(PXA_IRQ(ICHP_IRQ(ichp)), regs); + } while (1); +} + static void __init pxa_init_low_gpio_irq(set_wake_t fn) { int irq; diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index e5e326d..8f97e15 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -441,6 +441,7 @@ MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleto .map_io = pxa3xx_map_io, .nr_irqs = LITTLETON_NR_IRQS, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = littleton_init, MACHINE_END diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 6cf8180..c171d6e 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -503,6 +503,7 @@ MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine") .map_io = lpd270_map_io, .nr_irqs = LPD270_NR_IRQS, .init_irq = lpd270_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = lpd270_init, MACHINE_END diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index e10ddb8..a8c696b 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -553,6 +553,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") .map_io = lubbock_map_io, .nr_irqs = LUBBOCK_NR_IRQS, .init_irq = lubbock_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = lubbock_init, MACHINE_END diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 0e42798..5fe5bcd 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -757,6 +757,7 @@ MACHINE_START(MAGICIAN, "HTC Magician") .map_io = pxa27x_map_io, .nr_irqs = MAGICIAN_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = magician_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 3479e2b..4622eb7 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -620,6 +620,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") .map_io = mainstone_map_io, .nr_irqs = MAINSTONE_NR_IRQS, .init_irq = mainstone_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = mainstone_init, MACHINE_END diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index aa67637..64810f9 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -754,6 +754,7 @@ MACHINE_START(MIOA701, "MIO A701") .boot_params = 0xa0000100, .map_io = &pxa27x_map_io, .init_irq = &pxa27x_init_irq, + .handle_irq = &pxa27x_handle_irq, .init_machine = mioa701_machine_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c index 59cce78..fb408861 100644 --- a/arch/arm/mach-pxa/mp900.c +++ b/arch/arm/mach-pxa/mp900.c @@ -96,6 +96,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C") .timer = &pxa_timer, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = mp900c_init, MACHINE_END diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 4061ecd..6b77365 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -345,6 +345,7 @@ MACHINE_START(PALMLD, "Palm LifeDrive") .boot_params = 0xa0000100, .map_io = palmld_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = palmld_init MACHINE_END diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index df4d7d0..9bd3e47 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -206,6 +206,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5") .map_io = pxa27x_map_io, .reserve = palmt5_reserve, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = palmt5_init MACHINE_END diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index fb06bd0..6ad4a6c 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -31,14 +31,13 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <mach/pxa25x.h> #include <mach/audio.h> #include <mach/palmtc.h> #include <mach/mmc.h> #include <mach/pxafb.h> -#include <mach/mfp-pxa25x.h> #include <mach/irda.h> #include <mach/udc.h> -#include <mach/pxa2xx-regs.h> #include "generic.h" #include "devices.h" @@ -541,6 +540,7 @@ MACHINE_START(PALMTC, "Palm Tungsten|C") .boot_params = 0xa0000100, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = palmtc_init MACHINE_END diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 726f5b9..664232f 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -31,11 +31,11 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <mach/pxa25x.h> #include <mach/audio.h> #include <mach/palmte2.h> #include <mach/mmc.h> #include <mach/pxafb.h> -#include <mach/mfp-pxa25x.h> #include <mach/irda.h> #include <mach/udc.h> #include <mach/palmasoc.h> @@ -359,6 +359,7 @@ MACHINE_START(PALMTE2, "Palm Tungsten|E2") .boot_params = 0xa0000100, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = palmte2_init MACHINE_END diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index 20d1b18..bb27d4b 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -444,6 +444,7 @@ MACHINE_START(TREO680, "Palm Treo 680") .map_io = pxa27x_map_io, .reserve = treo_reserve, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = treo680_init, MACHINE_END @@ -453,6 +454,7 @@ MACHINE_START(CENTRO, "Palm Centro 685") .map_io = pxa27x_map_io, .reserve = treo_reserve, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = centro_init, MACHINE_END diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 595f002..fc428558 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -367,6 +367,7 @@ MACHINE_START(PALMTX, "Palm T|X") .boot_params = 0xa0000100, .map_io = palmtx_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = palmtx_init MACHINE_END diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 5a5329b..e61c1cc 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -402,6 +402,7 @@ MACHINE_START(PALMZ72, "Palm Zire72") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = palmz72_init MACHINE_END diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 1fc8a66..ffa65df 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -262,6 +262,7 @@ MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270") .map_io = pcm027_map_io, .nr_irqs = PCM027_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = pcm027_init, MACHINE_END diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 16d14fd..a113ea9 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -468,6 +468,7 @@ MACHINE_START(POODLE, "SHARP Poodle") .map_io = pxa25x_map_io, .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = poodle_init, MACHINE_END diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index ef1c56a..b5cd9e5 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -32,7 +32,6 @@ #include <mach/ohci.h> #include <mach/pm.h> #include <mach/dma.h> -#include <mach/regs-intc.h> #include <mach/smemc.h> #include "generic.h" @@ -338,13 +337,13 @@ static void pxa_ack_ext_wakeup(struct irq_data *d) static void pxa_mask_ext_wakeup(struct irq_data *d) { - ICMR2 &= ~(1 << ((d->irq - PXA_IRQ(0)) & 0x1f)); + pxa_mask_irq(d); PECR &= ~PECR_IE(d->irq - IRQ_WAKEUP0); } static void pxa_unmask_ext_wakeup(struct irq_data *d) { - ICMR2 |= 1 << ((d->irq - PXA_IRQ(0)) & 0x1f); + pxa_unmask_irq(d); PECR |= PECR_IE(d->irq - IRQ_WAKEUP0); } diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c index ecc82a3..0ee166b 100644 --- a/arch/arm/mach-pxa/pxa95x.c +++ b/arch/arm/mach-pxa/pxa95x.c @@ -27,7 +27,6 @@ #include <mach/reset.h> #include <mach/pm.h> #include <mach/dma.h> -#include <mach/regs-intc.h> #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 2f37d43..bbcd905 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -46,10 +46,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> -#include <mach/pxa3xx-regs.h> -#include <mach/mfp-pxa3xx.h> -#include <mach/mfp-pxa300.h> +#include <mach/pxa300.h> #include <mach/ohci.h> #include <mach/pxafb.h> #include <mach/mmc.h> @@ -1093,6 +1090,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") .init_machine = raumfeld_controller_init, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, MACHINE_END #endif @@ -1103,6 +1101,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") .init_machine = raumfeld_connector_init, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, MACHINE_END #endif @@ -1113,6 +1112,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") .init_machine = raumfeld_speaker_init, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index fee97a9..df4356e 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -599,6 +599,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") .boot_params = 0xa0000100, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = saar_init, MACHINE_END diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c index e53a333..ebd6379 100644 --- a/arch/arm/mach-pxa/saarb.c +++ b/arch/arm/mach-pxa/saarb.c @@ -107,6 +107,7 @@ MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)") .map_io = pxa3xx_map_io, .nr_irqs = SAARB_NR_IRQS, .init_irq = pxa95x_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = saarb_init, MACHINE_END diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 01c5769..438c7b5 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz") .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, .timer = &pxa_timer, MACHINE_END @@ -994,6 +995,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi") .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, .timer = &pxa_timer, MACHINE_END @@ -1004,6 +1006,7 @@ MACHINE_START(AKITA, "SHARP Akita") .fixup = spitz_fixup, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index cb5611d..3f8d0af 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -1001,6 +1001,7 @@ static void __init stargate2_init(void) MACHINE_START(INTELMOTE2, "IMOTE 2") .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = imote2_init, .boot_params = 0xA0000100, @@ -1012,6 +1013,7 @@ MACHINE_START(STARGATE2, "Stargate 2") .map_io = pxa27x_map_io, .nr_irqs = STARGATE_NR_IRQS, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = stargate2_init, .boot_params = 0xA0000100, diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 53d4a47..32fb58e 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -492,6 +492,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") .boot_params = 0xa0000100, .map_io = pxa3xx_map_io, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = tavorevb_init, MACHINE_END diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c index 79f4422..fd5a8ea 100644 --- a/arch/arm/mach-pxa/tavorevb3.c +++ b/arch/arm/mach-pxa/tavorevb3.c @@ -129,6 +129,7 @@ MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)") .map_io = pxa3xx_map_io, .nr_irqs = TAVOREVB3_NR_IRQS, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = evb3_init, MACHINE_END diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 5fa1457..9f69a26 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -974,6 +974,7 @@ MACHINE_START(TOSA, "SHARP Tosa") .map_io = pxa25x_map_io, .nr_irqs = TOSA_NR_IRQS, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .init_machine = tosa_init, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 687417a..c041750 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -558,6 +558,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module") .init_machine = trizeps4_init, .map_io = trizeps4_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, MACHINE_END @@ -567,5 +568,6 @@ MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module") .init_machine = trizeps4_init, .map_io = trizeps4_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 903218e..d4a3dc7 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -995,6 +995,7 @@ MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC") .boot_params = 0xa0000100, .map_io = viper_map_io, .init_irq = viper_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, .init_machine = viper_init, MACHINE_END diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 67bd414..5f8490a 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -719,6 +719,7 @@ MACHINE_START(VPAC270, "Voipac PXA270") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = vpac270_init MACHINE_END diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index f55f8f2..acc600f 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c @@ -28,8 +28,7 @@ #include <asm/mach/map.h> #include <mach/hardware.h> -#include <mach/pxa2xx-regs.h> -#include <mach/mfp-pxa25x.h> +#include <mach/pxa25x.h> #include <mach/smemc.h> #include "generic.h" @@ -185,6 +184,7 @@ MACHINE_START(XCEP, "Iskratel XCEP") .init_machine = xcep_init, .map_io = pxa25x_map_io, .init_irq = pxa25x_init_irq, + .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, MACHINE_END diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index fbe9e02..6c9275a 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -40,6 +40,7 @@ #include <mach/pxafb.h> #include <mach/mmc.h> #include <plat/pxa27x_keypad.h> +#include <mach/pm.h> #include "generic.h" #include "devices.h" @@ -677,6 +678,20 @@ static void __init z2_pmic_init(void) static inline void z2_pmic_init(void) {} #endif +#ifdef CONFIG_PM +static void z2_power_off(void) +{ + /* We're using deep sleep as poweroff, so clear PSPR to ensure that + * bootloader will jump to its entry point in resume handler + */ + PSPR = 0x0; + local_irq_disable(); + pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); +} +#else +#define z2_power_off NULL +#endif + /****************************************************************************** * Machine init ******************************************************************************/ @@ -698,12 +713,15 @@ static void __init z2_init(void) z2_leds_init(); z2_keys_init(); z2_pmic_init(); + + pm_power_off = z2_power_off; } MACHINE_START(ZIPIT2, "Zipit Z2") .boot_params = 0xa0000100, .map_io = pxa27x_map_io, .init_irq = pxa27x_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = z2_init, MACHINE_END diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 9b99cc1..99c49bc 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -35,14 +35,13 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/pxa2xx-regs.h> +#include <mach/pxa27x.h> #include <mach/regs-uart.h> #include <mach/ohci.h> #include <mach/mmc.h> #include <mach/pxa27x-udc.h> #include <mach/udc.h> #include <mach/pxafb.h> -#include <mach/mfp-pxa27x.h> #include <mach/pm.h> #include <mach/audio.h> #include <mach/arcom-pcmcia.h> @@ -909,6 +908,7 @@ MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS") .map_io = zeus_map_io, .nr_irqs = ZEUS_NR_IRQS, .init_irq = zeus_init_irq, + .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, .init_machine = zeus_init, MACHINE_END diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 5821185..15ec66b 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -24,7 +24,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/hardware.h> +#include <mach/pxa3xx.h> #include <mach/audio.h> #include <mach/pxafb.h> #include <mach/zylonite.h> @@ -426,6 +426,7 @@ MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") .map_io = pxa3xx_map_io, .nr_irqs = ZYLONITE_NR_IRQS, .init_irq = pxa3xx_init_irq, + .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, .init_machine = zylonite_init, MACHINE_END diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h index a30f2e3..6657ff23 100644 --- a/arch/arm/mach-realview/include/mach/system.h +++ b/arch/arm/mach-realview/include/mach/system.h @@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd) */ if (realview_reset) realview_reset(mode); + dsb(); } #endif diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h index 70a83b2..45eea52 100644 --- a/arch/arm/mach-s3c2410/include/mach/pm-core.h +++ b/arch/arm/mach-s3c2410/include/mach/pm-core.h @@ -62,3 +62,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs, struct pm_uart_save *save) { } + +static inline void s3c_pm_restored_gpios(void) { } +static inline void s3c_pm_saved_gpios(void) { } diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index 554e0d3..f9e6bda 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c @@ -36,7 +36,7 @@ #include <linux/io.h> #include <mach/hardware.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <mach/regs-clock.h> diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c index 6224bad..9ad99f8 100644 --- a/arch/arm/mach-s3c2440/s3c2442.c +++ b/arch/arm/mach-s3c2440/s3c2442.c @@ -38,7 +38,7 @@ #include <linux/io.h> #include <mach/hardware.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <mach/regs-clock.h> diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c index f8d9613..7f5ea0a 100644 --- a/arch/arm/mach-s3c2440/s3c244x-clock.c +++ b/arch/arm/mach-s3c2440/s3c244x-clock.c @@ -35,7 +35,7 @@ #include <linux/io.h> #include <mach/hardware.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <mach/regs-clock.h> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index fdc89fc..f057b6a 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -267,3 +267,26 @@ config MACH_SMARTQ7 select MACH_SMARTQ help Machine support for the SmartQ 7 + +config MACH_WLF_CRAGG_6410 + bool "Wolfson Cragganmore 6410" + select CPU_S3C6410 + select S3C64XX_SETUP_SDHCI + select S3C64XX_SETUP_I2C1 + select S3C64XX_SETUP_IDE + select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_KEYPAD + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_KEYPAD + select S3C_DEV_USB_HOST + select S3C_DEV_USB_HSOTG + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_HSMMC2 + select S3C_DEV_I2C1 + select S3C_DEV_WDT + select S3C_DEV_RTC + select S3C64XX_DEV_SPI + select S3C24XX_GPIO_EXTRA128 + help + Machine support for the Wolfson Cragganmore S3C6410 variant. diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index f5a7144..61b4034 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_MACH_HMT) += mach-hmt.o obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o +obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o # device support diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h index 8e2df26..c026f67 100644 --- a/arch/arm/mach-s3c64xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h @@ -198,7 +198,9 @@ * interrupt controllers). */ #define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) -#ifdef CONFIG_SMDK6410_WM1190_EV1 +#ifdef CONFIG_MACH_WLF_CRAGG_6410 +#define IRQ_BOARD_NR 128 +#elif defined(CONFIG_SMDK6410_WM1190_EV1) #define IRQ_BOARD_NR 64 #elif defined(CONFIG_SMDK6410_WM1192_EV1) #define IRQ_BOARD_NR 64 @@ -215,6 +217,7 @@ /* Compatibility */ #define IRQ_ONENAND IRQ_ONENAND0 +#define IRQ_I2S0 IRQ_S3C6410_IIS #endif /* __ASM_MACH_S3C64XX_IRQS_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h index 1e9f20f..38659be 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h @@ -53,7 +53,7 @@ static inline void s3c_pm_arch_show_resume_irqs(void) * the IRQ wake controls depending on the CPU we are running on */ #define s3c_irqwake_eintallow ((1 << 28) - 1) -#define s3c_irqwake_intallow (0) +#define s3c_irqwake_intallow (~0) static inline void s3c_pm_arch_update_uart(void __iomem *regs, struct pm_uart_save *save) @@ -96,3 +96,20 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs, save->ucon = new_ucon; } } + +static inline void s3c_pm_restored_gpios(void) +{ + /* ensure sleep mode has been cleared from the system */ + + __raw_writel(0, S3C64XX_SLPEN); +} + +static inline void s3c_pm_saved_gpios(void) +{ + /* turn on the sleep mode and keep it there, as it seems that during + * suspend the xCON registers get re-set and thus you can end up with + * problems between going to sleep and resuming. + */ + + __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN); +} diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c index 97660c8..75d9a0e 100644 --- a/arch/arm/mach-s3c64xx/irq.c +++ b/arch/arm/mach-s3c64xx/irq.c @@ -48,14 +48,22 @@ static struct s3c_uart_irq uart_irqs[] = { }, }; +/* setup the sources the vic should advertise resume for, even though it + * is not doing the wake (set_irq_wake needs to be valid) */ +#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE)) +#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \ + 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE)) void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); /* initialise the pair of VICs */ - vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0); - vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0); + vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME); + vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME); /* add the timer sub-irqs */ s3c_init_vic_timer_irq(5, IRQ_TIMER0); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c new file mode 100644 index 0000000..af0c2fe --- /dev/null +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -0,0 +1,774 @@ +/* linux/arch/arm/mach-s3c64xx/mach-crag6410.c + * + * Copyright 2011 Wolfson Microelectronics plc + * Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * Copyright 2011 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/serial_core.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/io.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/pwm_backlight.h> +#include <linux/dm9000.h> +#include <linux/gpio_keys.h> +#include <linux/basic_mmio_gpio.h> +#include <linux/spi/spi.h> + +#include <linux/i2c/pca953x.h> + +#include <video/platform_lcd.h> + +#include <linux/mfd/wm831x/core.h> +#include <linux/mfd/wm831x/pdata.h> +#include <linux/mfd/wm831x/irq.h> +#include <linux/mfd/wm831x/gpio.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include <mach/hardware.h> +#include <mach/map.h> + +#include <mach/s3c6410.h> +#include <mach/regs-sys.h> +#include <mach/regs-gpio.h> +#include <mach/regs-modem.h> + +#include <mach/regs-gpio-memport.h> + +#include <plat/regs-serial.h> +#include <plat/regs-fb-v4.h> +#include <plat/fb.h> +#include <plat/sdhci.h> +#include <plat/gpio-cfg.h> +#include <plat/s3c64xx-spi.h> + +#include <plat/keypad.h> +#include <plat/clock.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/adc.h> +#include <plat/iic.h> +#include <plat/pm.h> + +#include <sound/wm8996.h> +#include <sound/wm8962.h> +#include <sound/wm9081.h> + +#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START +#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) + +#define PCA935X_GPIO_BASE GPIO_BOARD_START +#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) +#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16) + +/* serial port setup */ + +#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) +#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) + +static struct s3c2410_uartcfg crag6410_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [3] = { + .hwport = 3, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, +}; + +static struct platform_pwm_backlight_data crag6410_backlight_data = { + .pwm_id = 0, + .max_brightness = 1000, + .dft_brightness = 600, + .pwm_period_ns = 100000, /* about 1kHz */ +}; + +static struct platform_device crag6410_backlight_device = { + .name = "pwm-backlight", + .id = -1, + .dev = { + .parent = &s3c_device_timer[0].dev, + .platform_data = &crag6410_backlight_data, + }, +}; + +static void crag6410_lcd_power_set(struct plat_lcd_data *pd, unsigned int power) +{ + pr_debug("%s: setting power %d\n", __func__, power); + + if (power) { + gpio_set_value(S3C64XX_GPB(0), 1); + msleep(1); + s3c_gpio_cfgpin(S3C64XX_GPF(14), S3C_GPIO_SFN(2)); + } else { + gpio_direction_output(S3C64XX_GPF(14), 0); + gpio_set_value(S3C64XX_GPB(0), 0); + } +} + +static struct platform_device crag6410_lcd_powerdev = { + .name = "platform-lcd", + .id = -1, + .dev.parent = &s3c_device_fb.dev, + .dev.platform_data = &(struct plat_lcd_data) { + .set_power = crag6410_lcd_power_set, + }, +}; + +/* 640x480 URT */ +static struct s3c_fb_pd_win crag6410_fb_win0 = { + /* this is to ensure we use win0 */ + .win_mode = { + .left_margin = 150, + .right_margin = 80, + .upper_margin = 40, + .lower_margin = 5, + .hsync_len = 40, + .vsync_len = 5, + .xres = 640, + .yres = 480, + }, + .max_bpp = 32, + .default_bpp = 16, + .virtual_y = 480 * 2, + .virtual_x = 640, +}; + +/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ +static struct s3c_fb_platdata crag6410_lcd_pdata __initdata = { + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, + .win[0] = &crag6410_fb_win0, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, +}; + +/* 2x6 keypad */ + +static uint32_t crag6410_keymap[] __initdata = { + /* KEY(row, col, keycode) */ + KEY(0, 0, KEY_VOLUMEUP), + KEY(0, 1, KEY_HOME), + KEY(0, 2, KEY_VOLUMEDOWN), + KEY(0, 3, KEY_HELP), + KEY(0, 4, KEY_MENU), + KEY(0, 5, KEY_MEDIA), + KEY(1, 0, 232), + KEY(1, 1, KEY_DOWN), + KEY(1, 2, KEY_LEFT), + KEY(1, 3, KEY_UP), + KEY(1, 4, KEY_RIGHT), + KEY(1, 5, KEY_CAMERA), +}; + +static struct matrix_keymap_data crag6410_keymap_data __initdata = { + .keymap = crag6410_keymap, + .keymap_size = ARRAY_SIZE(crag6410_keymap), +}; + +static struct samsung_keypad_platdata crag6410_keypad_data __initdata = { + .keymap_data = &crag6410_keymap_data, + .rows = 2, + .cols = 6, +}; + +static struct gpio_keys_button crag6410_gpio_keys[] = { + [0] = { + .code = KEY_SUSPEND, + .gpio = S3C64XX_GPL(10), /* EINT 18 */ + .type = EV_KEY, + .wakeup = 1, + .active_low = 1, + }, + [1] = { + .code = SW_FRONT_PROXIMITY, + .gpio = S3C64XX_GPN(11), /* EINT 11 */ + .type = EV_SW, + }, +}; + +static struct gpio_keys_platform_data crag6410_gpio_keydata = { + .buttons = crag6410_gpio_keys, + .nbuttons = ARRAY_SIZE(crag6410_gpio_keys), +}; + +static struct platform_device crag6410_gpio_keydev = { + .name = "gpio-keys", + .id = 0, + .dev.platform_data = &crag6410_gpio_keydata, +}; + +static struct resource crag6410_dm9k_resource[] = { + [0] = { + .start = S3C64XX_PA_XM0CSN5, + .end = S3C64XX_PA_XM0CSN5 + 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C64XX_PA_XM0CSN5 + (1 << 8), + .end = S3C64XX_PA_XM0CSN5 + (1 << 8) + 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = S3C_EINT(17), + .end = S3C_EINT(17), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct dm9000_plat_data mini6410_dm9k_pdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device crag6410_dm9k_device = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(crag6410_dm9k_resource), + .resource = crag6410_dm9k_resource, + .dev.platform_data = &mini6410_dm9k_pdata, +}; + +static struct resource crag6410_mmgpio_resource[] = { + [0] = { + .start = S3C64XX_PA_XM0CSN4 + 1, + .end = S3C64XX_PA_XM0CSN4 + 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device crag6410_mmgpio = { + .name = "basic-mmio-gpio", + .id = -1, + .resource = crag6410_mmgpio_resource, + .num_resources = ARRAY_SIZE(crag6410_mmgpio_resource), + .dev.platform_data = &(struct bgpio_pdata) { + .base = -1, + }, +}; + +static struct platform_device speyside_device = { + .name = "speyside", + .id = -1, +}; + +static struct platform_device speyside_wm8962_device = { + .name = "speyside-wm8962", + .id = -1, +}; + +static struct regulator_consumer_supply wallvdd_consumers[] = { + REGULATOR_SUPPLY("SPKVDD1", "1-001a"), + REGULATOR_SUPPLY("SPKVDD2", "1-001a"), +}; + +static struct regulator_init_data wallvdd_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(wallvdd_consumers), + .consumer_supplies = wallvdd_consumers, +}; + +static struct fixed_voltage_config wallvdd_pdata = { + .supply_name = "WALLVDD", + .microvolts = 5000000, + .init_data = &wallvdd_data, + .gpio = -EINVAL, +}; + +static struct platform_device wallvdd_device = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &wallvdd_pdata, + }, +}; + +static struct platform_device *crag6410_devices[] __initdata = { + &s3c_device_hsmmc0, + &s3c_device_hsmmc1, + &s3c_device_hsmmc2, + &s3c_device_i2c0, + &s3c_device_i2c1, + &s3c_device_fb, + &s3c_device_ohci, + &s3c_device_usb_hsotg, + &s3c_device_adc, + &s3c_device_rtc, + &s3c_device_ts, + &s3c_device_timer[0], + &s3c64xx_device_iis0, + &s3c64xx_device_iis1, + &samsung_asoc_dma, + &samsung_device_keypad, + &crag6410_gpio_keydev, + &crag6410_dm9k_device, + &s3c64xx_device_spi0, + &crag6410_mmgpio, + &crag6410_lcd_powerdev, + &crag6410_backlight_device, + &speyside_device, + &speyside_wm8962_device, + &wallvdd_device, +}; + +static struct pca953x_platform_data crag6410_pca_data = { + .gpio_base = PCA935X_GPIO_BASE, + .irq_base = 0, +}; + +static struct regulator_consumer_supply vddarm_consumers[] __initdata = { + REGULATOR_SUPPLY("vddarm", NULL), +}; + +static struct regulator_init_data vddarm __initdata = { + .constraints = { + .name = "VDDARM", + .min_uV = 1000000, + .max_uV = 1300000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers), + .consumer_supplies = vddarm_consumers, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddint __initdata = { + .constraints = { + .name = "VDDINT", + .min_uV = 1000000, + .max_uV = 1200000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, +}; + +static struct regulator_init_data vddmem __initdata = { + .constraints = { + .name = "VDDMEM", + .always_on = 1, + }, +}; + +static struct regulator_init_data vddsys __initdata = { + .constraints = { + .name = "VDDSYS,VDDEXT,VDDPCM,VDDSS", + .always_on = 1, + }, +}; + +static struct regulator_consumer_supply vddmmc_consumers[] __initdata = { + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.1"), + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), +}; + +static struct regulator_init_data vddmmc __initdata = { + .constraints = { + .name = "VDDMMC,UH", + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(vddmmc_consumers), + .consumer_supplies = vddmmc_consumers, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddotgi __initdata = { + .constraints = { + .name = "VDDOTGi", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddotg __initdata = { + .constraints = { + .name = "VDDOTG", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddhi __initdata = { + .constraints = { + .name = "VDDHI", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddadc __initdata = { + .constraints = { + .name = "VDDADC,VDDDAC", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddmem0 __initdata = { + .constraints = { + .name = "VDDMEM0", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddpll __initdata = { + .constraints = { + .name = "VDDPLL", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddlcd __initdata = { + .constraints = { + .name = "VDDLCD", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data vddalive __initdata = { + .constraints = { + .name = "VDDALIVE", + .always_on = 1, + }, + .supply_regulator = "WALLVDD", +}; + +static struct wm831x_backup_pdata banff_backup_pdata __initdata = { + .charger_enable = 1, + .vlim = 2500, /* mV */ + .ilim = 200, /* uA */ +}; + +static struct wm831x_status_pdata banff_red_led __initdata = { + .name = "banff:red:", + .default_src = WM831X_STATUS_MANUAL, +}; + +static struct wm831x_status_pdata banff_green_led __initdata = { + .name = "banff:green:", + .default_src = WM831X_STATUS_MANUAL, +}; + +static struct wm831x_touch_pdata touch_pdata __initdata = { + .data_irq = S3C_EINT(26), + .pd_irq = S3C_EINT(27), +}; + +static struct wm831x_pdata crag_pmic_pdata __initdata = { + .wm831x_num = 1, + .irq_base = BANFF_PMIC_IRQ_BASE, + .gpio_base = GPIO_BOARD_START + 8, + + .backup = &banff_backup_pdata, + + .gpio_defaults = { + /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/ + [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6, + /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/ + [11] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x7, + }, + + .dcdc = { + &vddarm, /* DCDC1 */ + &vddint, /* DCDC2 */ + &vddmem, /* DCDC3 */ + }, + + .ldo = { + &vddsys, /* LDO1 */ + &vddmmc, /* LDO2 */ + NULL, /* LDO3 */ + &vddotgi, /* LDO4 */ + &vddotg, /* LDO5 */ + &vddhi, /* LDO6 */ + &vddadc, /* LDO7 */ + &vddmem0, /* LDO8 */ + &vddpll, /* LDO9 */ + &vddlcd, /* LDO10 */ + &vddalive, /* LDO11 */ + }, + + .status = { + &banff_green_led, + &banff_red_led, + }, + + .touch = &touch_pdata, +}; + +static struct i2c_board_info i2c_devs0[] __initdata = { + { I2C_BOARD_INFO("24c08", 0x50), }, + { I2C_BOARD_INFO("tca6408", 0x20), + .platform_data = &crag6410_pca_data, + }, + { I2C_BOARD_INFO("wm8312", 0x34), + .platform_data = &crag_pmic_pdata, + .irq = S3C_EINT(23), + }, +}; + +static struct s3c2410_platform_i2c i2c0_pdata = { + .frequency = 400000, +}; + +static struct regulator_init_data pvdd_1v2 __initdata = { + .constraints = { + .name = "PVDD_1V2", + .always_on = 1, + }, +}; + +static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { + REGULATOR_SUPPLY("PLLVDD", "1-001a"), + REGULATOR_SUPPLY("DBVDD", "1-001a"), + REGULATOR_SUPPLY("CPVDD", "1-001a"), + REGULATOR_SUPPLY("AVDD2", "1-001a"), + REGULATOR_SUPPLY("DCVDD", "1-001a"), + REGULATOR_SUPPLY("AVDD", "1-001a"), +}; + +static struct regulator_init_data pvdd_1v8 __initdata = { + .constraints = { + .name = "PVDD_1V8", + .always_on = 1, + }, + + .consumer_supplies = pvdd_1v8_consumers, + .num_consumer_supplies = ARRAY_SIZE(pvdd_1v8_consumers), +}; + +static struct regulator_consumer_supply pvdd_3v3_consumers[] __initdata = { + REGULATOR_SUPPLY("MICVDD", "1-001a"), + REGULATOR_SUPPLY("AVDD1", "1-001a"), +}; + +static struct regulator_init_data pvdd_3v3 __initdata = { + .constraints = { + .name = "PVDD_3V3", + .always_on = 1, + }, + + .consumer_supplies = pvdd_3v3_consumers, + .num_consumer_supplies = ARRAY_SIZE(pvdd_3v3_consumers), +}; + +static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = { + .wm831x_num = 2, + .irq_base = GLENFARCLAS_PMIC_IRQ_BASE, + .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE, + + .gpio_defaults = { + /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */ + [0] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA, + [1] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA, + [2] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA, + }, + + .dcdc = { + &pvdd_1v2, /* DCDC1 */ + &pvdd_1v8, /* DCDC2 */ + &pvdd_3v3, /* DCDC3 */ + }, + + .disable_touch = true, +}; + +static struct wm8996_retune_mobile_config wm8996_retune[] = { + { + .name = "Sub LPF", + .rate = 48000, + .regs = { + 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000, + 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000, + 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000 + }, + }, + { + .name = "Sub HPF", + .rate = 48000, + .regs = { + 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000, + 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000, + 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000 + }, + }, +}; + +static struct wm8996_pdata wm8996_pdata __initdata = { + .ldo_ena = S3C64XX_GPN(7), + .gpio_base = CODEC_GPIO_BASE, + .micdet_def = 1, + .inl_mode = WM8996_DIFFERRENTIAL_1, + .inr_mode = WM8996_DIFFERRENTIAL_1, + + .irq_flags = IRQF_TRIGGER_RISING, + + .gpio_default = { + 0x8001, /* GPIO1 == ADCLRCLK1 */ + 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */ + 0x0141, /* GPIO3 == HP_SEL */ + 0x0002, /* GPIO4 == IRQ */ + 0x020e, /* GPIO5 == CLKOUT */ + }, + + .retune_mobile_cfgs = wm8996_retune, + .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune), +}; + +static struct wm8962_pdata wm8962_pdata __initdata = { + .gpio_init = { + 0, + WM8962_GPIO_FN_OPCLK, + WM8962_GPIO_FN_DMICCLK, + 0, + 0x8000 | WM8962_GPIO_FN_DMICDAT, + WM8962_GPIO_FN_IRQ, /* Open drain mode */ + }, + .irq_active_low = true, +}; + +static struct wm9081_pdata wm9081_pdata __initdata = { + .irq_high = false, + .irq_cmos = false, +}; + +static struct i2c_board_info i2c_devs1[] __initdata = { + { I2C_BOARD_INFO("wm8311", 0x34), + .irq = S3C_EINT(0), + .platform_data = &glenfarclas_pmic_pdata }, + + { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, + { I2C_BOARD_INFO("wm8996", 0x1a), + .platform_data = &wm8996_pdata, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, + }, + { I2C_BOARD_INFO("wm9081", 0x6c), + .platform_data = &wm9081_pdata, }, + { I2C_BOARD_INFO("wm8962", 0x1a), + .platform_data = &wm8962_pdata, + .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, + }, +}; + +static void __init crag6410_map_io(void) +{ + s3c64xx_init_io(NULL, 0); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); + + /* LCD type and Bypass set by bootloader */ +} + +static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = { + .max_width = 4, + .cd_type = S3C_SDHCI_CD_PERMANENT, +}; + +static struct s3c_sdhci_platdata crag6410_hsmmc1_pdata = { + .max_width = 4, + .cd_type = S3C_SDHCI_CD_GPIO, + .ext_cd_gpio = S3C64XX_GPF(11), +}; + +static void crag6410_cfg_sdhci0(struct platform_device *dev, int width) +{ + /* Set all the necessary GPG pins to special-function 2 */ + s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2)); + + /* force card-detected for prototype 0 */ + s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_DOWN); +} + +static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = { + .max_width = 4, + .cd_type = S3C_SDHCI_CD_INTERNAL, + .cfg_gpio = crag6410_cfg_sdhci0, +}; + +static void __init crag6410_machine_init(void) +{ + /* Open drain IRQs need pullups */ + s3c_gpio_setpull(S3C64XX_GPM(0), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S3C64XX_GPN(0), S3C_GPIO_PULL_UP); + + gpio_request(S3C64XX_GPB(0), "LCD power"); + gpio_direction_output(S3C64XX_GPB(0), 0); + + gpio_request(S3C64XX_GPF(14), "LCD PWM"); + gpio_direction_output(S3C64XX_GPF(14), 0); /* turn off */ + + gpio_request(S3C64XX_GPB(1), "SD power"); + gpio_direction_output(S3C64XX_GPB(1), 0); + + gpio_request(S3C64XX_GPF(10), "nRESETSEL"); + gpio_direction_output(S3C64XX_GPF(10), 1); + + s3c_sdhci0_set_platdata(&crag6410_hsmmc0_pdata); + s3c_sdhci1_set_platdata(&crag6410_hsmmc1_pdata); + s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata); + + s3c_i2c0_set_platdata(&i2c0_pdata); + s3c_i2c1_set_platdata(NULL); + s3c_fb_set_platdata(&crag6410_lcd_pdata); + + i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); + i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); + + samsung_keypad_set_platdata(&crag6410_keypad_data); + + platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); + + regulator_has_full_constraints(); + + s3c_pm_init(); +} + +MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410") + /* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */ + .boot_params = S3C64XX_PA_SDRAM + 0x100, + .init_irq = s3c6410_init_irq, + .map_io = crag6410_map_io, + .init_machine = crag6410_machine_init, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 8bad643..055e285 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -16,6 +16,7 @@ #include <linux/suspend.h> #include <linux/serial_core.h> #include <linux/io.h> +#include <linux/gpio.h> #include <mach/map.h> #include <mach/irqs.h> diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile index ae6bf6f..5f6afdf 100644 --- a/arch/arm/mach-s5p64x0/Makefile +++ b/arch/arm/mach-s5p64x0/Makefile @@ -13,7 +13,7 @@ obj- := # Core support for S5P64X0 system obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o -obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o +obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h index 513abff..5837a36 100644 --- a/arch/arm/mach-s5p64x0/include/mach/irqs.h +++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h @@ -85,6 +85,8 @@ #define IRQ_S3CUART_RX4 IRQ_S5P_UART_RX4 #define IRQ_S3CUART_RX5 IRQ_S5P_UART_RX5 +#define IRQ_I2S0 IRQ_I2SV40 + /* S5P6450 EINT feature will be added */ /* diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h index 0953ef6..6ce2547 100644 --- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h @@ -34,4 +34,14 @@ #define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180) #define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300) +/* External interrupt control registers for group0 */ + +#define EINT0CON0_OFFSET (0x900) +#define EINT0MASK_OFFSET (0x920) +#define EINT0PEND_OFFSET (0x924) + +#define S5P64X0_EINT0CON0 (S5P_VA_GPIO + EINT0CON0_OFFSET) +#define S5P64X0_EINT0MASK (S5P_VA_GPIO + EINT0MASK_OFFSET) +#define S5P64X0_EINT0PEND (S5P_VA_GPIO + EINT0PEND_OFFSET) + #endif /* __ASM_ARCH_REGS_GPIO_H */ diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c new file mode 100644 index 0000000..fe7380f --- /dev/null +++ b/arch/arm/mach-s5p64x0/irq-eint.c @@ -0,0 +1,152 @@ +/* arch/arm/mach-s5p64x0/irq-eint.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.com/ + * + * Based on linux/arch/arm/mach-s3c64xx/irq-eint.c + * + * S5P64X0 - Interrupt handling for External Interrupts. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <plat/regs-irqtype.h> +#include <plat/gpio-cfg.h> + +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> + +#define eint_offset(irq) ((irq) - IRQ_EINT(0)) + +static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type) +{ + int offs = eint_offset(data->irq); + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + + if (offs > 15) + return -EINVAL; + + switch (type) { + case IRQ_TYPE_NONE: + printk(KERN_WARNING "No edge setting!\n"); + break; + case IRQ_TYPE_EDGE_RISING: + newvalue = S3C2410_EXTINT_RISEEDGE; + break; + case IRQ_TYPE_EDGE_FALLING: + newvalue = S3C2410_EXTINT_FALLEDGE; + break; + case IRQ_TYPE_EDGE_BOTH: + newvalue = S3C2410_EXTINT_BOTHEDGE; + break; + case IRQ_TYPE_LEVEL_LOW: + newvalue = S3C2410_EXTINT_LOWLEV; + break; + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S3C2410_EXTINT_HILEV; + break; + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + shift = (offs / 2) * 4; + mask = 0x7 << shift; + + ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, S5P64X0_EINT0CON0); + + /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */ + if (0x50000 == (__raw_readl(S5P64X0_SYS_ID) & 0xFF000)) + s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2)); + else + s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2)); + + return 0; +} + +/* + * s5p64x0_irq_demux_eint + * + * This function demuxes the IRQ from the group0 external interrupts, + * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into + * the specific handlers s5p64x0_irq_demux_eintX_Y. + */ +static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end) +{ + u32 status = __raw_readl(S5P64X0_EINT0PEND); + u32 mask = __raw_readl(S5P64X0_EINT0MASK); + unsigned int irq; + + status &= ~mask; + status >>= start; + status &= (1 << (end - start + 1)) - 1; + + for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) { + if (status & 1) + generic_handle_irq(irq); + status >>= 1; + } +} + +static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc) +{ + s5p64x0_irq_demux_eint(0, 3); +} + +static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc) +{ + s5p64x0_irq_demux_eint(4, 11); +} + +static void s5p64x0_irq_demux_eint12_15(unsigned int irq, + struct irq_desc *desc) +{ + s5p64x0_irq_demux_eint(12, 15); +} + +static int s5p64x0_alloc_gc(void) +{ + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE, + S5P_VA_GPIO, handle_level_irq); + if (!gc) { + printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0" + "external interrupts failed\n", __func__); + return -EINVAL; + } + + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + ct->chip.irq_set_type = s5p64x0_irq_eint_set_type; + ct->regs.ack = EINT0PEND_OFFSET; + ct->regs.mask = EINT0MASK_OFFSET; + irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + return 0; +} + +static int __init s5p64x0_init_irq_eint(void) +{ + int ret = s5p64x0_alloc_gc(); + irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3); + irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11); + irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15); + + return ret; +} +arch_initcall(s5p64x0_init_irq_eint); diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 79bb3a0..69dd87c 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -90,6 +90,7 @@ config MACH_GONI select S3C_DEV_HSMMC2 select S3C_DEV_I2C1 select S3C_DEV_I2C2 + select S5P_DEV_MFC select S3C_DEV_USB_HSOTG select S5P_DEV_ONENAND select SAMSUNG_DEV_KEYPAD diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index ae72f87..52a8e60 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -324,6 +324,12 @@ static struct clk init_clocks_off[] = { .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1 << 26), }, { + .name = "mfc", + .devname = "s5p-mfc", + .parent = &clk_pclk_psys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 16), + }, { .name = "otg", .parent = &clk_hclk_psys.clk, .enable = s5pv210_clk_ip1_ctrl, @@ -879,6 +885,7 @@ static struct clksrc_clk clksrcs[] = { }, { .clk = { .name = "sclk_mfc", + .devname = "s5p-mfc", .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1 << 16), }, diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 61e6c24..79907ec 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -126,7 +126,7 @@ void __init s5pv210_map_io(void) s5pv210_default_sdhci2(); s5pv210_default_sdhci3(); - s3c_adc_setname("s3c64xx-adc"); + s3c_adc_setname("samsung-adc-v3"); s3c_cfcon_setname("s5pv210-pata"); diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index 8d58f19..63f5d82 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c @@ -18,6 +18,7 @@ #include <mach/map.h> #include <mach/dma.h> #include <mach/irqs.h> +#include <mach/regs-audss.h> static const char *rclksrc[] = { [0] = "busclk", @@ -52,6 +53,7 @@ static struct s3c_audio_pdata i2sv5_pdata = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, .src_clk = rclksrc, + .idma_addr = S5PV210_AUDSS_INT_MEM, }, }, }; diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index 1dd5883..aac343c 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -59,6 +59,8 @@ #define S5PV210_PA_CFCON 0xE8200000 +#define S5PV210_PA_MFC 0xF1700000 + #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) #define S5PV210_PA_HSOTG 0xEC000000 @@ -107,6 +109,7 @@ #define S5P_PA_FIMC1 S5PV210_PA_FIMC1 #define S5P_PA_FIMC2 S5PV210_PA_FIMC2 #define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS +#define S5P_PA_MFC S5PV210_PA_MFC #define S5P_PA_ONENAND S5PC110_PA_ONENAND #define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA #define S5P_PA_SDRAM S5PV210_PA_SDRAM diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h index e8d394f..3e22109 100644 --- a/arch/arm/mach-s5pv210/include/mach/pm-core.h +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h @@ -41,3 +41,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs, { /* nothing here yet */ } + +static inline void s3c_pm_restored_gpios(void) { } +static inline void s3c_pm_saved_gpios(void) { } diff --git a/arch/arm/mach-s5pv210/include/mach/regs-audss.h b/arch/arm/mach-s5pv210/include/mach/regs-audss.h new file mode 100644 index 0000000..eacc1f7 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/regs-audss.h @@ -0,0 +1,18 @@ +/* arch/arm/mach-s5pv210/include/mach/regs-audss.h + * + * Copyright (c) 2011 Samsung Electronics + * http://www.samsung.com + * + * S5PV210 Audio SubSystem clock register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __PLAT_REGS_AUDSS_H +#define __PLAT_REGS_AUDSS_H __FILE__ + +#define S5PV210_AUDSS_INT_MEM (0xC0000000) + +#endif /* _PLAT_REGS_AUDSS_H */ diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index e0c4d06..85c2d51 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -46,6 +46,7 @@ #include <plat/sdhci.h> #include <plat/clock.h> #include <plat/s5p-time.h> +#include <plat/mfc.h> #include <plat/regs-fb-v4.h> /* Following are default values for UCON, ULCON and UFCON UART registers */ @@ -808,6 +809,9 @@ static struct platform_device *goni_devices[] __initdata = { &goni_i2c_gpio5, &mmc2_fixed_voltage, &goni_device_gpiokeys, + &s5p_device_mfc, + &s5p_device_mfc_l, + &s5p_device_mfc_r, &s3c_device_i2c0, &s5p_device_fimc0, &s5p_device_fimc1, @@ -841,6 +845,11 @@ static void __init goni_map_io(void) s5p_set_timer_source(S5P_PWM3, S5P_PWM4); } +static void __init goni_reserve(void) +{ + s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); +} + static void __init goni_machine_init(void) { /* Radio: call before I2C 1 registeration */ @@ -893,4 +902,5 @@ MACHINE_START(GONI, "GONI") .map_io = goni_map_io, .init_machine = goni_machine_init, .timer = &s5p_timer, + .reserve = &goni_reserve, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index ef20f92..5e011fc 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -229,6 +229,7 @@ static struct platform_device *smdkv210_devices[] __initdata = { &s5pv210_device_iis0, &s5pv210_device_spdif, &samsung_asoc_dma, + &samsung_asoc_idma, &samsung_device_keypad, &smdkv210_dm9000, &smdkv210_lcd_lte480wv, diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 309e388..f149d27 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -88,7 +88,7 @@ static struct sleep_save s5pv210_core_save[] = { SAVE_ITEM(S3C2410_TCNTO(0)), }; -void s5pv210_cpu_suspend(unsigned long arg) +static int s5pv210_cpu_suspend(unsigned long arg) { unsigned long tmp; diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h index 967ae76..99f5856 100644 --- a/arch/arm/mach-sa1100/include/mach/hardware.h +++ b/arch/arm/mach-sa1100/include/mach/hardware.h @@ -76,12 +76,4 @@ static inline unsigned long get_clock_tick_rate(void) #include "SA-1101.h" #endif -#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI) -#define PCIBIOS_MIN_IO 0 -#define PCIBIOS_MIN_MEM 0 -#define pcibios_assign_all_busses() 1 -#define HAVE_ARCH_PCI_SET_DMA_MASK 1 -#endif - - #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index fba7a91..dd39fee 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c @@ -28,6 +28,7 @@ #include <asm/mach-types.h> #include <mach/nanoengine.h> +#include <mach/hardware.h> static DEFINE_SPINLOCK(nano_lock); @@ -122,7 +123,8 @@ static struct pci_ops pci_nano_ops = { .write = nanoengine_write_config, }; -static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, + u8 pin) { return NANOENGINE_IRQ_GPIO_PCI; } @@ -252,6 +254,9 @@ int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) { int ret = 0; + pcibios_min_io = 0; + pcibios_min_mem = 0; + if (nr == 0) { sys->mem_offset = NANO_PCI_MEM_RW_PHYS; sys->io_offset = 0x400; diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h index 94d84b2..663f952 100644 --- a/arch/arm/mach-shark/include/mach/hardware.h +++ b/arch/arm/mach-shark/include/mach/hardware.h @@ -12,11 +12,5 @@ #define UNCACHEABLE_ADDR 0xdf010000 -#define pcibios_assign_all_busses() 1 - -#define PCIBIOS_MIN_IO 0x6000 -#define PCIBIOS_MIN_MEM 0x50000000 -#define PCIMEM_BASE 0xe8000000 - #endif diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c index 89d175c..7cb79a0 100644 --- a/arch/arm/mach-shark/pci.c +++ b/arch/arm/mach-shark/pci.c @@ -8,12 +8,13 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/init.h> +#include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> -static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init shark_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->bus->number == 0) if (dev->devfn == 0) @@ -37,8 +38,15 @@ static struct hw_pci shark_pci __initdata = { static int __init shark_pci_init(void) { - if (machine_is_shark()) - pci_common_init(&shark_pci); + if (!machine_is_shark()) + return; + + pcibios_min_io = 0x6000; + pcibios_min_mem = 0x50000000; + vga_base = 0xe8000000; + + pci_common_init(&shark_pci); + return 0; } diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index ce5c251..cdfdd62 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -341,6 +341,7 @@ static struct platform_device mipidsi0_device = { static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, }; @@ -382,7 +383,7 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) } static struct sh_mobile_sdhi_info sh_sdhi1_info = { - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .set_pwr = ag5evm_sdhi1_set_pwr, diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 837138e..523f608 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -957,19 +957,16 @@ static struct resource csi2_resources[] = { }, }; -static struct platform_device csi2_device = { - .name = "sh-mobile-csi2", - .id = 0, +static struct sh_mobile_ceu_companion csi2 = { + .id = 0, .num_resources = ARRAY_SIZE(csi2_resources), .resource = csi2_resources, - .dev = { - .platform_data = &csi2_info, - }, + .platform_data = &csi2_info, }; static struct sh_mobile_ceu_info sh_mobile_ceu_info = { .flags = SH_CEU_FLAG_USE_8BIT_BUS, - .csi2_dev = &csi2_device.dev, + .csi2 = &csi2, }; static struct resource ceu_resources[] = { @@ -1013,7 +1010,6 @@ static struct platform_device *ap4evb_devices[] __initdata = { &lcdc1_device, &lcdc_device, &hdmi_device, - &csi2_device, &ceu_device, &ap4evb_camera, &meram_device, @@ -1416,6 +1412,7 @@ static void __init ap4evb_init(void) fsi_init_pm_clock(); sh7372_pm_init(); pm_clk_add(&fsi_device.dev, "spu2"); + pm_clk_add(&lcdc1_device.dev, "hdmi"); } static void __init ap4evb_timer_init(void) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 5b36b6c..17c19dc 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -641,6 +641,8 @@ static struct usbhs_private usbhs0_private = { }, .driver_param = { .buswait_bwait = 4, + .d0_tx_id = SHDMA_SLAVE_USB0_TX, + .d1_rx_id = SHDMA_SLAVE_USB0_RX, }, }, }; @@ -810,6 +812,8 @@ static struct usbhs_private usbhs1_private = { .buswait_bwait = 4, .pipe_type = usbhs1_pipe_cfg, .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg), + .d0_tx_id = SHDMA_SLAVE_USB1_TX, + .d1_rx_id = SHDMA_SLAVE_USB1_RX, }, }, }; @@ -1192,8 +1196,8 @@ static struct platform_device sh_mmcif_device = { }; -static int mackerel_camera_add(struct soc_camera_link *icl, struct device *dev); -static void mackerel_camera_del(struct soc_camera_link *icl); +static int mackerel_camera_add(struct soc_camera_device *icd); +static void mackerel_camera_del(struct soc_camera_device *icd); static int camera_set_capture(struct soc_camera_platform_info *info, int enable) @@ -1232,16 +1236,15 @@ static void mackerel_camera_release(struct device *dev) soc_camera_platform_release(&camera_device); } -static int mackerel_camera_add(struct soc_camera_link *icl, - struct device *dev) +static int mackerel_camera_add(struct soc_camera_device *icd) { - return soc_camera_platform_add(icl, dev, &camera_device, &camera_link, + return soc_camera_platform_add(icd, &camera_device, &camera_link, mackerel_camera_release, 0); } -static void mackerel_camera_del(struct soc_camera_link *icl) +static void mackerel_camera_del(struct soc_camera_device *icd) { - soc_camera_platform_del(icl, camera_device, &camera_link); + soc_camera_platform_del(icd, camera_device, &camera_link); } static struct sh_mobile_ceu_info sh_mobile_ceu_info = { @@ -1589,6 +1592,7 @@ static void __init mackerel_init(void) hdmi_init_pm_clock(); sh7372_pm_init(); pm_clk_add(&fsi_device.dev, "spu2"); + pm_clk_add(&hdmi_lcdc_device.dev, "hdmi"); } static void __init mackerel_timer_init(void) diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index 6b186ae..5218c34 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -259,9 +259,6 @@ static struct clk mstp_clks[MSTP_NR] = { [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */ }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("r_clk", &r_clk), diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 91f5779..6697592 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -503,16 +503,17 @@ static struct clk *late_main_clks[] = { &sh7372_fsidivb_clk, }; -enum { MSTP001, +enum { MSTP001, MSTP000, MSTP131, MSTP130, MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP117, MSTP116, MSTP113, MSTP106, MSTP101, MSTP100, MSTP223, - MSTP218, MSTP217, MSTP216, - MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, - MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, + MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207, + MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, + MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406, + MSTP405, MSTP404, MSTP403, MSTP400, MSTP_NR }; #define MSTP(_parent, _reg, _bit, _flags) \ @@ -520,6 +521,7 @@ enum { MSTP001, static struct clk mstp_clks[MSTP_NR] = { [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP000] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 0, 0), /* MSIOF0 */ [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ @@ -538,14 +540,16 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ + [MSTP214] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */ + [MSTP208] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 8, 0), /* MSIOF1 */ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP205] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 5, 0), /* MSIOF2 */ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ - [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ @@ -557,14 +561,14 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ + [MSTP407] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-DMAC1 */ [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ + [MSTP405] = MSTP(&r_clk, SMSTPCR4, 5, 0), /* CMT4 */ + [MSTP404] = MSTP(&r_clk, SMSTPCR4, 4, 0), /* CMT3 */ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ + [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */ }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } -#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk), @@ -613,6 +617,7 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ @@ -633,14 +638,16 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */ + CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), /* USB-DMAC0 */ + CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[MSTP208]), /* MSIOF1 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("spi_sh_msiof.2", &mstp_clks[MSTP205]), /* MSIOF2 */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ - CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ @@ -654,11 +661,17 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ + CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */ CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ + CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */ + CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ + CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */ + CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1", + &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c index 9594246..8cee7b1 100644 --- a/arch/arm/mach-shmobile/clock-sh7377.c +++ b/arch/arm/mach-shmobile/clock-sh7377.c @@ -267,9 +267,6 @@ static struct clk mstp_clks[] = { [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("r_clk", &r_clk), diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index bcacb1e..61a846b 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -306,10 +306,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } -#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("r_clk", &r_clk), @@ -369,7 +365,7 @@ void __init sh73a0_clock_init(void) __raw_writel(0x108, SD2CKCR); /* detect main clock parent */ - switch ((__raw_readl(CKSCR) >> 24) & 0x03) { + switch ((__raw_readl(CKSCR) >> 28) & 0x03) { case 0: main_clk.parent = &sh73a0_extal1_clk; break; diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index ce595ce..24e63a8 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -459,6 +459,10 @@ enum { SHDMA_SLAVE_SDHI2_TX, SHDMA_SLAVE_MMCIF_RX, SHDMA_SLAVE_MMCIF_TX, + SHDMA_SLAVE_USB0_TX, + SHDMA_SLAVE_USB0_RX, + SHDMA_SLAVE_USB1_TX, + SHDMA_SLAVE_USB1_RX, }; extern struct clk sh7372_extal1_clk; diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 3b28743..739315e3 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -379,7 +379,7 @@ enum { /* BBIF2 */ VPU, TSIF1, - _3DG_SGX530, + /* 3DG */ _2DDMAC, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, IPMMU_IPMMUR, IPMMU_IPMMUR2, @@ -436,7 +436,7 @@ static struct intc_vect intcs_vectors[] = { /* BBIF2 */ INTCS_VECT(VPU, 0x980), INTCS_VECT(TSIF1, 0x9a0), - INTCS_VECT(_3DG_SGX530, 0x9e0), + /* 3DG */ INTCS_VECT(_2DDMAC, 0xa00), INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), @@ -521,7 +521,7 @@ static struct intc_mask_reg intcs_mask_registers[] = { RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ { 0, 0, MSIOF, 0, - _3DG_SGX530, 0, 0, 0 } }, + 0, 0, 0, 0 } }, { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, 0, 0, 0, 0 } }, @@ -561,7 +561,6 @@ static struct intc_prio_reg intcs_prio_registers[] = { TMU_TUNI2, TSIF1 } }, { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, - { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } }, { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 79f0413..2d9b1b1 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -169,35 +169,35 @@ static struct platform_device scif6_device = { }; /* CMT */ -static struct sh_timer_config cmt10_platform_data = { - .name = "CMT10", - .channel_offset = 0x10, - .timer_bit = 0, +static struct sh_timer_config cmt2_platform_data = { + .name = "CMT2", + .channel_offset = 0x40, + .timer_bit = 5, .clockevent_rating = 125, .clocksource_rating = 125, }; -static struct resource cmt10_resources[] = { +static struct resource cmt2_resources[] = { [0] = { - .name = "CMT10", - .start = 0xe6138010, - .end = 0xe613801b, + .name = "CMT2", + .start = 0xe6130040, + .end = 0xe613004b, .flags = IORESOURCE_MEM, }, [1] = { - .start = evt2irq(0x0b00), /* CMT1_CMT10 */ + .start = evt2irq(0x0b80), /* CMT2 */ .flags = IORESOURCE_IRQ, }, }; -static struct platform_device cmt10_device = { +static struct platform_device cmt2_device = { .name = "sh_cmt", - .id = 10, + .id = 2, .dev = { - .platform_data = &cmt10_platform_data, + .platform_data = &cmt2_platform_data, }, - .resource = cmt10_resources, - .num_resources = ARRAY_SIZE(cmt10_resources), + .resource = cmt2_resources, + .num_resources = ARRAY_SIZE(cmt2_resources), }; /* TMU */ @@ -602,6 +602,150 @@ static struct platform_device dma2_device = { }, }; +/* + * USB-DMAC + */ + +unsigned int usbts_shift[] = {3, 4, 5}; + +enum { + XMIT_SZ_8BYTE = 0, + XMIT_SZ_16BYTE = 1, + XMIT_SZ_32BYTE = 2, +}; + +#define USBTS_INDEX2VAL(i) (((i) & 3) << 6) + +static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = { + { + .offset = 0, + }, { + .offset = 0x20, + }, +}; + +/* USB DMAC0 */ +static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = { + { + .slave_id = SHDMA_SLAVE_USB0_TX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, { + .slave_id = SHDMA_SLAVE_USB0_RX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, +}; + +static struct sh_dmae_pdata usb_dma0_platform_data = { + .slave = sh7372_usb_dmae0_slaves, + .slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves), + .channel = sh7372_usb_dmae_channels, + .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), + .ts_low_shift = 6, + .ts_low_mask = 0xc0, + .ts_high_shift = 0, + .ts_high_mask = 0, + .ts_shift = usbts_shift, + .ts_shift_num = ARRAY_SIZE(usbts_shift), + .dmaor_init = DMAOR_DME, + .chcr_offset = 0x14, + .chcr_ie_bit = 1 << 5, + .dmaor_is_32bit = 1, + .needs_tend_set = 1, + .no_dmars = 1, +}; + +static struct resource sh7372_usb_dmae0_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xe68a0020, + .end = 0xe68a0064 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* VCR/SWR/DMICR */ + .start = 0xe68a0000, + .end = 0xe68a0014 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* IRQ for channels */ + .start = evt2irq(0x0a00), + .end = evt2irq(0x0a00), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb_dma0_device = { + .name = "sh-dma-engine", + .id = 3, + .resource = sh7372_usb_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7372_usb_dmae0_resources), + .dev = { + .platform_data = &usb_dma0_platform_data, + }, +}; + +/* USB DMAC1 */ +static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = { + { + .slave_id = SHDMA_SLAVE_USB1_TX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, { + .slave_id = SHDMA_SLAVE_USB1_RX, + .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE), + }, +}; + +static struct sh_dmae_pdata usb_dma1_platform_data = { + .slave = sh7372_usb_dmae1_slaves, + .slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves), + .channel = sh7372_usb_dmae_channels, + .channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels), + .ts_low_shift = 6, + .ts_low_mask = 0xc0, + .ts_high_shift = 0, + .ts_high_mask = 0, + .ts_shift = usbts_shift, + .ts_shift_num = ARRAY_SIZE(usbts_shift), + .dmaor_init = DMAOR_DME, + .chcr_offset = 0x14, + .chcr_ie_bit = 1 << 5, + .dmaor_is_32bit = 1, + .needs_tend_set = 1, + .no_dmars = 1, +}; + +static struct resource sh7372_usb_dmae1_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xe68c0020, + .end = 0xe68c0064 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* VCR/SWR/DMICR */ + .start = 0xe68c0000, + .end = 0xe68c0014 - 1, + .flags = IORESOURCE_MEM, + }, + { + /* IRQ for channels */ + .start = evt2irq(0x1d00), + .end = evt2irq(0x1d00), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb_dma1_device = { + .name = "sh-dma-engine", + .id = 4, + .resource = sh7372_usb_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7372_usb_dmae1_resources), + .dev = { + .platform_data = &usb_dma1_platform_data, + }, +}; + /* VPU */ static struct uio_info vpu_platform_data = { .name = "VPU5HG", @@ -818,7 +962,7 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif4_device, &scif5_device, &scif6_device, - &cmt10_device, + &cmt2_device, &tmu00_device, &tmu01_device, }; @@ -829,6 +973,8 @@ static struct platform_device *sh7372_late_devices[] __initdata = { &dma0_device, &dma1_device, &dma2_device, + &usb_dma0_device, + &usb_dma1_device, &vpu_device, &veu0_device, &veu1_device, diff --git a/arch/arm/mach-spear3xx/include/mach/clkdev.h b/arch/arm/mach-spear3xx/include/mach/clkdev.h deleted file mode 100644 index a3d0733..0000000 --- a/arch/arm/mach-spear3xx/include/mach/clkdev.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/clkdev.h - * - * Clock Dev framework definitions for SPEAr3xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -#include <plat/clkdev.h> - -#endif /* __MACH_CLKDEV_H */ diff --git a/arch/arm/mach-spear6xx/include/mach/clkdev.h b/arch/arm/mach-spear6xx/include/mach/clkdev.h deleted file mode 100644 index 05676bf..0000000 --- a/arch/arm/mach-spear6xx/include/mach/clkdev.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/clkdev.h - * - * Clock Dev framework definitions for SPEAr6xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -#include <plat/clkdev.h> - -#endif /* __MACH_CLKDEV_H */ diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 5ec1846..d82ebab 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -27,14 +27,14 @@ comment "Tegra board type" config MACH_HARMONY bool "Harmony board" - select MACH_HAS_SND_SOC_TEGRA_WM8903 + select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for nVidia Harmony development platform config MACH_KAEN bool "Kaen board" select MACH_SEABOARD - select MACH_HAS_SND_SOC_TEGRA_WM8903 + select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for the Kaen version of Seaboard @@ -45,12 +45,18 @@ config MACH_PAZ00 config MACH_SEABOARD bool "Seaboard board" - select MACH_HAS_SND_SOC_TEGRA_WM8903 + select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC help Support for nVidia Seaboard development platform. It will also be included for some of the derivative boards that have large similarities with the seaboard design. +config MACH_TEGRA_DT + bool "Generic Tegra board (FDT support)" + select USE_OF + help + Support for generic nVidia Tegra boards using Flattened Device Tree + config MACH_TRIMSLICE bool "TrimSlice board" select TEGRA_PCI diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index ed58ef9..f11b910 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -29,5 +29,8 @@ obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o +obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o +obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o + obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot index db52d61..428ad12 100644 --- a/arch/arm/mach-tegra/Makefile.boot +++ b/arch/arm/mach-tegra/Makefile.boot @@ -1,3 +1,6 @@ zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000 params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 + +dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb +dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c new file mode 100644 index 0000000..9f47e04 --- /dev/null +++ b/arch/arm/mach-tegra/board-dt.c @@ -0,0 +1,119 @@ +/* + * nVidia Tegra device tree board support + * + * Copyright (C) 2010 Secret Lab Technologies, Ltd. + * Copyright (C) 2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/irqdomain.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/pda_power.h> +#include <linux/io.h> +#include <linux/i2c.h> +#include <linux/i2c-tegra.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/setup.h> + +#include <mach/iomap.h> +#include <mach/irqs.h> + +#include "board.h" +#include "board-harmony.h" +#include "clock.h" +#include "devices.h" + +void harmony_pinmux_init(void); +void seaboard_pinmux_init(void); + + +struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL), + {} +}; + +static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { + /* name parent rate enabled */ + { "uartd", "pll_p", 216000000, true }, + { NULL, NULL, 0, 0}, +}; + +static struct of_device_id tegra_dt_match_table[] __initdata = { + { .compatible = "simple-bus", }, + {} +}; + +static struct of_device_id tegra_dt_gic_match[] __initdata = { + { .compatible = "nvidia,tegra20-gic", }, + {} +}; + +static void __init tegra_dt_init(void) +{ + struct device_node *node; + + node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match, + TEGRA_ARM_INT_DIST_BASE); + if (node) + irq_domain_add_simple(node, INT_GIC_BASE); + + tegra_clk_init_from_table(tegra_dt_clk_init_table); + + if (of_machine_is_compatible("nvidia,harmony")) + harmony_pinmux_init(); + else if (of_machine_is_compatible("nvidia,seaboard")) + seaboard_pinmux_init(); + + /* + * Finished with the static registrations now; fill in the missing + * devices + */ + of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL); +} + +static const char * tegra_dt_board_compat[] = { + "nvidia,harmony", + "nvidia,seaboard", + NULL +}; + +DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)") + .map_io = tegra_map_common_io, + .init_early = tegra_init_early, + .init_irq = tegra_init_irq, + .timer = &tegra_timer, + .init_machine = tegra_dt_init, + .dt_compat = tegra_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 30e18bc..846cd7d 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -25,7 +25,6 @@ #include <linux/io.h> #include <linux/gpio.h> #include <linux/i2c.h> -#include <linux/i2c-tegra.h> #include <sound/wm8903.h> @@ -83,22 +82,6 @@ static struct platform_device harmony_audio_device = { }, }; -static struct tegra_i2c_platform_data harmony_i2c1_platform_data = { - .bus_clk_rate = 400000, -}; - -static struct tegra_i2c_platform_data harmony_i2c2_platform_data = { - .bus_clk_rate = 400000, -}; - -static struct tegra_i2c_platform_data harmony_i2c3_platform_data = { - .bus_clk_rate = 400000, -}; - -static struct tegra_i2c_platform_data harmony_dvc_platform_data = { - .bus_clk_rate = 400000, -}; - static struct wm8903_platform_data harmony_wm8903_pdata = { .irq_active_low = 0, .micdet_cfg = 0, @@ -121,11 +104,6 @@ static struct i2c_board_info __initdata wm8903_board_info = { static void __init harmony_i2c_init(void) { - tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data; - tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data; - tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data; - tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data; - platform_device_register(&tegra_i2c_device1); platform_device_register(&tegra_i2c_device2); platform_device_register(&tegra_i2c_device3); diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c index 2643d1b..bdd2627 100644 --- a/arch/arm/mach-tegra/board-paz00-pinmux.c +++ b/arch/arm/mach-tegra/board-paz00-pinmux.c @@ -141,12 +141,10 @@ static struct tegra_pingroup_config paz00_pinmux[] = { }; static struct tegra_gpio_table gpio_table[] = { - { .gpio = TEGRA_GPIO_SD1_CD, .enable = true }, - { .gpio = TEGRA_GPIO_SD1_WP, .enable = true }, - { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true }, - { .gpio = TEGRA_GPIO_SD4_CD, .enable = true }, - { .gpio = TEGRA_GPIO_SD4_WP, .enable = true }, - { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true }, + { .gpio = TEGRA_GPIO_SD1_CD, .enable = true }, + { .gpio = TEGRA_GPIO_SD1_WP, .enable = true }, + { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true }, + { .gpio = TEGRA_ULPI_RST, .enable = true }, }; void paz00_pinmux_init(void) diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 57e50a8..ea2f79c 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -25,6 +25,7 @@ #include <linux/dma-mapping.h> #include <linux/pda_power.h> #include <linux/io.h> +#include <linux/i2c.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -34,6 +35,7 @@ #include <mach/iomap.h> #include <mach/irqs.h> #include <mach/sdhci.h> +#include <mach/gpio.h> #include "board.h" #include "board-paz00.h" @@ -66,10 +68,22 @@ static struct platform_device debug_uart = { static struct platform_device *paz00_devices[] __initdata = { &debug_uart, &tegra_sdhci_device1, - &tegra_sdhci_device2, &tegra_sdhci_device4, }; +static void paz00_i2c_init(void) +{ + platform_device_register(&tegra_i2c_device1); + platform_device_register(&tegra_i2c_device2); + platform_device_register(&tegra_i2c_device4); +} + +static void paz00_usb_init(void) +{ + platform_device_register(&tegra_ehci2_device); + platform_device_register(&tegra_ehci3_device); +} + static void __init tegra_paz00_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { @@ -84,23 +98,16 @@ static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = { { NULL, NULL, 0, 0}, }; - static struct tegra_sdhci_platform_data sdhci_pdata1 = { .cd_gpio = TEGRA_GPIO_SD1_CD, .wp_gpio = TEGRA_GPIO_SD1_WP, .power_gpio = TEGRA_GPIO_SD1_POWER, }; -static struct tegra_sdhci_platform_data sdhci_pdata2 = { +static struct tegra_sdhci_platform_data sdhci_pdata4 = { .cd_gpio = -1, .wp_gpio = -1, .power_gpio = -1, -}; - -static struct tegra_sdhci_platform_data sdhci_pdata4 = { - .cd_gpio = TEGRA_GPIO_SD4_CD, - .wp_gpio = TEGRA_GPIO_SD4_WP, - .power_gpio = TEGRA_GPIO_SD4_POWER, .is_8bit = 1, }; @@ -111,13 +118,15 @@ static void __init tegra_paz00_init(void) paz00_pinmux_init(); tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; - tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2; tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices)); + + paz00_i2c_init(); + paz00_usb_init(); } -MACHINE_START(PAZ00, "paz00") +MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ") .boot_params = 0x00000100, .fixup = tegra_paz00_fixup, .map_io = tegra_map_common_io, diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h index da193ca7..d4ff39d 100644 --- a/arch/arm/mach-tegra/board-paz00.h +++ b/arch/arm/mach-tegra/board-paz00.h @@ -17,12 +17,10 @@ #ifndef _MACH_TEGRA_BOARD_PAZ00_H #define _MACH_TEGRA_BOARD_PAZ00_H -#define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5 -#define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1 -#define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PT3 -#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2 -#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3 -#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6 +#define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5 +#define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1 +#define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PT3 +#define TEGRA_ULPI_RST TEGRA_GPIO_PV0 void paz00_pinmux_init(void); diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c index 10fbbdc..56cbabf 100644 --- a/arch/arm/mach-tegra/board-seaboard.c +++ b/arch/arm/mach-tegra/board-seaboard.c @@ -19,7 +19,6 @@ #include <linux/platform_device.h> #include <linux/serial_8250.h> #include <linux/i2c.h> -#include <linux/i2c-tegra.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/io.h> @@ -66,22 +65,6 @@ static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = { { NULL, NULL, 0, 0}, }; -static struct tegra_i2c_platform_data seaboard_i2c1_platform_data = { - .bus_clk_rate = 400000. -}; - -static struct tegra_i2c_platform_data seaboard_i2c2_platform_data = { - .bus_clk_rate = 400000, -}; - -static struct tegra_i2c_platform_data seaboard_i2c3_platform_data = { - .bus_clk_rate = 400000, -}; - -static struct tegra_i2c_platform_data seaboard_dvc_platform_data = { - .bus_clk_rate = 400000, -}; - static struct gpio_keys_button seaboard_gpio_keys_buttons[] = { { .code = SW_LID, @@ -137,9 +120,9 @@ static struct tegra_sdhci_platform_data sdhci_pdata4 = { static struct platform_device *seaboard_devices[] __initdata = { &debug_uart, &tegra_pmu_device, - &tegra_sdhci_device1, - &tegra_sdhci_device3, &tegra_sdhci_device4, + &tegra_sdhci_device3, + &tegra_sdhci_device1, &seaboard_gpio_keys_device, }; @@ -161,11 +144,6 @@ static void __init seaboard_i2c_init(void) i2c_register_board_info(3, &adt7461_device, 1); - tegra_i2c_device1.dev.platform_data = &seaboard_i2c1_platform_data; - tegra_i2c_device2.dev.platform_data = &seaboard_i2c2_platform_data; - tegra_i2c_device3.dev.platform_data = &seaboard_i2c3_platform_data; - tegra_i2c_device4.dev.platform_data = &seaboard_dvc_platform_data; - platform_device_register(&tegra_i2c_device1); platform_device_register(&tegra_i2c_device2); platform_device_register(&tegra_i2c_device3); diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c index d9dc5d2..47c596c 100644 --- a/arch/arm/mach-tegra/board-trimslice-pinmux.c +++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c @@ -29,7 +29,7 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, + {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, @@ -126,7 +126,7 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, @@ -145,6 +145,9 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { static struct tegra_gpio_table gpio_table[] = { { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ + + { .gpio = TRIMSLICE_GPIO_USB1_MODE, .enable = true }, /* USB1 mode */ + { .gpio = TRIMSLICE_GPIO_USB2_RST, .enable = true }, /* USB2 PHY rst */ }; void __init trimslice_pinmux_init(void) diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c index cda4cfd..89a6d2a 100644 --- a/arch/arm/mach-tegra/board-trimslice.c +++ b/arch/arm/mach-tegra/board-trimslice.c @@ -23,6 +23,8 @@ #include <linux/platform_device.h> #include <linux/serial_8250.h> #include <linux/io.h> +#include <linux/i2c.h> +#include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -30,6 +32,7 @@ #include <mach/iomap.h> #include <mach/sdhci.h> +#include <mach/gpio.h> #include "board.h" #include "clock.h" @@ -71,12 +74,58 @@ static struct tegra_sdhci_platform_data sdhci_pdata4 = { .power_gpio = -1, }; +static struct platform_device trimslice_audio_device = { + .name = "tegra-snd-trimslice", + .id = 0, +}; + static struct platform_device *trimslice_devices[] __initdata = { &debug_uart, &tegra_sdhci_device1, &tegra_sdhci_device4, + &tegra_i2s_device1, + &tegra_das_device, + &tegra_pcm_device, + &trimslice_audio_device, }; +static struct i2c_board_info trimslice_i2c3_board_info[] = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, + { + I2C_BOARD_INFO("em3027", 0x56), + }, +}; + +static void trimslice_i2c_init(void) +{ + platform_device_register(&tegra_i2c_device1); + platform_device_register(&tegra_i2c_device2); + platform_device_register(&tegra_i2c_device3); + + i2c_register_board_info(2, trimslice_i2c3_board_info, + ARRAY_SIZE(trimslice_i2c3_board_info)); +} + +static void trimslice_usb_init(void) +{ + int err; + + platform_device_register(&tegra_ehci3_device); + + platform_device_register(&tegra_ehci2_device); + + err = gpio_request_one(TRIMSLICE_GPIO_USB1_MODE, GPIOF_OUT_INIT_HIGH, + "usb1mode"); + if (err) { + pr_err("TrimSlice: failed to obtain USB1 mode gpio: %d\n", err); + return; + } + + platform_device_register(&tegra_ehci1_device); +} + static void __init tegra_trimslice_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { @@ -90,6 +139,10 @@ static void __init tegra_trimslice_fixup(struct machine_desc *desc, static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = { /* name parent rate enabled */ { "uarta", "pll_p", 216000000, true }, + { "pll_a", "pll_p_out1", 56448000, true }, + { "pll_a_out0", "pll_a", 11289600, true }, + { "cdev1", NULL, 0, true }, + { "i2s1", "pll_a_out0", 11289600, false}, { NULL, NULL, 0, 0}, }; @@ -112,6 +165,9 @@ static void __init tegra_trimslice_init(void) tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices)); + + trimslice_i2c_init(); + trimslice_usb_init(); } MACHINE_START(TRIMSLICE, "trimslice") diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h index e8ef629..7a7dee8 100644 --- a/arch/arm/mach-tegra/board-trimslice.h +++ b/arch/arm/mach-tegra/board-trimslice.h @@ -20,6 +20,9 @@ #define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */ #define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */ +#define TRIMSLICE_GPIO_USB1_MODE TEGRA_GPIO_PV2 /* USB1 mode */ +#define TRIMSLICE_GPIO_USB2_RST TEGRA_GPIO_PV0 /* USB2 PHY reset */ + void trimslice_pinmux_init(void); #endif diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 1528f9d..57e35d2 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c @@ -22,10 +22,14 @@ #include <linux/dma-mapping.h> #include <linux/fsl_devices.h> #include <linux/serial_8250.h> +#include <linux/i2c-tegra.h> +#include <linux/platform_data/tegra_usb.h> #include <asm/pmu.h> #include <mach/irqs.h> #include <mach/iomap.h> #include <mach/dma.h> +#include <mach/usb_phy.h> +#include "gpio-names.h" static struct resource i2c_resource1[] = { [0] = { @@ -79,13 +83,29 @@ static struct resource i2c_resource4[] = { }, }; +static struct tegra_i2c_platform_data tegra_i2c1_platform_data = { + .bus_clk_rate = 400000, +}; + +static struct tegra_i2c_platform_data tegra_i2c2_platform_data = { + .bus_clk_rate = 400000, +}; + +static struct tegra_i2c_platform_data tegra_i2c3_platform_data = { + .bus_clk_rate = 400000, +}; + +static struct tegra_i2c_platform_data tegra_dvc_platform_data = { + .bus_clk_rate = 400000, +}; + struct platform_device tegra_i2c_device1 = { .name = "tegra-i2c", .id = 0, .resource = i2c_resource1, .num_resources = ARRAY_SIZE(i2c_resource1), .dev = { - .platform_data = 0, + .platform_data = &tegra_i2c1_platform_data, }, }; @@ -95,7 +115,7 @@ struct platform_device tegra_i2c_device2 = { .resource = i2c_resource2, .num_resources = ARRAY_SIZE(i2c_resource2), .dev = { - .platform_data = 0, + .platform_data = &tegra_i2c2_platform_data, }, }; @@ -105,7 +125,7 @@ struct platform_device tegra_i2c_device3 = { .resource = i2c_resource3, .num_resources = ARRAY_SIZE(i2c_resource3), .dev = { - .platform_data = 0, + .platform_data = &tegra_i2c3_platform_data, }, }; @@ -115,7 +135,7 @@ struct platform_device tegra_i2c_device4 = { .resource = i2c_resource4, .num_resources = ARRAY_SIZE(i2c_resource4), .dev = { - .platform_data = 0, + .platform_data = &tegra_dvc_platform_data, }, }; @@ -334,6 +354,28 @@ static struct resource tegra_usb3_resources[] = { }, }; +static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { + /* All existing boards use GPIO PV0 for phy reset */ + .reset_gpio = TEGRA_GPIO_PV0, + .clk = "cdev2", +}; + +static struct tegra_ehci_platform_data tegra_ehci1_pdata = { + .operating_mode = TEGRA_USB_OTG, + .power_down_on_bus_suspend = 1, +}; + +static struct tegra_ehci_platform_data tegra_ehci2_pdata = { + .phy_config = &tegra_ehci2_ulpi_phy_config, + .operating_mode = TEGRA_USB_HOST, + .power_down_on_bus_suspend = 1, +}; + +static struct tegra_ehci_platform_data tegra_ehci3_pdata = { + .operating_mode = TEGRA_USB_HOST, + .power_down_on_bus_suspend = 1, +}; + static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32); struct platform_device tegra_ehci1_device = { @@ -342,6 +384,7 @@ struct platform_device tegra_ehci1_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tegra_ehci1_pdata, }, .resource = tegra_usb1_resources, .num_resources = ARRAY_SIZE(tegra_usb1_resources), @@ -353,6 +396,7 @@ struct platform_device tegra_ehci2_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tegra_ehci2_pdata, }, .resource = tegra_usb2_resources, .num_resources = ARRAY_SIZE(tegra_usb2_resources), @@ -364,6 +408,7 @@ struct platform_device tegra_ehci3_device = { .dev = { .dma_mask = &tegra_ehci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tegra_ehci3_pdata, }, .resource = tegra_usb3_resources, .num_resources = ARRAY_SIZE(tegra_usb3_resources), diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h deleted file mode 100644 index 425b42e..0000000 --- a/arch/arm/mach-tegra/include/mach/barriers.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/barriers.h - * - * Copyright (C) 2010 ARM Ltd. - * Written by Catalin Marinas <catalin.marinas@arm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __MACH_BARRIERS_H -#define __MACH_BARRIERS_H - -#include <asm/outercache.h> - -#define rmb() dsb() -#define wmb() do { dsb(); outer_sync(); } while (0) -#define mb() wmb() - -#endif /* __MACH_BARRIERS_H */ diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h index d0183d8..027c421 100644 --- a/arch/arm/mach-tegra/include/mach/system.h +++ b/arch/arm/mach-tegra/include/mach/system.h @@ -21,7 +21,6 @@ #ifndef __MACH_TEGRA_SYSTEM_H #define __MACH_TEGRA_SYSTEM_H -#include <mach/hardware.h> #include <mach/iomap.h> extern void (*arch_reset)(char mode, const char *cmd); diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c index 31848a9..ea50fe2 100644 --- a/arch/arm/mach-tegra/io.c +++ b/arch/arm/mach-tegra/io.c @@ -24,7 +24,6 @@ #include <linux/mm.h> #include <linux/io.h> -#include <mach/hardware.h> #include <asm/page.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index 2941212..f1f699d 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -449,7 +449,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -static int tegra_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int tegra_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return INT_PCIE_INTR; } @@ -912,6 +912,8 @@ int __init tegra_pcie_init(bool init_port0, bool init_port1) if (!(init_port0 || init_port1)) return -ENODEV; + pcibios_min_mem = 0; + err = tegra_pcie_get_resources(); if (err) return err; diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 1a594dc..0886cbc 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -21,7 +21,6 @@ #include <asm/cacheflush.h> #include <asm/hardware/gic.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/smp_scu.h> @@ -122,7 +121,7 @@ void __init smp_init_cpus(void) } for (i = 0; i < ncores; i++) - cpu_set(i, cpu_possible_map); + set_cpu_possible(i, true); set_smp_cross_call(gic_raise_softirq); } diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index bb61807..0fe9b3e 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -2182,8 +2182,8 @@ struct clk tegra_list_clks[] = { PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ - PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ - PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */ + PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */ + PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */ PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index 5767208..7b597e2 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c @@ -40,8 +40,8 @@ struct pl022_config_chip dummy_chip_info = { .hierarchy = SSP_MASTER, /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ .slave_tx_disable = 0, - .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, - .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, + .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, .ctrl_len = SSP_BITS_12, .wait_state = SSP_MWIRE_WAIT_ZERO, .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index 18d7fa0..5f51bde 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -27,9 +27,6 @@ #include <asm/mach/time.h> #include <asm/mach/irq.h> -/* Be able to sleep for atleast 4 seconds (usually more) */ -#define APPTIMER_MIN_RANGE 4 - /* * APP side special timer registers * This timer contains four timers which can fire an interrupt each. @@ -309,11 +306,11 @@ static int u300_set_next_event(unsigned long cycles, /* Use general purpose timer 1 as clock event */ static struct clock_event_device clockevent_u300_1mhz = { - .name = "GPT1", - .rating = 300, /* Reasonably fast and accurate clock event */ - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = u300_set_next_event, - .set_mode = u300_set_mode, + .name = "GPT1", + .rating = 300, /* Reasonably fast and accurate clock event */ + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = u300_set_next_event, + .set_mode = u300_set_mode, }; /* Clock event timer interrupt handler */ @@ -328,9 +325,9 @@ static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) } static struct irqaction u300_timer_irq = { - .name = "U300 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = u300_timer_interrupt, + .name = "U300 Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = u300_timer_interrupt, }; /* @@ -413,16 +410,10 @@ static void __init u300_timer_init(void) "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) pr_err("timer: failed to initialize U300 clock source\n"); - clockevents_calc_mult_shift(&clockevent_u300_1mhz, - rate, APPTIMER_MIN_RANGE); - /* 32bit counter, so 32bits delta is max */ - clockevent_u300_1mhz.max_delta_ns = - clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz); - /* This timer is slow enough to set for 1 cycle == 1 MHz */ - clockevent_u300_1mhz.min_delta_ns = - clockevent_delta2ns(1, &clockevent_u300_1mhz); - clockevent_u300_1mhz.cpumask = cpumask_of(0); - clockevents_register_device(&clockevent_u300_1mhz); + /* Configure and register the clockevent */ + clockevents_config_and_register(&clockevent_u300_1mhz, rate, + 1, 0xffffffff); + /* * TODO: init and register the rest of the timers too, they can be * used by hrtimers! diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index f8b9392..4210cb4 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -20,7 +20,7 @@ config UX500_SOC_DB8500 endmenu -menu "Ux500 target platform" +menu "Ux500 target platform (boards)" config MACH_U8500 bool "U8500 Development platform" @@ -29,6 +29,19 @@ config MACH_U8500 help Include support for the mop500 development platform. +config MACH_HREFV60 + bool "U85000 Development platform, HREFv60 version" + depends on UX500_SOC_DB8500 + help + Include support for the HREFv60 new development platform. + +config MACH_SNOWBALL + bool "U8500 Snowball platform" + depends on UX500_SOC_DB8500 + select MACH_U8500 + help + Include support for the snowball development platform. + config MACH_U5500 bool "U5500 Development platform" depends on UX500_SOC_DB5500 diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 70cdbd6..f26fd76 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -236,6 +236,46 @@ static pin_cfg_t mop500_pins_hrefv60[] = { }; +static pin_cfg_t snowball_pins[] = { + /* SSP0, to AB8500 */ + GPIO143_SSP0_CLK, + GPIO144_SSP0_FRM, + GPIO145_SSP0_RXD | PIN_PULL_DOWN, + GPIO146_SSP0_TXD, + + /* MMC0: MicroSD card */ + GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH, + + /* MMC2: LAN */ + GPIO86_SM_ADQ0, + GPIO87_SM_ADQ1, + GPIO88_SM_ADQ2, + GPIO89_SM_ADQ3, + GPIO90_SM_ADQ4, + GPIO91_SM_ADQ5, + GPIO92_SM_ADQ6, + GPIO93_SM_ADQ7, + + GPIO94_SM_ADVn, + GPIO95_SM_CS0n, + GPIO96_SM_OEn, + GPIO97_SM_WEn, + + GPIO128_SM_CKO, + GPIO130_SM_FBCLK, + GPIO131_SM_ADQ8, + GPIO132_SM_ADQ9, + GPIO133_SM_ADQ10, + GPIO134_SM_ADQ11, + GPIO135_SM_ADQ12, + GPIO136_SM_ADQ13, + GPIO137_SM_ADQ14, + GPIO138_SM_ADQ15, + + /* RSTn_LAN */ + GPIO141_GPIO | PIN_OUTPUT_HIGH, +}; + void __init mop500_pins_init(void) { nmk_config_pins(mop500_pins_common, @@ -243,6 +283,9 @@ void __init mop500_pins_init(void) if (machine_is_hrefv60()) nmk_config_pins(mop500_pins_hrefv60, ARRAY_SIZE(mop500_pins_hrefv60)); + else if (machine_is_snowball()) + nmk_config_pins(snowball_pins, + ARRAY_SIZE(snowball_pins)); else nmk_config_pins(mop500_pins_default, ARRAY_SIZE(mop500_pins_default)); diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 0f2e522..2735d03 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -272,7 +272,14 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .max_uV = 2900000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, - .boot_on = 1, /* must be on for display */ + .boot_on = 1, /* display is on at boot */ + /* + * This voltage cannot be disabled right now because + * it is somehow affecting the external MMC + * functionality, though that typically will use + * AUX3. + */ + .always_on = 1, }, .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), .consumer_supplies = ab8500_vaux1_consumers, diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 7c6cb4fa..d0cb9e5 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -32,13 +32,32 @@ #define MCI_DATA31DIREN (1 << 5) #define MCI_FBCLKEN (1 << 7) +/* GPIO pins used by the sdi0 level shifter */ +static int sdi0_en = -1; +static int sdi0_vsel = -1; + static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, unsigned char power_mode) { - if (power_mode == MMC_POWER_UP) - gpio_set_value_cansleep(GPIO_SDMMC_EN, 1); - else if (power_mode == MMC_POWER_OFF) - gpio_set_value_cansleep(GPIO_SDMMC_EN, 0); + switch (power_mode) { + case MMC_POWER_UP: + case MMC_POWER_ON: + /* + * Level shifter voltage should depend on vdd to when deciding + * on either 1.8V or 2.9V. Once the decision has been made the + * level shifter must be disabled and re-enabled with a changed + * select signal in order to switch the voltage. Since there is + * no framework support yet for indicating 1.8V in vdd, use the + * default 2.9V. + */ + gpio_direction_output(sdi0_vsel, 0); + gpio_direction_output(sdi0_en, 1); + break; + case MMC_POWER_OFF: + gpio_direction_output(sdi0_vsel, 0); + gpio_direction_output(sdi0_en, 0); + break; + } return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | MCI_DATA2DIREN | MCI_DATA31DIREN; @@ -67,8 +86,10 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi0_data = { .vdd_handler = mop500_sdi0_vdd_handler, .ocr_mask = MMC_VDD_29_30, - .f_max = 100000000, - .capabilities = MMC_CAP_4_BIT_DATA, + .f_max = 50000000, + .capabilities = MMC_CAP_4_BIT_DATA | + MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED, .gpio_wp = -1, #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, @@ -77,10 +98,6 @@ static struct mmci_platform_data mop500_sdi0_data = { #endif }; -/* GPIO pins used by the sdi0 level shifter */ -static int sdi0_en = -1; -static int sdi0_vsel = -1; - static void sdi0_configure(void) { int ret; @@ -140,7 +157,7 @@ static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi2_data = { .ocr_mask = MMC_VDD_165_195, - .f_max = 100000000, + .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_cd = -1, .gpio_wp = -1, @@ -177,7 +194,7 @@ static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = { static struct mmci_platform_data mop500_sdi4_data = { .ocr_mask = MMC_VDD_29_30, - .f_max = 100000000, + .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_MMC_HIGHSPEED, .gpio_cd = -1, @@ -199,17 +216,27 @@ void __init mop500_sdi_init(void) /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ if (!cpu_is_u8500v10()) mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; - db8500_add_sdi2(&mop500_sdi2_data, periphid); + /* sdi2 on snowball is in ATL_B mode for FSMC (LAN) */ + if (!machine_is_snowball()) + db8500_add_sdi2(&mop500_sdi2_data, periphid); /* On-board eMMC */ db8500_add_sdi4(&mop500_sdi4_data, periphid); - if (machine_is_hrefv60()) { - mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; - sdi0_en = HREFV60_SDMMC_EN_GPIO; - sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; + if (machine_is_hrefv60() || machine_is_snowball()) { + if (machine_is_hrefv60()) { + mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; + sdi0_en = HREFV60_SDMMC_EN_GPIO; + sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; + } else if (machine_is_snowball()) { + mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; + mop500_sdi0_data.cd_invert = true; + sdi0_en = SNOWBALL_SDMMC_EN_GPIO; + sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO; + } sdi0_configure(); } + /* * On boards with the TC35892 GPIO expander, sdi0 will finally * be added when the TC35892 initializes and calls diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c index 69cce41..5af36aa 100644 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ b/arch/arm/mach-ux500/board-mop500-uib.c @@ -25,7 +25,7 @@ struct uib { void (*init)(void); }; -static struct __initdata uib mop500_uibs[] = { +static struct uib __initdata mop500_uibs[] = { [STUIB] = { .name = "ST-UIB", .option = "stuib", diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 2a08c07..cd54aba 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -26,9 +26,11 @@ #include <linux/mfd/ab8500/gpio.h> #include <linux/leds-lp5521.h> #include <linux/input.h> +#include <linux/smsc911x.h> #include <linux/gpio_keys.h> #include <linux/delay.h> +#include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -47,6 +49,26 @@ #include "board-mop500.h" #include "board-mop500-regulators.h" +static struct gpio_led snowball_led_array[] = { + { + .name = "user_led", + .default_trigger = "none", + .gpio = 142, + }, +}; + +static struct gpio_led_platform_data snowball_led_data = { + .leds = snowball_led_array, + .num_leds = ARRAY_SIZE(snowball_led_array), +}; + +static struct platform_device snowball_led_dev = { + .name = "leds-gpio", + .dev = { + .platform_data = &snowball_led_data, + }, +}; + static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { .gpio_base = MOP500_AB8500_GPIO(0), .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, @@ -69,6 +91,97 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { 0x7A, 0x00, 0x00}, }; +static struct gpio_keys_button snowball_key_array[] = { + { + .gpio = 32, + .type = EV_KEY, + .code = KEY_1, + .desc = "userpb", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 151, + .type = EV_KEY, + .code = KEY_2, + .desc = "extkb1", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 152, + .type = EV_KEY, + .code = KEY_3, + .desc = "extkb2", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 161, + .type = EV_KEY, + .code = KEY_4, + .desc = "extkb3", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, + { + .gpio = 162, + .type = EV_KEY, + .code = KEY_5, + .desc = "extkb4", + .active_low = 1, + .debounce_interval = 50, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data snowball_key_data = { + .buttons = snowball_key_array, + .nbuttons = ARRAY_SIZE(snowball_key_array), +}; + +static struct platform_device snowball_key_dev = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &snowball_key_data, + } +}; + +static struct smsc911x_platform_config snowball_sbnet_cfg = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, + .shift = 1, +}; + +static struct resource sbnet_res[] = { + { + .name = "smsc911x-memory", + .start = (0x5000 << 16), + .end = (0x5000 << 16) + 0xffff, + .flags = IORESOURCE_MEM, + }, + { + .start = NOMADIK_GPIO_TO_IRQ(140), + .end = NOMADIK_GPIO_TO_IRQ(140), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + }, +}; + +static struct platform_device snowball_sbnet_dev = { + .name = "smsc911x", + .num_resources = ARRAY_SIZE(sbnet_res), + .resource = sbnet_res, + .dev = { + .platform_data = &snowball_sbnet_cfg, + }, +}; + static struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, .regulator_reg_init = ab8500_regulator_reg_init, @@ -295,8 +408,9 @@ static void mop500_prox_deactivate(struct device *dev) } /* add any platform devices here - TODO */ -static struct platform_device *platform_devs[] __initdata = { +static struct platform_device *mop500_platform_devs[] __initdata = { &mop500_gpio_keys_device, + &ab8500_device, }; #ifdef CONFIG_STE_DMA40 @@ -478,6 +592,13 @@ static void __init mop500_uart_init(void) db8500_add_uart2(&uart2_plat); } +static struct platform_device *snowball_platform_devs[] __initdata = { + &snowball_led_dev, + &snowball_key_dev, + &snowball_sbnet_dev, + &ab8500_device, +}; + static void __init mop500_init_machine(void) { int i2c0_devs; @@ -487,24 +608,29 @@ static void __init mop500_init_machine(void) * all these GPIO pins to the internal GPIO controller * instead. */ - if (machine_is_hrefv60()) - mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - else - mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + if (!machine_is_snowball()) { + if (machine_is_hrefv60()) + mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; + else + mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + } u8500_init_devices(); mop500_pins_init(); - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); + if (machine_is_snowball()) + platform_add_devices(snowball_platform_devs, + ARRAY_SIZE(snowball_platform_devs)); + else + platform_add_devices(mop500_platform_devs, + ARRAY_SIZE(mop500_platform_devs)); mop500_i2c_init(); mop500_sdi_init(); mop500_spi_init(); mop500_uart_init(); - platform_device_register(&ab8500_device); - i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); if (machine_is_hrefv60()) i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; @@ -512,6 +638,9 @@ static void __init mop500_init_machine(void) i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); i2c_register_board_info(2, mop500_i2c2_devices, ARRAY_SIZE(mop500_i2c2_devices)); + + /* This board has full regulator constraints */ + regulator_has_full_constraints(); } MACHINE_START(U8500, "ST-Ericsson MOP500 platform") @@ -531,3 +660,12 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") .timer = &ux500_timer, .init_machine = mop500_init_machine, MACHINE_END + +MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") + .boot_params = 0x100, + .map_io = u8500_map_io, + .init_irq = ux500_init_irq, + /* we re-use nomadik timer here */ + .timer = &ux500_timer, + .init_machine = mop500_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 03a31cc..ee77a89 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -7,6 +7,11 @@ #ifndef __BOARD_MOP500_H #define __BOARD_MOP500_H +/* snowball GPIO for MMC card */ +#define SNOWBALL_SDMMC_EN_GPIO 217 +#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 +#define SNOWBALL_SDMMC_CD_GPIO 218 + /* HREFv60-specific GPIO assignments, this board has no GPIO expander */ #define HREFV60_TOUCH_RST_GPIO 143 #define HREFV60_PROX_SENSE_GPIO 217 diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 7d107be..e832664 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/clkdev.h> +#include <linux/cpufreq.h> #include <plat/mtu.h> #include <mach/hardware.h> @@ -742,6 +743,51 @@ err_out: late_initcall(clk_debugfs_init); #endif /* defined(CONFIG_DEBUG_FS) */ +unsigned long clk_smp_twd_rate = 400000000; + +unsigned long clk_smp_twd_get_rate(struct clk *clk) +{ + return clk_smp_twd_rate; +} + +static struct clk clk_smp_twd = { + .get_rate = clk_smp_twd_get_rate, + .name = "smp_twd", +}; + +static struct clk_lookup clk_smp_twd_lookup = { + .dev_id = "smp_twd", + .clk = &clk_smp_twd, +}; + +#ifdef CONFIG_CPU_FREQ + +static int clk_twd_cpufreq_transition(struct notifier_block *nb, + unsigned long state, void *data) +{ + struct cpufreq_freqs *f = data; + + if (state == CPUFREQ_PRECHANGE) { + /* Save frequency in simple Hz */ + clk_smp_twd_rate = f->new * 1000; + } + + return NOTIFY_OK; +} + +static struct notifier_block clk_twd_cpufreq_nb = { + .notifier_call = clk_twd_cpufreq_transition, +}; + +static int clk_init_smp_twd_cpufreq(void) +{ + return cpufreq_register_notifier(&clk_twd_cpufreq_nb, + CPUFREQ_TRANSITION_NOTIFIER); +} +late_initcall(clk_init_smp_twd_cpufreq); + +#endif + int __init clk_init(void) { if (cpu_is_u8500ed()) { @@ -762,6 +808,8 @@ int __init clk_init(void) else clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); + clkdev_add(&clk_smp_twd_lookup); + #ifdef CONFIG_DEBUG_FS clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); if (cpu_is_u8500ed()) diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c01bc19..22705d2 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -44,6 +44,7 @@ static struct map_desc u5500_io_desc[] __initdata = { __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K), __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K), __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), + __IO_DEV_DESC(U5500_PRCMU_TCDM_BASE, SZ_4K), }; static struct resource db5500_pmu_resources[] = { diff --git a/arch/arm/mach-ux500/include/mach/clkdev.h b/arch/arm/mach-ux500/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-ux500/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h index 088b550..7dd0807 100644 --- a/arch/arm/mach-ux500/include/mach/uncompress.h +++ b/arch/arm/mach-ux500/include/mach/uncompress.h @@ -54,7 +54,8 @@ static inline void arch_decomp_setup(void) if (machine_is_u8500() || machine_is_svp8500v1() || machine_is_svp8500v2() || - machine_is_hrefv60()) + machine_is_hrefv60() || + machine_is_snowball()) ux500_uart_base = U8500_UART2_BASE; else if (machine_is_u5500()) ux500_uart_base = U5500_UART0_BASE; diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 82e5359..0a01cbd 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -6,6 +6,7 @@ */ #include <linux/platform_device.h> #include <linux/usb/musb.h> +#include <linux/dma-mapping.h> #include <plat/ste_dma40.h> #include <mach/hardware.h> #include <mach/usb.h> diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig index 9cdec5a..c1f38f6 100644 --- a/arch/arm/mach-versatile/Kconfig +++ b/arch/arm/mach-versatile/Kconfig @@ -17,4 +17,12 @@ config MACH_VERSATILE_AB Include support for the ARM(R) Versatile Application Baseboard for the ARM926EJ-S. +config MACH_VERSATILE_DT + bool "Support Versatile platform from device tree" + select USE_OF + select CPU_ARM926T + help + Include support for the ARM(R) Versatile/PB platform, + using the device tree for discovery + endmenu diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile index 97cf4d8..81fa3fe 100644 --- a/arch/arm/mach-versatile/Makefile +++ b/arch/arm/mach-versatile/Makefile @@ -5,4 +5,5 @@ obj-y := core.o obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o +obj-$(CONFIG_MACH_VERSATILE_DT) += versatile_dt.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 0c99cf0..e340a54 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -24,6 +24,9 @@ #include <linux/platform_device.h> #include <linux/sysdev.h> #include <linux/interrupt.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> #include <linux/amba/bus.h> #include <linux/amba/clcd.h> #include <linux/amba/pl061.h> @@ -83,13 +86,26 @@ static struct fpga_irq_data sic_irq = { #define PIC_MASK 0 #endif +/* Lookup table for finding a DT node that represents the vic instance */ +static const struct of_device_id vic_of_match[] __initconst = { + { .compatible = "arm,versatile-vic", }, + {} +}; + +static const struct of_device_id sic_of_match[] __initconst = { + { .compatible = "arm,versatile-sic", }, + {} +}; + void __init versatile_init_irq(void) { vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); + irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START); writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq); + irq_domain_generate_simple(sic_of_match, VERSATILE_SIC_BASE, IRQ_SIC_START); /* * Interrupts on secondary controller from 0 to 8 are routed to @@ -646,6 +662,52 @@ static struct amba_device *amba_devs[] __initdata = { &kmi1_device, }; +#ifdef CONFIG_OF +/* + * Lookup table for attaching a specific name and platform_data pointer to + * devices as they get created by of_platform_populate(). Ideally this table + * would not exist, but the current clock implementation depends on some devices + * having a specific name. + */ +struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL), + + OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", NULL), + +#if 0 + /* + * These entries are unnecessary because no clocks referencing + * them. I've left them in for now as place holders in case + * any of them need to be added back, but they should be + * removed before actually committing this patch. --gcl + */ + OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL), + + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL), + OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL), +#endif + {} +}; +#endif + #ifdef CONFIG_LEDS #define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h index fd6404e..e014227 100644 --- a/arch/arm/mach-versatile/core.h +++ b/arch/arm/mach-versatile/core.h @@ -23,6 +23,7 @@ #define __ASM_ARCH_VERSATILE_H #include <linux/amba/bus.h> +#include <linux/of_platform.h> extern void __init versatile_init(void); extern void __init versatile_init_early(void); @@ -30,6 +31,9 @@ extern void __init versatile_init_irq(void); extern void __init versatile_map_io(void); extern struct sys_timer versatile_timer; extern unsigned int mmc_status(struct device *dev); +#ifdef CONFIG_OF +extern struct of_dev_auxdata versatile_auxdata_lookup[]; +#endif #define AMBA_DEVICE(name,busid,base,plat) \ static struct amba_device name##_device = { \ diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h index 6911e1f..4d4973d 100644 --- a/arch/arm/mach-versatile/include/mach/hardware.h +++ b/arch/arm/mach-versatile/include/mach/hardware.h @@ -30,12 +30,6 @@ #define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul #define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul -/* CIK guesswork */ -#define PCIBIOS_MIN_IO 0x44000000 -#define PCIBIOS_MIN_MEM 0x50000000 - -#define pcibios_assign_all_busses() 1 - /* macro to get at IO space when running virtually */ #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 13c7e5f..c898deb 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -311,6 +311,9 @@ struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys) void __init pci_versatile_preinit(void) { + pcibios_min_io = 0x44000000; + pcibios_min_mem = 0x50000000; + __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0); __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28, PCI_IMAP1); __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28, PCI_IMAP2); @@ -325,7 +328,7 @@ void __init pci_versatile_preinit(void) /* * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this. */ -static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; int devslot = PCI_SLOT(dev->devfn); diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c new file mode 100644 index 0000000..54e037c --- /dev/null +++ b/arch/arm/mach-versatile/versatile_dt.c @@ -0,0 +1,51 @@ +/* + * Versatile board support using the device tree + * + * Copyright (C) 2010 Secret Lab Technologies Ltd. + * Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com> + * Copyright (C) 2004 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include "core.h" + +static void __init versatile_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + versatile_auxdata_lookup, NULL); +} + +static const char *versatile_dt_match[] __initconst = { + "arm,versatile-ab", + "arm,versatile-pb", + NULL, +}; + +DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)") + .map_io = versatile_map_io, + .init_early = versatile_init_early, + .init_irq = versatile_init_irq, + .timer = &versatile_timer, + .init_machine = versatile_dt_init, + .dt_compat = versatile_dt_match, +MACHINE_END diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 9e6b93b..d0d267a 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -318,6 +318,10 @@ static struct clk v2m_sp804_clk = { .rate = 1000000, }; +static struct clk v2m_ref_clk = { + .rate = 32768, +}; + static struct clk dummy_apb_pclk; static struct clk_lookup v2m_lookups[] = { @@ -348,6 +352,9 @@ static struct clk_lookup v2m_lookups[] = { }, { /* CLCD */ .dev_id = "mb:clcd", .clk = &osc1_clk, + }, { /* SP805 WDT */ + .dev_id = "mb:wdt", + .clk = &v2m_ref_clk, }, { /* SP804 timers */ .dev_id = "sp804", .con_id = "v2m-timer0", diff --git a/arch/arm/mach-w90x900/include/mach/clkdev.h b/arch/arm/mach-w90x900/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/mach-w90x900/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile new file mode 100644 index 0000000..397268c --- /dev/null +++ b/arch/arm/mach-zynq/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := common.o timer.o diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot new file mode 100644 index 0000000..67039c3 --- /dev/null +++ b/arch/arm/mach-zynq/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c new file mode 100644 index 0000000..73e9368 --- /dev/null +++ b/arch/arm/mach-zynq/common.c @@ -0,0 +1,118 @@ +/* + * This file contains common code that is intended to be used across + * boards so that it's not replicated. + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/cpumask.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/of.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/hardware/gic.h> +#include <asm/hardware/cache-l2x0.h> + +#include <mach/zynq_soc.h> +#include <mach/clkdev.h> +#include "common.h" + +static struct of_device_id zynq_of_bus_ids[] __initdata = { + { .compatible = "simple-bus", }, + {} +}; + +/** + * xilinx_init_machine() - System specific initialization, intended to be + * called from board specific initialization. + */ +static void __init xilinx_init_machine(void) +{ +#ifdef CONFIG_CACHE_L2X0 + /* + * 64KB way size, 8-way associativity, parity disabled + */ + l2x0_init(PL310_L2CC_BASE, 0x02060000, 0xF0F0FFFF); +#endif + + of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL); +} + +/** + * xilinx_irq_init() - Interrupt controller initialization for the GIC. + */ +static void __init xilinx_irq_init(void) +{ + gic_init(0, 29, SCU_GIC_DIST_BASE, SCU_GIC_CPU_BASE); +} + +/* The minimum devices needed to be mapped before the VM system is up and + * running include the GIC, UART and Timer Counter. + */ + +static struct map_desc io_desc[] __initdata = { + { + .virtual = TTC0_VIRT, + .pfn = __phys_to_pfn(TTC0_PHYS), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = SCU_PERIPH_VIRT, + .pfn = __phys_to_pfn(SCU_PERIPH_PHYS), + .length = SZ_8K, + .type = MT_DEVICE, + }, { + .virtual = PL310_L2CC_VIRT, + .pfn = __phys_to_pfn(PL310_L2CC_PHYS), + .length = SZ_4K, + .type = MT_DEVICE, + }, + +#ifdef CONFIG_DEBUG_LL + { + .virtual = UART0_VIRT, + .pfn = __phys_to_pfn(UART0_PHYS), + .length = SZ_4K, + .type = MT_DEVICE, + }, +#endif + +}; + +/** + * xilinx_map_io() - Create memory mappings needed for early I/O. + */ +static void __init xilinx_map_io(void) +{ + iotable_init(io_desc, ARRAY_SIZE(io_desc)); +} + +static const char *xilinx_dt_match[] = { + "xlnx,zynq-ep107", + NULL +}; + +MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") + .map_io = xilinx_map_io, + .init_irq = xilinx_irq_init, + .init_machine = xilinx_init_machine, + .timer = &xttcpss_sys_timer, + .dt_compat = xilinx_dt_match, +MACHINE_END diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-zynq/common.h index 56e43b3..a009644 100644 --- a/arch/arm/mach-tegra/include/mach/hardware.h +++ b/arch/arm/mach-zynq/common.h @@ -1,11 +1,8 @@ /* - * arch/arm/mach-tegra/include/mach/hardware.h + * This file contains common function prototypes to avoid externs + * in the c files. * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross <ccross@google.com> - * Erik Gilling <konkers@google.com> + * Copyright (C) 2011 Xilinx * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -15,14 +12,13 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ -#ifndef __MACH_TEGRA_HARDWARE_H -#define __MACH_TEGRA_HARDWARE_H +#ifndef __MACH_ZYNQ_COMMON_H__ +#define __MACH_ZYNQ_COMMON_H__ + +#include <asm/mach/time.h> -#define PCIBIOS_MIN_IO 0x1000 -#define PCIBIOS_MIN_MEM 0 -#define pcibios_assign_all_busses() 1 +extern struct sys_timer xttcpss_sys_timer; #endif diff --git a/arch/arm/mach-zynq/include/mach/clkdev.h b/arch/arm/mach-zynq/include/mach/clkdev.h new file mode 100644 index 0000000..c6e73d8 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/clkdev.h @@ -0,0 +1,32 @@ +/* + * arch/arm/mach-zynq/include/mach/clkdev.h + * + * Copyright (C) 2011 Xilinx, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MACH_CLKDEV_H__ +#define __MACH_CLKDEV_H__ + +#include <plat/clock.h> + +struct clk { + unsigned long rate; + const struct clk_ops *ops; + const struct icst_params *params; + void __iomem *vcoreg; +}; + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-zynq/include/mach/debug-macro.S b/arch/arm/mach-zynq/include/mach/debug-macro.S new file mode 100644 index 0000000..9f664d5 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/debug-macro.S @@ -0,0 +1,36 @@ +/* arch/arm/mach-zynq/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <mach/zynq_soc.h> +#include <mach/uart.h> + + .macro addruart, rp, rv + ldr \rp, =LL_UART_PADDR @ physical + ldr \rv, =LL_UART_VADDR @ virtual + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA + .endm + + .macro waituart,rd,rx + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #UART_SR_OFFSET] @ get status register + tst \rd, #UART_SR_TXFULL @ + bne 1002b @ wait if FIFO is full + .endm diff --git a/arch/arm/mach-zynq/include/mach/entry-macro.S b/arch/arm/mach-zynq/include/mach/entry-macro.S new file mode 100644 index 0000000..3cfc01b --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/entry-macro.S @@ -0,0 +1,30 @@ +/* + * arch/arm/mach-zynq/include/mach/entry-macro.S + * + * Low-level IRQ helper macros + * + * Copyright (C) 2011 Xilinx + * + * based on arch/plat-mxc/include/mach/entry-macro.S + * + * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <mach/hardware.h> +#include <asm/hardware/entry-macro-gic.S> + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h new file mode 100644 index 0000000..d558d8a --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/hardware.h @@ -0,0 +1,18 @@ +/* arch/arm/mach-zynq/include/mach/hardware.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_HARDWARE_H__ +#define __MACH_HARDWARE_H__ + +#endif diff --git a/arch/arm/mach-zynq/include/mach/io.h b/arch/arm/mach-zynq/include/mach/io.h new file mode 100644 index 0000000..39d9885 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/io.h @@ -0,0 +1,33 @@ +/* arch/arm/mach-zynq/include/mach/io.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_IO_H__ +#define __MACH_IO_H__ + +/* Allow IO space to be anywhere in the memory */ + +#define IO_SPACE_LIMIT 0xffff + +/* IO address mapping macros, nothing special at this time but required */ + +#ifdef __ASSEMBLER__ +#define IOMEM(x) (x) +#else +#define IOMEM(x) ((void __force __iomem *)(x)) +#endif + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-zynq/include/mach/irqs.h b/arch/arm/mach-zynq/include/mach/irqs.h new file mode 100644 index 0000000..5fb04fd --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/irqs.h @@ -0,0 +1,21 @@ +/* arch/arm/mach-zynq/include/mach/irqs.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +#define ARCH_NR_GPIOS 118 +#define NR_IRQS (128 + ARCH_NR_GPIOS) + +#endif diff --git a/arch/arm/mach-zynq/include/mach/memory.h b/arch/arm/mach-zynq/include/mach/memory.h new file mode 100644 index 0000000..35a9263 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/memory.h @@ -0,0 +1,22 @@ +/* arch/arm/mach-zynq/include/mach/memory.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_MEMORY_H__ +#define __MACH_MEMORY_H__ + +#include <asm/sizes.h> + +#define PLAT_PHYS_OFFSET UL(0x0) + +#endif diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-zynq/include/mach/system.h index 66cd3f4..1b84d70 100644 --- a/arch/arm/mach-tegra/include/mach/clkdev.h +++ b/arch/arm/mach-zynq/include/mach/system.h @@ -1,10 +1,6 @@ -/* - * arch/arm/mach-tegra/include/mach/clkdev.h +/* arch/arm/mach-zynq/include/mach/system.h * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross <ccross@google.com> + * Copyright (C) 2011 Xilinx * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,21 +10,19 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -struct clk; +#ifndef __MACH_SYSTEM_H__ +#define __MACH_SYSTEM_H__ -static inline int __clk_get(struct clk *clk) +static inline void arch_idle(void) { - return 1; + cpu_do_idle(); } -static inline void __clk_put(struct clk *clk) +static inline void arch_reset(char mode, const char *cmd) { + /* Add architecture specific reset processing here */ } #endif diff --git a/arch/arm/mach-zynq/include/mach/timex.h b/arch/arm/mach-zynq/include/mach/timex.h new file mode 100644 index 0000000..6c0245e --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/timex.h @@ -0,0 +1,23 @@ +/* arch/arm/mach-zynq/include/mach/timex.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_TIMEX_H__ +#define __MACH_TIMEX_H__ + +/* the following is needed for the system to build but will be removed + in the future, the value is not important but won't hurt +*/ +#define CLOCK_TICK_RATE (100 * HZ) + +#endif diff --git a/arch/arm/mach-zynq/include/mach/uart.h b/arch/arm/mach-zynq/include/mach/uart.h new file mode 100644 index 0000000..5c47c97 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/uart.h @@ -0,0 +1,25 @@ +/* arch/arm/mach-zynq/include/mach/uart.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_UART_H__ +#define __MACH_UART_H__ + +#define UART_CR_OFFSET 0x00 /* Control Register [8:0] */ +#define UART_SR_OFFSET 0x2C /* Channel Status [11:0] */ +#define UART_FIFO_OFFSET 0x30 /* FIFO [15:0] or [7:0] */ + +#define UART_SR_TXFULL 0x00000010 /* TX FIFO full */ +#define UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */ + +#endif diff --git a/arch/arm/mach-zynq/include/mach/uncompress.h b/arch/arm/mach-zynq/include/mach/uncompress.h new file mode 100644 index 0000000..af4e844 --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/uncompress.h @@ -0,0 +1,51 @@ +/* arch/arm/mach-zynq/include/mach/uncompress.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_UNCOMPRESS_H__ +#define __MACH_UNCOMPRESS_H__ + +#include <linux/io.h> +#include <asm/processor.h> +#include <mach/zynq_soc.h> +#include <mach/uart.h> + +void arch_decomp_setup(void) +{ +} + +static inline void flush(void) +{ + /* + * Wait while the FIFO is not empty + */ + while (!(__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) & + UART_SR_TXEMPTY)) + cpu_relax(); +} + +#define arch_decomp_wdog() + +static void putc(char ch) +{ + /* + * Wait for room in the FIFO, then write the char into the FIFO + */ + while (__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) & + UART_SR_TXFULL) + cpu_relax(); + + __raw_writel(ch, IOMEM(LL_UART_PADDR + UART_FIFO_OFFSET)); +} + +#endif diff --git a/arch/arm/mach-zynq/include/mach/vmalloc.h b/arch/arm/mach-zynq/include/mach/vmalloc.h new file mode 100644 index 0000000..2398eff --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/vmalloc.h @@ -0,0 +1,20 @@ +/* arch/arm/mach-zynq/include/mach/vmalloc.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_VMALLOC_H__ +#define __MACH_VMALLOC_H__ + +#define VMALLOC_END 0xE0000000UL + +#endif diff --git a/arch/arm/mach-zynq/include/mach/zynq_soc.h b/arch/arm/mach-zynq/include/mach/zynq_soc.h new file mode 100644 index 0000000..d0d3f8f --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/zynq_soc.h @@ -0,0 +1,48 @@ +/* arch/arm/mach-zynq/include/mach/zynq_soc.h + * + * Copyright (C) 2011 Xilinx + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_XILINX_SOC_H__ +#define __MACH_XILINX_SOC_H__ + +#define PERIPHERAL_CLOCK_RATE 2500000 + +/* For now, all mappings are flat (physical = virtual) + */ +#define UART0_PHYS 0xE0000000 +#define UART0_VIRT UART0_PHYS + +#define TTC0_PHYS 0xF8001000 +#define TTC0_VIRT TTC0_PHYS + +#define PL310_L2CC_PHYS 0xF8F02000 +#define PL310_L2CC_VIRT PL310_L2CC_PHYS + +#define SCU_PERIPH_PHYS 0xF8F00000 +#define SCU_PERIPH_VIRT SCU_PERIPH_PHYS + +/* The following are intended for the devices that are mapped early */ + +#define TTC0_BASE IOMEM(TTC0_VIRT) +#define SCU_PERIPH_BASE IOMEM(SCU_PERIPH_VIRT) +#define SCU_GIC_CPU_BASE (SCU_PERIPH_BASE + 0x100) +#define SCU_GIC_DIST_BASE (SCU_PERIPH_BASE + 0x1000) +#define PL310_L2CC_BASE IOMEM(PL310_L2CC_VIRT) + +/* + * Mandatory for CONFIG_LL_DEBUG, UART is mapped virtual = physical + */ +#define LL_UART_PADDR UART0_PHYS +#define LL_UART_VADDR UART0_VIRT + +#endif diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c new file mode 100644 index 0000000..c2c96cc --- /dev/null +++ b/arch/arm/mach-zynq/timer.c @@ -0,0 +1,298 @@ +/* + * This file contains driver for the Xilinx PS Timer Counter IP. + * + * Copyright (C) 2011 Xilinx + * + * based on arch/mips/kernel/time.c timer driver + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/types.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/io.h> + +#include <asm/mach/time.h> +#include <mach/zynq_soc.h> +#include "common.h" + +#define IRQ_TIMERCOUNTER0 42 + +/* + * This driver configures the 2 16-bit count-up timers as follows: + * + * T1: Timer 1, clocksource for generic timekeeping + * T2: Timer 2, clockevent source for hrtimers + * T3: Timer 3, <unused> + * + * The input frequency to the timer module for emulation is 2.5MHz which is + * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32, + * the timers are clocked at 78.125KHz (12.8 us resolution). + * + * The input frequency to the timer module in silicon will be 200MHz. With the + * pre-scaler of 32, the timers are clocked at 6.25MHz (160ns resolution). + */ +#define XTTCPSS_CLOCKSOURCE 0 /* Timer 1 as a generic timekeeping */ +#define XTTCPSS_CLOCKEVENT 1 /* Timer 2 as a clock event */ + +#define XTTCPSS_TIMER_BASE TTC0_BASE +#define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER0 + 1) +/* + * Timer Register Offset Definitions of Timer 1, Increment base address by 4 + * and use same offsets for Timer 2 + */ +#define XTTCPSS_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */ +#define XTTCPSS_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */ +#define XTTCPSS_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */ +#define XTTCPSS_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */ +#define XTTCPSS_MATCH_1_OFFSET 0x30 /* Match 1 Value Reg, RW */ +#define XTTCPSS_MATCH_2_OFFSET 0x3C /* Match 2 Value Reg, RW */ +#define XTTCPSS_MATCH_3_OFFSET 0x48 /* Match 3 Value Reg, RW */ +#define XTTCPSS_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */ +#define XTTCPSS_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */ + +#define XTTCPSS_CNT_CNTRL_DISABLE_MASK 0x1 + +/* Setup the timers to use pre-scaling */ + +#define TIMER_RATE (PERIPHERAL_CLOCK_RATE / 32) + +/** + * struct xttcpss_timer - This definition defines local timer structure + * + * @base_addr: Base address of timer + **/ +struct xttcpss_timer { + void __iomem *base_addr; +}; + +static struct xttcpss_timer timers[2]; +static struct clock_event_device xttcpss_clockevent; + +/** + * xttcpss_set_interval - Set the timer interval value + * + * @timer: Pointer to the timer instance + * @cycles: Timer interval ticks + **/ +static void xttcpss_set_interval(struct xttcpss_timer *timer, + unsigned long cycles) +{ + u32 ctrl_reg; + + /* Disable the counter, set the counter value and re-enable counter */ + ctrl_reg = __raw_readl(timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); + ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK; + __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); + + __raw_writel(cycles, timer->base_addr + XTTCPSS_INTR_VAL_OFFSET); + + /* Reset the counter (0x10) so that it starts from 0, one-shot + mode makes this needed for timing to be right. */ + ctrl_reg |= 0x10; + ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK; + __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); +} + +/** + * xttcpss_clock_event_interrupt - Clock event timer interrupt handler + * + * @irq: IRQ number of the Timer + * @dev_id: void pointer to the xttcpss_timer instance + * + * returns: Always IRQ_HANDLED - success + **/ +static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &xttcpss_clockevent; + struct xttcpss_timer *timer = dev_id; + + /* Acknowledge the interrupt and call event handler */ + __raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET), + timer->base_addr + XTTCPSS_ISR_OFFSET); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction event_timer_irq = { + .name = "xttcpss clockevent", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = xttcpss_clock_event_interrupt, +}; + +/** + * xttcpss_timer_hardware_init - Initialize the timer hardware + * + * Initialize the hardware to start the clock source, get the clock + * event timer ready to use, and hook up the interrupt. + **/ +static void __init xttcpss_timer_hardware_init(void) +{ + /* Setup the clock source counter to be an incrementing counter + * with no interrupt and it rolls over at 0xFFFF. Pre-scale + it by 32 also. Let it start running now. + */ + timers[XTTCPSS_CLOCKSOURCE].base_addr = XTTCPSS_TIMER_BASE; + + __raw_writel(0x0, timers[XTTCPSS_CLOCKSOURCE].base_addr + + XTTCPSS_IER_OFFSET); + __raw_writel(0x9, timers[XTTCPSS_CLOCKSOURCE].base_addr + + XTTCPSS_CLK_CNTRL_OFFSET); + __raw_writel(0x10, timers[XTTCPSS_CLOCKSOURCE].base_addr + + XTTCPSS_CNT_CNTRL_OFFSET); + + /* Setup the clock event timer to be an interval timer which + * is prescaled by 32 using the interval interrupt. Leave it + * disabled for now. + */ + + timers[XTTCPSS_CLOCKEVENT].base_addr = XTTCPSS_TIMER_BASE + 4; + + __raw_writel(0x23, timers[XTTCPSS_CLOCKEVENT].base_addr + + XTTCPSS_CNT_CNTRL_OFFSET); + __raw_writel(0x9, timers[XTTCPSS_CLOCKEVENT].base_addr + + XTTCPSS_CLK_CNTRL_OFFSET); + __raw_writel(0x1, timers[XTTCPSS_CLOCKEVENT].base_addr + + XTTCPSS_IER_OFFSET); + + /* Setup IRQ the clock event timer */ + event_timer_irq.dev_id = &timers[XTTCPSS_CLOCKEVENT]; + setup_irq(XTTCPCC_EVENT_TIMER_IRQ, &event_timer_irq); +} + +/** + * __raw_readl_cycles - Reads the timer counter register + * + * returns: Current timer counter register value + **/ +static cycle_t __raw_readl_cycles(struct clocksource *cs) +{ + struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKSOURCE]; + + return (cycle_t)__raw_readl(timer->base_addr + + XTTCPSS_COUNT_VAL_OFFSET); +} + + +/* + * Instantiate and initialize the clock source structure + */ +static struct clocksource clocksource_xttcpss = { + .name = "xttcpss_timer1", + .rating = 200, /* Reasonable clock source */ + .read = __raw_readl_cycles, + .mask = CLOCKSOURCE_MASK(16), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + + +/** + * xttcpss_set_next_event - Sets the time interval for next event + * + * @cycles: Timer interval ticks + * @evt: Address of clock event instance + * + * returns: Always 0 - success + **/ +static int xttcpss_set_next_event(unsigned long cycles, + struct clock_event_device *evt) +{ + struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT]; + + xttcpss_set_interval(timer, cycles); + return 0; +} + +/** + * xttcpss_set_mode - Sets the mode of timer + * + * @mode: Mode to be set + * @evt: Address of clock event instance + **/ +static void xttcpss_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT]; + u32 ctrl_reg; + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + xttcpss_set_interval(timer, TIMER_RATE / HZ); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + ctrl_reg = __raw_readl(timer->base_addr + + XTTCPSS_CNT_CNTRL_OFFSET); + ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK; + __raw_writel(ctrl_reg, + timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); + break; + case CLOCK_EVT_MODE_RESUME: + ctrl_reg = __raw_readl(timer->base_addr + + XTTCPSS_CNT_CNTRL_OFFSET); + ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK; + __raw_writel(ctrl_reg, + timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET); + break; + } +} + +/* + * Instantiate and initialize the clock event structure + */ +static struct clock_event_device xttcpss_clockevent = { + .name = "xttcpss_timer2", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = xttcpss_set_next_event, + .set_mode = xttcpss_set_mode, + .rating = 200, +}; + +/** + * xttcpss_timer_init - Initialize the timer + * + * Initializes the timer hardware and register the clock source and clock event + * timers with Linux kernal timer framework + **/ +static void __init xttcpss_timer_init(void) +{ + xttcpss_timer_hardware_init(); + clocksource_register_hz(&clocksource_xttcpss, TIMER_RATE); + + /* Calculate the parameters to allow the clockevent to operate using + integer math + */ + clockevents_calc_mult_shift(&xttcpss_clockevent, TIMER_RATE, 4); + + xttcpss_clockevent.max_delta_ns = + clockevent_delta2ns(0xfffe, &xttcpss_clockevent); + xttcpss_clockevent.min_delta_ns = + clockevent_delta2ns(1, &xttcpss_clockevent); + + /* Indicate that clock event is on 1st CPU as SMP boot needs it */ + + xttcpss_clockevent.cpumask = cpumask_of(0); + clockevents_register_device(&xttcpss_clockevent); +} + +/* + * Instantiate and initialize the system timer structure + */ +struct sys_timer xttcpss_sys_timer = { + .init = xttcpss_timer_init, +}; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 0074b8d..88633fe 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -821,7 +821,8 @@ config CACHE_L2X0 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ - ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE + ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ + ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX default y select OUTER_CACHE select OUTER_CACHE_SYNC diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index 52162d5..2cbf68e 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S @@ -17,7 +17,7 @@ cmp \tmp, # 0x5600 @ Is it ldrsb? orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes tst \tmp, #1 << 11 @ L = 0 -> write - orreq \psr, \psr, #1 << 11 @ yes. + orreq \fsr, \fsr, #1 << 11 @ yes. b do_DataAbort not_thumb: .endm diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index be7c638..cfbcf8b 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -22,6 +22,7 @@ #include <linux/sched.h> #include <linux/uaccess.h> +#include <asm/system.h> #include <asm/unaligned.h> #include "fault.h" @@ -95,6 +96,33 @@ static const char *usermode_action[] = { "signal+warn" }; +/* Return true if and only if the ARMv6 unaligned access model is in use. */ +static bool cpu_is_v6_unaligned(void) +{ + return cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U); +} + +static int safe_usermode(int new_usermode, bool warn) +{ + /* + * ARMv6 and later CPUs can perform unaligned accesses for + * most single load and store instructions up to word size. + * LDM, STM, LDRD and STRD still need to be handled. + * + * Ignoring the alignment fault is not an option on these + * CPUs since we spin re-faulting the instruction without + * making any progress. + */ + if (cpu_is_v6_unaligned() && !(new_usermode & (UM_FIXUP | UM_SIGNAL))) { + new_usermode |= UM_FIXUP; + + if (warn) + printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); + } + + return new_usermode; +} + static int alignment_proc_show(struct seq_file *m, void *v) { seq_printf(m, "User:\t\t%lu\n", ai_user); @@ -125,7 +153,7 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer if (get_user(mode, buffer)) return -EFAULT; if (mode >= '0' && mode <= '5') - ai_usermode = mode - '0'; + ai_usermode = safe_usermode(mode - '0', true); } return count; } @@ -886,9 +914,16 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (ai_usermode & UM_FIXUP) goto fixup; - if (ai_usermode & UM_SIGNAL) - force_sig(SIGBUS, current); - else { + if (ai_usermode & UM_SIGNAL) { + siginfo_t si; + + si.si_signo = SIGBUS; + si.si_errno = 0; + si.si_code = BUS_ADRALN; + si.si_addr = (void __user *)addr; + + force_sig_info(si.si_signo, &si, current); + } else { /* * We're about to disable the alignment trap and return to * user space. But if an interrupt occurs before actually @@ -926,20 +961,11 @@ static int __init alignment_init(void) return -ENOMEM; #endif - /* - * ARMv6 and later CPUs can perform unaligned accesses for - * most single load and store instructions up to word size. - * LDM, STM, LDRD and STRD still need to be handled. - * - * Ignoring the alignment fault is not an option on these - * CPUs since we spin re-faulting the instruction without - * making any progress. - */ - if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) { + if (cpu_is_v6_unaligned()) { cr_alignment &= ~CR_A; cr_no_alignment &= ~CR_A; set_cr(cr_alignment); - ai_usermode = UM_FIXUP; + ai_usermode = safe_usermode(ai_usermode, false); } hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN, diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 44c0867..9ecfdb5 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -277,6 +277,25 @@ static void l2x0_disable(void) spin_unlock_irqrestore(&l2x0_lock, flags); } +static void __init l2x0_unlock(__u32 cache_id) +{ + int lockregs; + int i; + + if (cache_id == L2X0_CACHE_ID_PART_L310) + lockregs = 8; + else + /* L210 and unknown types */ + lockregs = 1; + + for (i = 0; i < lockregs; i++) { + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE + + i * L2X0_LOCKDOWN_STRIDE); + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE + + i * L2X0_LOCKDOWN_STRIDE); + } +} + void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) { __u32 aux; @@ -328,6 +347,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) * accessing the below registers will fault. */ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* Make sure that I&D is not locked down when starting */ + l2x0_unlock(cache_id); /* l2x0 controller is disabled */ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 2fee782..cc7e2d8 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -298,7 +298,7 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid(unsigned long pfn) { - return memblock_is_memory(pfn << PAGE_SHIFT); + return memblock_is_memory(__pfn_to_phys(pfn)); } EXPORT_SYMBOL(pfn_valid); #endif @@ -441,7 +441,7 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) static inline void poison_init_mem(void *s, size_t count) { u32 *p = (u32 *)s; - while ((count = count - 4)) + for (; count != 0; count -= 4) *p++ = 0xe7fddef0; } diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index ffad039..430df1a 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -9,6 +9,9 @@ #include <linux/ioport.h> #include <linux/io.h> +unsigned long vga_base; +EXPORT_SYMBOL(vga_base); + #ifdef __io void __iomem *ioport_map(unsigned long port, unsigned int nr) { @@ -23,6 +26,15 @@ EXPORT_SYMBOL(ioport_unmap); #endif #ifdef CONFIG_PCI +unsigned long pcibios_min_io = 0x1000; +EXPORT_SYMBOL(pcibios_min_io); + +unsigned long pcibios_min_mem = 0x01000000; +EXPORT_SYMBOL(pcibios_min_mem); + +unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; +EXPORT_SYMBOL(pci_flags); + void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { resource_size_t start = pci_resource_start(dev, bar); diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 92bd102..2e6849b 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -379,7 +379,7 @@ ENTRY(cpu_arm920_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm920_suspend_size -.equ cpu_arm920_suspend_size, 4 * 3 +.equ cpu_arm920_suspend_size, 4 * 4 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm920_do_suspend) stmfd sp!, {r4 - r7, lr} diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 2bbcf05..cd8f79c 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -394,7 +394,7 @@ ENTRY(cpu_arm926_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm926_suspend_size -.equ cpu_arm926_suspend_size, 4 * 3 +.equ cpu_arm926_suspend_size, 4 * 4 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm926_do_suspend) stmfd sp!, {r4 - r7, lr} diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index f8f7ea3..683af3a 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -410,6 +410,7 @@ __arm946_proc_info: .long 0x41009460 .long 0xff00fff0 .long 0 + .long 0 b __arm946_setup .long cpu_arch_name .long cpu_elf_name @@ -418,6 +419,6 @@ __arm946_proc_info: .long arm946_processor_functions .long 0 .long 0 - .long arm940_cache_fns + .long arm946_cache_fns .size __arm946_proc_info, . - __arm946_proc_info diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 07219c2..69e7f2e 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -182,11 +182,11 @@ ENDPROC(cpu_sa1100_do_suspend) ENTRY(cpu_sa1100_do_resume) ldmia r0, {r4 - r7} @ load cp regs - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs - mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache - mcr p15, 0, r1, c9, c0, 0 @ invalidate RB - mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB + mov ip, #0 + mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs + mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache + mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB mcr p15, 0, r4, c3, c0, 0 @ domain ID mcr p15, 0, r5, c2, c0, 0 @ translation table base addr diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 219138d..a923aa0 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -223,6 +223,22 @@ __v6_setup: mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them +#ifdef CONFIG_ARM_ERRATA_364296 + /* + * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data + * corruption with hit-under-miss enabled). The conditional code below + * (setting the undocumented bit 31 in the auxiliary control register + * and the FI bit in the control register) disables hit-under-miss + * without putting the processor into full low interrupt latency mode. + */ + ldr r6, =0x4107b362 @ id for ARM1136 r0p2 + mrc p15, 0, r5, c0, c0, 0 @ get processor id + teq r5, r6 @ check for the faulty core + mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg + orreq r5, r5, #(1 << 31) @ set the undocumented bit 31 + mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg + orreq r0, r0, #(1 << 21) @ low interrupt latency configuration +#endif mov pc, lr @ return to head.S:__ret /* diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index a30e785..9049c0764 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -66,6 +66,7 @@ ENDPROC(cpu_v7_proc_fin) ENTRY(cpu_v7_reset) mrc p15, 0, r1, c1, c0, 0 @ ctrl register bic r1, r1, #0x1 @ ...............m + THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions) mcr p15, 0, r1, c1, c0, 0 @ disable MMU isb mov pc, r0 @@ -247,13 +248,16 @@ ENTRY(cpu_v7_do_resume) mcr p15, 0, r7, c2, c0, 0 @ TTB 0 mcr p15, 0, r8, c2, c0, 1 @ TTB 1 mcr p15, 0, ip, c2, c0, 2 @ TTB control register - mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register + mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register + teq r4, r10 @ Is it already set? + mcrne p15, 0, r10, c1, c0, 1 @ No, so write it mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control ldr r4, =PRRR @ PRRR ldr r5, =NMRR @ NMRR mcr p15, 0, r4, c10, c2, 0 @ write PRRR mcr p15, 0, r5, c10, c2, 1 @ write NMRR isb + dsb mov r0, r9 @ control register mov r2, r7, lsr #14 @ get TTB0 base mov r2, r2, lsl #14 diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 64f1fc7..755e1bf 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -28,7 +28,6 @@ #include <linux/init.h> #include <asm/assembler.h> #include <asm/hwcap.h> -#include <mach/hardware.h> #include <asm/pgtable.h> #include <asm/pgtable-hwdef.h> #include <asm/page.h> @@ -407,7 +406,7 @@ ENTRY(cpu_xsc3_set_pte_ext) .align .globl cpu_xsc3_suspend_size -.equ cpu_xsc3_suspend_size, 4 * 8 +.equ cpu_xsc3_suspend_size, 4 * 7 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_xsc3_do_suspend) stmfd sp!, {r4 - r10, lr} @@ -419,12 +418,12 @@ ENTRY(cpu_xsc3_do_suspend) mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg mrc p15, 0, r10, c1, c0, 0 @ control reg bic r4, r4, #2 @ clear frequency change bit - stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs + stmia r0, {r4 - r10} @ store cp regs ldmia sp!, {r4 - r10, pc} ENDPROC(cpu_xsc3_do_suspend) ENTRY(cpu_xsc3_do_resume) - ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs + ldmia r0, {r4 - r10} @ load cp regs mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index 43f2b15..845549c 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -374,6 +374,9 @@ void __init iop3xx_pci_preinit_cond(void) void __init iop3xx_pci_preinit(void) { + pcibios_min_io = 0; + pcibios_min_mem = 0; + iop3xx_atu_disable(); iop3xx_atu_setup(); iop3xx_atu_debug(); diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c index fb166b2..0d6ed31b 100644 --- a/arch/arm/plat-mxc/devices.c +++ b/arch/arm/plat-mxc/devices.c @@ -95,8 +95,22 @@ struct device mxc_aips_bus = { .parent = &platform_bus, }; +struct device mxc_ahb_bus = { + .init_name = "mxc_ahb", + .parent = &platform_bus, +}; + static int __init mxc_device_init(void) { - return device_register(&mxc_aips_bus); + int ret; + + ret = device_register(&mxc_aips_bus); + if (IS_ERR_VALUE(ret)) + goto done; + + ret = device_register(&mxc_ahb_bus); + +done: + return ret; } core_initcall(mxc_device_init); diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c index 4fc6ffc..0bae44e 100644 --- a/arch/arm/plat-mxc/devices/platform-fec.c +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -11,40 +11,45 @@ #include <mach/hardware.h> #include <mach/devices-common.h> -#define imx_fec_data_entry_single(soc) \ +#define imx_fec_data_entry_single(soc, _devid) \ { \ + .devid = _devid, \ .iobase = soc ## _FEC_BASE_ADDR, \ .irq = soc ## _INT_FEC, \ } #ifdef CONFIG_SOC_IMX25 const struct imx_fec_data imx25_fec_data __initconst = - imx_fec_data_entry_single(MX25); + imx_fec_data_entry_single(MX25, "imx25-fec"); #endif /* ifdef CONFIG_SOC_IMX25 */ #ifdef CONFIG_SOC_IMX27 const struct imx_fec_data imx27_fec_data __initconst = - imx_fec_data_entry_single(MX27); + imx_fec_data_entry_single(MX27, "imx27-fec"); #endif /* ifdef CONFIG_SOC_IMX27 */ #ifdef CONFIG_SOC_IMX35 +/* i.mx35 has the i.mx27 type fec */ const struct imx_fec_data imx35_fec_data __initconst = - imx_fec_data_entry_single(MX35); + imx_fec_data_entry_single(MX35, "imx27-fec"); #endif #ifdef CONFIG_SOC_IMX50 +/* i.mx50 has the i.mx25 type fec */ const struct imx_fec_data imx50_fec_data __initconst = - imx_fec_data_entry_single(MX50); + imx_fec_data_entry_single(MX50, "imx25-fec"); #endif #ifdef CONFIG_SOC_IMX51 +/* i.mx51 has the i.mx27 type fec */ const struct imx_fec_data imx51_fec_data __initconst = - imx_fec_data_entry_single(MX51); + imx_fec_data_entry_single(MX51, "imx27-fec"); #endif #ifdef CONFIG_SOC_IMX53 +/* i.mx53 has the i.mx25 type fec */ const struct imx_fec_data imx53_fec_data __initconst = - imx_fec_data_entry_single(MX53); + imx_fec_data_entry_single(MX53, "imx25-fec"); #endif struct platform_device *__init imx_add_fec( @@ -63,7 +68,7 @@ struct platform_device *__init imx_add_fec( }, }; - return imx_add_platform_device_dmamask("fec", 0, + return imx_add_platform_device_dmamask(data->devid, 0, res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c index c64f015..7fa7e9c 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-dma.c +++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c @@ -6,207 +6,29 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ -#include <linux/compiler.h> -#include <linux/err.h> -#include <linux/init.h> - -#include <mach/hardware.h> #include <mach/devices-common.h> -#include <mach/sdma.h> - -struct imx_imx_sdma_data { - resource_size_t iobase; - resource_size_t irq; - struct sdma_platform_data pdata; -}; - -#define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\ - { \ - .iobase = soc ## _SDMA ## _BASE_ADDR, \ - .irq = soc ## _INT_SDMA, \ - .pdata = { \ - .sdma_version = _sdma_version, \ - .cpu_name = _cpu_name, \ - .to_version = _to_version, \ - }, \ - } - -#ifdef CONFIG_SOC_IMX25 -struct imx_imx_sdma_data imx25_imx_sdma_data __initconst = - imx_imx_sdma_data_entry_single(MX25, 2, "imx25", 1); -#endif /* ifdef CONFIG_SOC_IMX25 */ -#ifdef CONFIG_SOC_IMX31 -struct imx_imx_sdma_data imx31_imx_sdma_data __initdata = - imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 1); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -struct imx_imx_sdma_data imx35_imx_sdma_data __initdata = - imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 1); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -#ifdef CONFIG_SOC_IMX51 -struct imx_imx_sdma_data imx51_imx_sdma_data __initconst = - imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 1); -#endif /* ifdef CONFIG_SOC_IMX51 */ +struct platform_device __init __maybe_unused *imx_add_imx_dma(void) +{ + return platform_device_register_resndata(&mxc_ahb_bus, + "imx-dma", -1, NULL, 0, NULL, 0); +} -static struct platform_device __init __maybe_unused *imx_add_imx_sdma( - const struct imx_imx_sdma_data *data) +struct platform_device __init __maybe_unused *imx_add_imx_sdma(char *name, + resource_size_t iobase, int irq, struct sdma_platform_data *pdata) { struct resource res[] = { { - .start = data->iobase, - .end = data->iobase + SZ_16K - 1, + .start = iobase, + .end = iobase + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { - .start = data->irq, - .end = data->irq, + .start = irq, + .end = irq, .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device("imx-sdma", -1, - res, ARRAY_SIZE(res), - &data->pdata, sizeof(data->pdata)); -} - -static struct platform_device __init __maybe_unused *imx_add_imx_dma(void) -{ - return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0); -} - -#ifdef CONFIG_ARCH_MX25 -static struct sdma_script_start_addrs addr_imx25 = { - .ap_2_ap_addr = 729, - .uart_2_mcu_addr = 904, - .per_2_app_addr = 1255, - .mcu_2_app_addr = 834, - .uartsh_2_mcu_addr = 1120, - .per_2_shp_addr = 1329, - .mcu_2_shp_addr = 1048, - .ata_2_mcu_addr = 1560, - .mcu_2_ata_addr = 1479, - .app_2_per_addr = 1189, - .app_2_mcu_addr = 770, - .shp_2_per_addr = 1407, - .shp_2_mcu_addr = 979, -}; -#endif - -#ifdef CONFIG_SOC_IMX31 -static struct sdma_script_start_addrs addr_imx31_to1 = { - .per_2_per_addr = 1677, -}; - -static struct sdma_script_start_addrs addr_imx31_to2 = { - .ap_2_ap_addr = 423, - .ap_2_bp_addr = 829, - .bp_2_ap_addr = 1029, -}; -#endif - -#ifdef CONFIG_SOC_IMX35 -static struct sdma_script_start_addrs addr_imx35_to1 = { - .ap_2_ap_addr = 642, - .uart_2_mcu_addr = 817, - .mcu_2_app_addr = 747, - .uartsh_2_mcu_addr = 1183, - .per_2_shp_addr = 1033, - .mcu_2_shp_addr = 961, - .ata_2_mcu_addr = 1333, - .mcu_2_ata_addr = 1252, - .app_2_mcu_addr = 683, - .shp_2_per_addr = 1111, - .shp_2_mcu_addr = 892, -}; - -static struct sdma_script_start_addrs addr_imx35_to2 = { - .ap_2_ap_addr = 729, - .uart_2_mcu_addr = 904, - .per_2_app_addr = 1597, - .mcu_2_app_addr = 834, - .uartsh_2_mcu_addr = 1270, - .per_2_shp_addr = 1120, - .mcu_2_shp_addr = 1048, - .ata_2_mcu_addr = 1429, - .mcu_2_ata_addr = 1339, - .app_2_per_addr = 1531, - .app_2_mcu_addr = 770, - .shp_2_per_addr = 1198, - .shp_2_mcu_addr = 979, -}; -#endif - -#ifdef CONFIG_SOC_IMX51 -static struct sdma_script_start_addrs addr_imx51 = { - .ap_2_ap_addr = 642, - .uart_2_mcu_addr = 817, - .mcu_2_app_addr = 747, - .mcu_2_shp_addr = 961, - .ata_2_mcu_addr = 1473, - .mcu_2_ata_addr = 1392, - .app_2_per_addr = 1033, - .app_2_mcu_addr = 683, - .shp_2_per_addr = 1251, - .shp_2_mcu_addr = 892, -}; -#endif - -static int __init imxXX_add_imx_dma(void) -{ - struct platform_device *ret; - -#if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27) - if (cpu_is_mx21() || cpu_is_mx27()) - ret = imx_add_imx_dma(); - else -#endif - -#if defined(CONFIG_SOC_IMX25) - if (cpu_is_mx25()) { - imx25_imx_sdma_data.pdata.script_addrs = &addr_imx25; - ret = imx_add_imx_sdma(&imx25_imx_sdma_data); - } else -#endif - -#if defined(CONFIG_SOC_IMX31) - if (cpu_is_mx31()) { - int to_version = mx31_revision() >> 4; - imx31_imx_sdma_data.pdata.to_version = to_version; - if (to_version == 1) - imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to1; - else - imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to2; - ret = imx_add_imx_sdma(&imx31_imx_sdma_data); - } else -#endif - -#if defined(CONFIG_SOC_IMX35) - if (cpu_is_mx35()) { - int to_version = mx35_revision() >> 4; - imx35_imx_sdma_data.pdata.to_version = to_version; - if (to_version == 1) - imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to1; - else - imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to2; - ret = imx_add_imx_sdma(&imx35_imx_sdma_data); - } else -#endif - -#if defined(CONFIG_SOC_IMX51) - if (cpu_is_mx51()) { - int to_version = mx51_revision() >> 4; - imx51_imx_sdma_data.pdata.to_version = to_version; - imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51; - ret = imx_add_imx_sdma(&imx51_imx_sdma_data); - } else -#endif - ret = ERR_PTR(-ENODEV); - - if (IS_ERR(ret)) - return PTR_ERR(ret); - - return 0; + return platform_device_register_resndata(&mxc_ahb_bus, name, + -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } -arch_initcall(imxXX_add_imx_dma); diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c index 2ab74f0..afe60f7 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-i2c.c +++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c @@ -94,8 +94,9 @@ const struct imx_imx_i2c_data imx53_imx_i2c_data[] __initconst = { imx_imx_i2c_data_entry(MX53, _id, _hwid, SZ_4K) imx53_imx_i2c_data_entry(0, 1), imx53_imx_i2c_data_entry(1, 2), + imx53_imx_i2c_data_entry(2, 3), }; -#endif /* ifdef CONFIG_SOC_IMX51 */ +#endif /* ifdef CONFIG_SOC_IMX53 */ struct platform_device *__init imx_add_imx_i2c( const struct imx_imx_i2c_data *data, diff --git a/arch/arm/plat-mxc/devices/platform-imx-keypad.c b/arch/arm/plat-mxc/devices/platform-imx-keypad.c index 2636611..479c3e9 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-keypad.c +++ b/arch/arm/plat-mxc/devices/platform-imx-keypad.c @@ -46,6 +46,11 @@ const struct imx_imx_keypad_data imx51_imx_keypad_data __initconst = imx_imx_keypad_data_entry_single(MX51, SZ_16); #endif /* ifdef CONFIG_SOC_IMX51 */ +#ifdef CONFIG_SOC_IMX53 +const struct imx_imx_keypad_data imx53_imx_keypad_data __initconst = + imx_imx_keypad_data_entry_single(MX53, SZ_16); +#endif /* ifdef CONFIG_SOC_IMX53 */ + struct platform_device *__init imx_add_imx_keypad( const struct imx_imx_keypad_data *data, const struct matrix_keymap_data *pdata) diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/plat-mxc/devices/platform-imx-ssi.c index 66b8593..21c6f30 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-ssi.c +++ b/arch/arm/plat-mxc/devices/platform-imx-ssi.c @@ -76,6 +76,16 @@ const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = { }; #endif /* ifdef CONFIG_SOC_IMX51 */ +#ifdef CONFIG_SOC_IMX53 +const struct imx_imx_ssi_data imx53_imx_ssi_data[] __initconst = { +#define imx53_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX53, _id, _hwid, SZ_16K) + imx53_imx_ssi_data_entry(0, 1), + imx53_imx_ssi_data_entry(1, 2), + imx53_imx_ssi_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_SOC_IMX53 */ + struct platform_device *__init imx_add_imx_ssi( const struct imx_imx_ssi_data *data, const struct imx_ssi_platform_data *pdata) diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c index 3c854c2..2020d84 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-uart.c +++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c @@ -123,6 +123,8 @@ const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst = { imx53_imx_uart_data_entry(0, 1), imx53_imx_uart_data_entry(1, 2), imx53_imx_uart_data_entry(2, 3), + imx53_imx_uart_data_entry(3, 4), + imx53_imx_uart_data_entry(4, 5), }; #endif /* ifdef CONFIG_SOC_IMX53 */ @@ -150,7 +152,7 @@ struct platform_device *__init imx_add_imx_uart_3irq( }, }; - return imx_add_platform_device("imx-uart", data->id, res, + return imx_add_platform_device("imx1-uart", data->id, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } @@ -170,6 +172,7 @@ struct platform_device *__init imx_add_imx_uart_1irq( }, }; - return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); + /* i.mx21 type uart runs on all i.mx except i.mx1 */ + return imx_add_platform_device("imx21-uart", data->id, + res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c index 6b2940b..5955f5d 100644 --- a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c +++ b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c @@ -10,21 +10,22 @@ #include <mach/devices-common.h> #include <mach/esdhc.h> -#define imx_sdhci_esdhc_imx_data_entry_single(soc, _id, hwid) \ +#define imx_sdhci_esdhc_imx_data_entry_single(soc, _devid, _id, hwid) \ { \ + .devid = _devid, \ .id = _id, \ .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \ .irq = soc ## _INT_ESDHC ## hwid, \ } -#define imx_sdhci_esdhc_imx_data_entry(soc, id, hwid) \ - [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, id, hwid) +#define imx_sdhci_esdhc_imx_data_entry(soc, devid, id, hwid) \ + [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, devid, id, hwid) #ifdef CONFIG_SOC_IMX25 const struct imx_sdhci_esdhc_imx_data imx25_sdhci_esdhc_imx_data[] __initconst = { #define imx25_sdhci_esdhc_imx_data_entry(_id, _hwid) \ - imx_sdhci_esdhc_imx_data_entry(MX25, _id, _hwid) + imx_sdhci_esdhc_imx_data_entry(MX25, "sdhci-esdhc-imx25", _id, _hwid) imx25_sdhci_esdhc_imx_data_entry(0, 1), imx25_sdhci_esdhc_imx_data_entry(1, 2), }; @@ -34,7 +35,7 @@ imx25_sdhci_esdhc_imx_data[] __initconst = { const struct imx_sdhci_esdhc_imx_data imx35_sdhci_esdhc_imx_data[] __initconst = { #define imx35_sdhci_esdhc_imx_data_entry(_id, _hwid) \ - imx_sdhci_esdhc_imx_data_entry(MX35, _id, _hwid) + imx_sdhci_esdhc_imx_data_entry(MX35, "sdhci-esdhc-imx35", _id, _hwid) imx35_sdhci_esdhc_imx_data_entry(0, 1), imx35_sdhci_esdhc_imx_data_entry(1, 2), imx35_sdhci_esdhc_imx_data_entry(2, 3), @@ -45,7 +46,7 @@ imx35_sdhci_esdhc_imx_data[] __initconst = { const struct imx_sdhci_esdhc_imx_data imx51_sdhci_esdhc_imx_data[] __initconst = { #define imx51_sdhci_esdhc_imx_data_entry(_id, _hwid) \ - imx_sdhci_esdhc_imx_data_entry(MX51, _id, _hwid) + imx_sdhci_esdhc_imx_data_entry(MX51, "sdhci-esdhc-imx51", _id, _hwid) imx51_sdhci_esdhc_imx_data_entry(0, 1), imx51_sdhci_esdhc_imx_data_entry(1, 2), imx51_sdhci_esdhc_imx_data_entry(2, 3), @@ -57,7 +58,7 @@ imx51_sdhci_esdhc_imx_data[] __initconst = { const struct imx_sdhci_esdhc_imx_data imx53_sdhci_esdhc_imx_data[] __initconst = { #define imx53_sdhci_esdhc_imx_data_entry(_id, _hwid) \ - imx_sdhci_esdhc_imx_data_entry(MX53, _id, _hwid) + imx_sdhci_esdhc_imx_data_entry(MX53, "sdhci-esdhc-imx53", _id, _hwid) imx53_sdhci_esdhc_imx_data_entry(0, 1), imx53_sdhci_esdhc_imx_data_entry(1, 2), imx53_sdhci_esdhc_imx_data_entry(2, 3), @@ -65,6 +66,11 @@ imx53_sdhci_esdhc_imx_data[] __initconst = { }; #endif /* ifdef CONFIG_SOC_IMX53 */ +static const struct esdhc_platform_data default_esdhc_pdata __initconst = { + .wp_type = ESDHC_WP_NONE, + .cd_type = ESDHC_CD_NONE, +}; + struct platform_device *__init imx_add_sdhci_esdhc_imx( const struct imx_sdhci_esdhc_imx_data *data, const struct esdhc_platform_data *pdata) @@ -81,6 +87,13 @@ struct platform_device *__init imx_add_sdhci_esdhc_imx( }, }; - return imx_add_platform_device("sdhci-esdhc-imx", data->id, res, + /* + * If machine does not provide pdata, use the default one + * which means no WP/CD support + */ + if (!pdata) + pdata = &default_esdhc_pdata; + + return imx_add_platform_device(data->devid, data->id, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/include/mach/clkdev.h b/arch/arm/plat-mxc/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/plat-mxc/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S index 91fc7cd..e4dde91 100644 --- a/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S @@ -44,6 +44,14 @@ #define UART_PADDR MX51_UART1_BASE_ADDR #endif +/* iMX50/53 have same addresses, but not iMX51 */ +#if defined(CONFIG_SOC_IMX50) || defined(CONFIG_SOC_IMX53) +#ifdef UART_PADDR +#error "CONFIG_DEBUG_LL is incompatible with multiple archs" +#endif +#define UART_PADDR MX53_UART1_BASE_ADDR +#endif + #define UART_VADDR IMX_IO_ADDRESS(UART_PADDR) .macro addruart, rp, rv diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index 03f6266..524538a 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h @@ -9,8 +9,10 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/init.h> +#include <mach/sdma.h> extern struct device mxc_aips_bus; +extern struct device mxc_ahb_bus; struct platform_device *imx_add_platform_device_dmamask( const char *name, int id, @@ -28,6 +30,7 @@ static inline struct platform_device *imx_add_platform_device( #include <linux/fec.h> struct imx_fec_data { + const char *devid; resource_size_t iobase; resource_size_t irq; }; @@ -274,6 +277,7 @@ struct platform_device *__init imx_add_mxc_w1( #include <mach/esdhc.h> struct imx_sdhci_esdhc_imx_data { + const char *devid; int id; resource_size_t iobase; resource_size_t irq; @@ -293,3 +297,7 @@ struct imx_spi_imx_data { struct platform_device *__init imx_add_spi_imx( const struct imx_spi_imx_data *data, const struct spi_imx_master *pdata); + +struct platform_device *imx_add_imx_dma(void); +struct platform_device *imx_add_imx_sdma(char *name, + resource_size_t iobase, int irq, struct sdma_platform_data *pdata); diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h index ef77515..233d0a5 100644 --- a/arch/arm/plat-mxc/include/mach/dma.h +++ b/arch/arm/plat-mxc/include/mach/dma.h @@ -60,7 +60,8 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan) static inline int imx_dma_is_general_purpose(struct dma_chan *chan) { - return !strcmp(dev_name(chan->device->dev), "imx-sdma") || + return !strcmp(dev_name(chan->device->dev), "imx31-sdma") || + !strcmp(dev_name(chan->device->dev), "imx35-sdma") || !strcmp(dev_name(chan->device->dev), "imx-dma"); } diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h index 86003f4..aaf9748 100644 --- a/arch/arm/plat-mxc/include/mach/esdhc.h +++ b/arch/arm/plat-mxc/include/mach/esdhc.h @@ -10,17 +10,34 @@ #ifndef __ASM_ARCH_IMX_ESDHC_H #define __ASM_ARCH_IMX_ESDHC_H +enum wp_types { + ESDHC_WP_NONE, /* no WP, neither controller nor gpio */ + ESDHC_WP_CONTROLLER, /* mmc controller internal WP */ + ESDHC_WP_GPIO, /* external gpio pin for WP */ +}; + +enum cd_types { + ESDHC_CD_NONE, /* no CD, neither controller nor gpio */ + ESDHC_CD_CONTROLLER, /* mmc controller internal CD */ + ESDHC_CD_GPIO, /* external gpio pin for CD */ + ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */ +}; + /** - * struct esdhc_platform_data - optional platform data for esdhc on i.MX + * struct esdhc_platform_data - platform data for esdhc on i.MX * - * strongly recommended for i.MX25/35, not needed for other variants + * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35. * - * @wp_gpio: gpio for write_protect (-EINVAL if unused) - * @cd_gpio: gpio for card_detect interrupt (-EINVAL if unused) + * @wp_gpio: gpio for write_protect + * @cd_gpio: gpio for card_detect interrupt + * @wp_type: type of write_protect method (see wp_types enum above) + * @cd_type: type of card_detect method (see cd_types enum above) */ struct esdhc_platform_data { unsigned int wp_gpio; unsigned int cd_gpio; + enum wp_types wp_type; + enum cd_types cd_type; }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/arch/arm/plat-mxc/include/mach/iomux-mx53.h index 9440b9e..5408fd1 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx53.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx53.h @@ -30,6 +30,9 @@ #define MX53_SDHC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH | \ PAD_CTL_SRE_FAST) +#define PAD_CTRL_I2C (PAD_CTL_SRE_FAST | PAD_CTL_ODE | PAD_CTL_PKE | \ + PAD_CTL_PUE | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP \ + | PAD_CTL_HYS) #define _MX53_PAD_GPIO_19__KPP_COL_5 IOMUX_PAD(0x348, 0x20, 0, 0x840, 0, 0) #define _MX53_PAD_GPIO_19__GPIO4_5 IOMUX_PAD(0x348, 0x20, 1, 0x0, 0, 0) @@ -1256,7 +1259,7 @@ #define MX53_PAD_KEY_COL3__GPIO4_12 (_MX53_PAD_KEY_COL3__GPIO4_12 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__USBOH3_H2_DP (_MX53_PAD_KEY_COL3__USBOH3_H2_DP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__SPDIF_IN1 (_MX53_PAD_KEY_COL3__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_KEY_COL3__I2C2_SCL (_MX53_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_KEY_COL3__I2C2_SCL (_MX53_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_KEY_COL3__ECSPI1_SS3 (_MX53_PAD_KEY_COL3__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__FEC_CRS (_MX53_PAD_KEY_COL3__FEC_CRS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK (_MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1264,7 +1267,7 @@ #define MX53_PAD_KEY_ROW3__GPIO4_13 (_MX53_PAD_KEY_ROW3__GPIO4_13 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__USBOH3_H2_DM (_MX53_PAD_KEY_ROW3__USBOH3_H2_DM | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK (_MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_KEY_ROW3__I2C2_SDA (_MX53_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_KEY_ROW3__I2C2_SDA (_MX53_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_KEY_ROW3__OSC32K_32K_OUT (_MX53_PAD_KEY_ROW3__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__CCM_PLL4_BYP (_MX53_PAD_KEY_ROW3__CCM_PLL4_BYP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 (_MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1536,7 +1539,7 @@ #define MX53_PAD_CSI0_DAT8__KPP_COL_7 (_MX53_PAD_CSI0_DAT8__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__ECSPI2_SCLK (_MX53_PAD_CSI0_DAT8__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC (_MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_CSI0_DAT8__I2C1_SDA (_MX53_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_CSI0_DAT8__I2C1_SDA (_MX53_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 (_MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 (_MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 (_MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1544,7 +1547,7 @@ #define MX53_PAD_CSI0_DAT9__KPP_ROW_7 (_MX53_PAD_CSI0_DAT9__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__ECSPI2_MOSI (_MX53_PAD_CSI0_DAT9__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR (_MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_CSI0_DAT9__I2C1_SCL (_MX53_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_CSI0_DAT9__I2C1_SCL (_MX53_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 (_MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 (_MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 (_MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1631,25 +1634,25 @@ #define MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK (_MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS (_MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_EB2__ECSPI1_SS0 (_MX53_PAD_EIM_EB2__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_EB2__I2C2_SCL (_MX53_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_EB2__I2C2_SCL (_MX53_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D16__EMI_WEIM_D_16 (_MX53_PAD_EIM_D16__EMI_WEIM_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__GPIO3_16 (_MX53_PAD_EIM_D16__GPIO3_16 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__IPU_DI0_PIN5 (_MX53_PAD_EIM_D16__IPU_DI0_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK (_MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__ECSPI1_SCLK (_MX53_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D16__I2C2_SDA (_MX53_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_D16__I2C2_SDA (_MX53_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D17__EMI_WEIM_D_17 (_MX53_PAD_EIM_D17__EMI_WEIM_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__GPIO3_17 (_MX53_PAD_EIM_D17__GPIO3_17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__IPU_DI0_PIN6 (_MX53_PAD_EIM_D17__IPU_DI0_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN (_MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__ECSPI1_MISO (_MX53_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D17__I2C3_SCL (_MX53_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_D17__I2C3_SCL (_MX53_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D18__EMI_WEIM_D_18 (_MX53_PAD_EIM_D18__EMI_WEIM_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__GPIO3_18 (_MX53_PAD_EIM_D18__GPIO3_18 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__IPU_DI0_PIN7 (_MX53_PAD_EIM_D18__IPU_DI0_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO (_MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__ECSPI1_MOSI (_MX53_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D18__I2C3_SDA (_MX53_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_D18__I2C3_SDA (_MX53_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D18__IPU_DI1_D0_CS (_MX53_PAD_EIM_D18__IPU_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D19__EMI_WEIM_D_19 (_MX53_PAD_EIM_D19__EMI_WEIM_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D19__GPIO3_19 (_MX53_PAD_EIM_D19__GPIO3_19 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1672,7 +1675,7 @@ #define MX53_PAD_EIM_D21__IPU_DI0_PIN17 (_MX53_PAD_EIM_D21__IPU_DI0_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK (_MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D21__CSPI_SCLK (_MX53_PAD_EIM_D21__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D21__I2C1_SCL (_MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_D21__I2C1_SCL (_MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D21__USBOH3_USBOTG_OC (_MX53_PAD_EIM_D21__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D22__EMI_WEIM_D_22 (_MX53_PAD_EIM_D22__EMI_WEIM_D_22 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D22__GPIO3_22 (_MX53_PAD_EIM_D22__GPIO3_22 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1732,7 +1735,7 @@ #define MX53_PAD_EIM_D28__UART2_CTS (_MX53_PAD_EIM_D28__UART2_CTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL)) #define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO (_MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D28__CSPI_MOSI (_MX53_PAD_EIM_D28__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D28__I2C1_SDA (_MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_EIM_D28__I2C1_SDA (_MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_EIM_D28__IPU_EXT_TRIG (_MX53_PAD_EIM_D28__IPU_EXT_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D28__IPU_DI0_PIN13 (_MX53_PAD_EIM_D28__IPU_DI0_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D29__EMI_WEIM_D_29 (_MX53_PAD_EIM_D29__EMI_WEIM_D_29 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2297,7 +2300,7 @@ #define MX53_PAD_GPIO_9__SCC_FAIL_STATE (_MX53_PAD_GPIO_9__SCC_FAIL_STATE | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__ESAI1_HCKR (_MX53_PAD_GPIO_3__ESAI1_HCKR | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__GPIO1_3 (_MX53_PAD_GPIO_3__GPIO1_3 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_3__I2C3_SCL (_MX53_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_GPIO_3__I2C3_SCL (_MX53_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_GPIO_3__DPLLIP1_TOG_EN (_MX53_PAD_GPIO_3__DPLLIP1_TOG_EN | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__CCM_CLKO2 (_MX53_PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 (_MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2305,7 +2308,7 @@ #define MX53_PAD_GPIO_3__MLB_MLBCLK (_MX53_PAD_GPIO_3__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__ESAI1_SCKT (_MX53_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__GPIO1_6 (_MX53_PAD_GPIO_6__GPIO1_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_6__I2C3_SDA (_MX53_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_GPIO_6__I2C3_SDA (_MX53_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_GPIO_6__CCM_CCM_OUT_0 (_MX53_PAD_GPIO_6__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__CSU_CSU_INT_DEB (_MX53_PAD_GPIO_6__CSU_CSU_INT_DEB | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 (_MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2333,7 +2336,7 @@ #define MX53_PAD_GPIO_5__CCM_CLKO (_MX53_PAD_GPIO_5__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 (_MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 (_MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_5__I2C3_SCL (_MX53_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_GPIO_5__I2C3_SCL (_MX53_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_GPIO_5__CCM_PLL1_BYP (_MX53_PAD_GPIO_5__CCM_PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_7__ESAI1_TX4_RX1 (_MX53_PAD_GPIO_7__ESAI1_TX4_RX1 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_7__GPIO1_7 (_MX53_PAD_GPIO_7__GPIO1_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2356,7 +2359,7 @@ #define MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT (_MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 (_MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_16__SPDIF_IN1 (_MX53_PAD_GPIO_16__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_16__I2C3_SDA (_MX53_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX53_PAD_GPIO_16__I2C3_SDA (_MX53_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) #define MX53_PAD_GPIO_16__SJC_DE_B (_MX53_PAD_GPIO_16__SJC_DE_B | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_17__ESAI1_TX0 (_MX53_PAD_GPIO_17__ESAI1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_17__GPIO7_12 (_MX53_PAD_GPIO_17__GPIO7_12 | MUX_PAD_CTRL(NO_PAD_CTRL)) diff --git a/arch/arm/plat-mxc/include/mach/mx53.h b/arch/arm/plat-mxc/include/mach/mx53.h index 74cd093..5e3c323 100644 --- a/arch/arm/plat-mxc/include/mach/mx53.h +++ b/arch/arm/plat-mxc/include/mach/mx53.h @@ -176,10 +176,10 @@ /* * DMA request assignments */ -#define MX53_DMA_REQ_SSI3_TX1 47 -#define MX53_DMA_REQ_SSI3_RX1 46 -#define MX53_DMA_REQ_SSI3_TX2 45 -#define MX53_DMA_REQ_SSI3_RX2 44 +#define MX53_DMA_REQ_SSI3_TX0 47 +#define MX53_DMA_REQ_SSI3_RX0 46 +#define MX53_DMA_REQ_SSI3_TX1 45 +#define MX53_DMA_REQ_SSI3_RX1 44 #define MX53_DMA_REQ_UART3_TX 43 #define MX53_DMA_REQ_UART3_RX 42 #define MX53_DMA_REQ_ESAI_TX 41 @@ -194,14 +194,14 @@ #define MX53_DMA_REQ_ASRC_DMA1 32 #define MX53_DMA_REQ_EMI_WR 31 #define MX53_DMA_REQ_EMI_RD 30 -#define MX53_DMA_REQ_SSI1_TX1 29 -#define MX53_DMA_REQ_SSI1_RX1 28 -#define MX53_DMA_REQ_SSI1_TX2 27 -#define MX53_DMA_REQ_SSI1_RX2 26 -#define MX53_DMA_REQ_SSI2_TX1 25 -#define MX53_DMA_REQ_SSI2_RX1 24 -#define MX53_DMA_REQ_SSI2_TX2 23 -#define MX53_DMA_REQ_SSI2_RX2 22 +#define MX53_DMA_REQ_SSI1_TX0 29 +#define MX53_DMA_REQ_SSI1_RX0 28 +#define MX53_DMA_REQ_SSI1_TX1 27 +#define MX53_DMA_REQ_SSI1_RX1 26 +#define MX53_DMA_REQ_SSI2_TX0 25 +#define MX53_DMA_REQ_SSI2_RX0 24 +#define MX53_DMA_REQ_SSI2_TX1 23 +#define MX53_DMA_REQ_SSI2_RX1 22 #define MX53_DMA_REQ_I2C2_SDHC2 21 #define MX53_DMA_REQ_I2C1_SDHC1 20 #define MX53_DMA_REQ_UART1_TX 19 @@ -241,7 +241,7 @@ #define MX53_INT_IPU_ERR 10 #define MX53_INT_IPU_SYN 11 #define MX53_INT_GPU 12 -#define MX53_INT_RESV13 13 +#define MX53_INT_UART4 13 #define MX53_INT_USB_H1 14 #define MX53_INT_EMI 15 #define MX53_INT_USB_H2 16 @@ -314,7 +314,7 @@ #define MX53_INT_CAN2 83 #define MX53_INT_GPU2_IRQ 84 #define MX53_INT_GPU2_BUSY 85 -#define MX53_INT_RESV86 86 +#define MX53_INT_UART5 86 #define MX53_INT_FEC 87 #define MX53_INT_OWIRE 88 #define MX53_INT_CTI1_TG2 89 diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h index 913e043..3a39428 100644 --- a/arch/arm/plat-mxc/include/mach/sdma.h +++ b/arch/arm/plat-mxc/include/mach/sdma.h @@ -48,15 +48,11 @@ struct sdma_script_start_addrs { /** * struct sdma_platform_data - platform specific data for SDMA engine * - * @sdma_version The version of this SDMA engine - * @cpu_name used to generate the firmware name - * @to_version CPU Tape out version + * @fw_name The firmware name * @script_addrs SDMA scripts addresses in SDMA ROM */ struct sdma_platform_data { - int sdma_version; - char *cpu_name; - int to_version; + char *fw_name; struct sdma_script_start_addrs *script_addrs; }; diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index d85e2d1..88fd404 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h @@ -117,6 +117,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) case MACH_TYPE_MX53_EVK: case MACH_TYPE_MX53_LOCO: case MACH_TYPE_MX53_SMD: + case MACH_TYPE_MX53_ARD: uart_base = MX53_UART1_BASE_ADDR; break; default: diff --git a/arch/arm/plat-mxc/irq-common.c b/arch/arm/plat-mxc/irq-common.c index e1c6eff..96953e2 100644 --- a/arch/arm/plat-mxc/irq-common.c +++ b/arch/arm/plat-mxc/irq-common.c @@ -42,17 +42,16 @@ EXPORT_SYMBOL(imx_irq_set_priority); int mxc_set_irq_fiq(unsigned int irq, unsigned int type) { - struct mxc_irq_chip *chip; - struct irq_chip *base; + struct irq_chip_generic *gc; + int (*set_irq_fiq)(unsigned int, unsigned int); int ret; ret = -ENOSYS; - base = irq_get_chip(irq); - if (base) { - chip = container_of(base, struct mxc_irq_chip, base); - if (chip->set_irq_fiq) - ret = chip->set_irq_fiq(irq, type); + gc = irq_get_chip_data(irq); + if (gc && gc->private) { + set_irq_fiq = gc->private; + ret = set_irq_fiq(irq, type); } return ret; diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index 710f2e7d..f257fcc 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -68,78 +68,34 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) return 0; } +#else +#define tzic_set_irq_fiq NULL #endif -/** - * tzic_mask_irq() - Disable interrupt source "d" in the TZIC - * - * @param d interrupt source - */ -static void tzic_mask_irq(struct irq_data *d) -{ - int index, off; - - index = d->irq >> 5; - off = d->irq & 0x1F; - __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0(index)); -} - -/** - * tzic_unmask_irq() - Enable interrupt source "d" in the TZIC - * - * @param d interrupt source - */ -static void tzic_unmask_irq(struct irq_data *d) -{ - int index, off; - - index = d->irq >> 5; - off = d->irq & 0x1F; - __raw_writel(1 << off, tzic_base + TZIC_ENSET0(index)); -} - -static unsigned int wakeup_intr[4]; +static unsigned int *wakeup_intr[4]; -/** - * tzic_set_wake_irq() - Set interrupt source "d" in the TZIC as a wake-up source. - * - * @param d interrupt source - * @param enable enable as wake-up if equal to non-zero - * disble as wake-up if equal to zero - * - * @return This function returns 0 on success. - */ -static int tzic_set_wake_irq(struct irq_data *d, unsigned int enable) +static __init void tzic_init_gc(unsigned int irq_start) { - unsigned int index, off; - - index = d->irq >> 5; - off = d->irq & 0x1F; - - if (index > 3) - return -EINVAL; - - if (enable) - wakeup_intr[index] |= (1 << off); - else - wakeup_intr[index] &= ~(1 << off); - - return 0; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + int idx = irq_start >> 5; + + gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base, + handle_level_irq); + gc->private = tzic_set_irq_fiq; + gc->wake_enabled = IRQ_MSK(32); + wakeup_intr[idx] = &gc->wake_active; + + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_disable_reg; + ct->chip.irq_unmask = irq_gc_unmask_enable_reg; + ct->chip.irq_set_wake = irq_gc_set_wake; + ct->regs.disable = TZIC_ENCLEAR0(idx); + ct->regs.enable = TZIC_ENSET0(idx); + + irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); } -static struct mxc_irq_chip mxc_tzic_chip = { - .base = { - .name = "MXC_TZIC", - .irq_ack = tzic_mask_irq, - .irq_mask = tzic_mask_irq, - .irq_unmask = tzic_unmask_irq, - .irq_set_wake = tzic_set_wake_irq, - }, -#ifdef CONFIG_FIQ - .set_irq_fiq = tzic_set_irq_fiq, -#endif -}; - /* * This function initializes the TZIC hardware and disables all the * interrupts. It registers the interrupt enable and disable functions @@ -168,11 +124,8 @@ void __init tzic_init_irq(void __iomem *irqbase) /* all IRQ no FIQ Warning :: No selection */ - for (i = 0; i < TZIC_NUM_IRQS; i++) { - irq_set_chip_and_handler(i, &mxc_tzic_chip.base, - handle_level_irq); - set_irq_flags(i, IRQF_VALID); - } + for (i = 0; i < TZIC_NUM_IRQS; i += 32) + tzic_init_gc(i); #ifdef CONFIG_FIQ /* Initialize FIQ */ @@ -199,7 +152,7 @@ int tzic_enable_wake(int is_idle) for (i = 0; i < 4; i++) { v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) : - wakeup_intr[i]; + *wakeup_intr[i]; __raw_writel(v, tzic_base + TZIC_WAKEUP0(i)); } diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 6e6735f..bb8f4a6 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -13,6 +13,7 @@ config ARCH_OMAP1 bool "TI OMAP1" select CLKDEV_LOOKUP select CLKSRC_MMIO + select GENERIC_IRQ_CHIP help "Systems based on omap7xx, omap15xx or omap16xx" diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 964704f..3ba4d11 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -475,8 +475,41 @@ int __init clk_init(struct clk_functions * custom_clocks) /* * debugfs support to trace clock tree hierarchy and attributes */ + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + static struct dentry *clk_debugfs_root; +static int clk_dbg_show_summary(struct seq_file *s, void *unused) +{ + struct clk *c; + struct clk *pa; + + seq_printf(s, "%-30s %-30s %-10s %s\n", + "clock-name", "parent-name", "rate", "use-count"); + + list_for_each_entry(c, &clocks, node) { + pa = c->parent; + seq_printf(s, "%-30s %-30s %-10lu %d\n", + c->name, pa ? pa->name : "none", c->rate, c->usecount); + } + + return 0; +} + +static int clk_dbg_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_dbg_show_summary, inode->i_private); +} + +static const struct file_operations debug_clock_fops = { + .open = clk_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int clk_debugfs_register_one(struct clk *c) { int err; @@ -545,6 +578,12 @@ static int __init clk_debugfs_init(void) if (err) goto err_out; } + + d = debugfs_create_file("summary", S_IRUGO, + d, NULL, &debug_clock_fops); + if (!d) + return -ENOMEM; + return 0; err_out: debugfs_remove_recursive(clk_debugfs_root); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 8dfb818..75a847d 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -209,8 +209,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) } omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); - /* Enable autoidle on OMAP2 / OMAP3 */ - if (cpu_is_omap24xx() || cpu_is_omap34xx()) + /* Enable autoidle on OMAP2+ */ + if (cpu_class_is_omap2()) autoidle = 1; /* diff --git a/arch/arm/plat-omap/include/plat/clkdev.h b/arch/arm/plat-omap/include/plat/clkdev.h deleted file mode 100644 index 730c49d..0000000 --- a/arch/arm/plat-omap/include/plat/clkdev.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __MACH_CLKDEV_H -#define __MACH_CLKDEV_H - -static inline int __clk_get(struct clk *clk) -{ - return 1; -} - -static inline void __clk_put(struct clk *clk) -{ -} - -#endif diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index f1899a3e..387a963 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -39,6 +39,7 @@ struct omap_clk { #define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */ #define CK_443X (1 << 11) #define CK_TI816X (1 << 12) +#define CK_446X (1 << 13) #define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index f57e064..df4b968 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -58,10 +58,12 @@ struct clkops { #define RATE_IN_36XX (1 << 4) #define RATE_IN_4430 (1 << 5) #define RATE_IN_TI816X (1 << 6) +#define RATE_IN_4460 (1 << 7) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) #define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX) +#define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460) /* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */ #define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX) diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 8198bb6..67b3d75 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -88,6 +88,7 @@ unsigned int omap_rev(void); * cpu_is_omap243x(): True for OMAP2430 * cpu_is_omap343x(): True for OMAP3430 * cpu_is_omap443x(): True for OMAP4430 + * cpu_is_omap446x(): True for OMAP4460 */ #define GET_OMAP_CLASS (omap_rev() & 0xff) @@ -123,6 +124,7 @@ IS_OMAP_SUBCLASS(243x, 0x243) IS_OMAP_SUBCLASS(343x, 0x343) IS_OMAP_SUBCLASS(363x, 0x363) IS_OMAP_SUBCLASS(443x, 0x443) +IS_OMAP_SUBCLASS(446x, 0x446) IS_TI_SUBCLASS(816x, 0x816) @@ -137,6 +139,7 @@ IS_TI_SUBCLASS(816x, 0x816) #define cpu_is_ti816x() 0 #define cpu_is_omap44xx() 0 #define cpu_is_omap443x() 0 +#define cpu_is_omap446x() 0 #if defined(MULTI_OMAP1) # if defined(CONFIG_ARCH_OMAP730) @@ -361,8 +364,10 @@ IS_OMAP_TYPE(3517, 0x3517) # if defined(CONFIG_ARCH_OMAP4) # undef cpu_is_omap44xx # undef cpu_is_omap443x +# undef cpu_is_omap446x # define cpu_is_omap44xx() is_omap44xx() # define cpu_is_omap443x() is_omap443x() +# define cpu_is_omap446x() is_omap446x() # endif /* Macros to detect if we have OMAP1 or OMAP2 */ @@ -410,6 +415,9 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) #define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) +#define OMAP446X_CLASS 0x44600044 +#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) + /* * omap_chip bits * @@ -439,13 +447,15 @@ IS_OMAP_TYPE(3517, 0x3517) #define CHIP_IS_OMAP4430ES2_1 (1 << 12) #define CHIP_IS_OMAP4430ES2_2 (1 << 13) #define CHIP_IS_TI816X (1 << 14) +#define CHIP_IS_OMAP4460ES1_0 (1 << 15) #define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) #define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \ CHIP_IS_OMAP4430ES2 | \ CHIP_IS_OMAP4430ES2_1 | \ - CHIP_IS_OMAP4430ES2_2) + CHIP_IS_OMAP4430ES2_2 | \ + CHIP_IS_OMAP4460ES1_0) /* * "GE" here represents "greater than or equal to" in terms of ES @@ -468,7 +478,7 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features */ -extern u32 omap3_features; +extern u32 omap_features; #define OMAP3_HAS_L2CACHE BIT(0) #define OMAP3_HAS_IVA BIT(1) @@ -478,11 +488,15 @@ extern u32 omap3_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) +#define OMAP4_HAS_MPU_1GHZ BIT(8) +#define OMAP4_HAS_MPU_1_2GHZ BIT(9) +#define OMAP4_HAS_MPU_1_5GHZ BIT(10) + #define OMAP3_HAS_FEATURE(feat,flag) \ static inline unsigned int omap3_has_ ##feat(void) \ { \ - return (omap3_features & OMAP3_HAS_ ##flag); \ + return omap_features & OMAP3_HAS_ ##flag; \ } \ OMAP3_HAS_FEATURE(l2cache, L2CACHE) @@ -494,4 +508,19 @@ OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +/* + * Runtime detection of OMAP4 features + */ +extern u32 omap_features; + +#define OMAP4_HAS_FEATURE(feat, flag) \ +static inline unsigned int omap4_has_ ##feat(void) \ +{ \ + return omap_features & OMAP4_HAS_ ##flag; \ +} \ + +OMAP4_HAS_FEATURE(mpu_1ghz, MPU_1GHZ) +OMAP4_HAS_FEATURE(mpu_1_2ghz, MPU_1_2GHZ) +OMAP4_HAS_FEATURE(mpu_1_5ghz, MPU_1_5GHZ) + #endif diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h index d1c916f..dc562a5 100644 --- a/arch/arm/plat-omap/include/plat/dma.h +++ b/arch/arm/plat-omap/include/plat/dma.h @@ -195,6 +195,11 @@ #define OMAP36XX_DMA_UART4_TX 81 /* S_DMA_80 */ #define OMAP36XX_DMA_UART4_RX 82 /* S_DMA_81 */ + +/* Only for AM35xx */ +#define AM35XX_DMA_UART4_TX 54 +#define AM35XX_DMA_UART4_RX 55 + /*----------------------------------------------------------------------------*/ #define OMAP1_DMA_TOUT_IRQ (1 << 0) diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h index 878d632..7c22b9e 100644 --- a/arch/arm/plat-omap/include/plat/i2c.h +++ b/arch/arm/plat-omap/include/plat/i2c.h @@ -22,6 +22,7 @@ #define __ASM__ARCH_OMAP_I2C_H #include <linux/i2c.h> +#include <linux/i2c-omap.h> #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) extern int omap_register_i2c_bus(int bus_id, u32 clkrate, @@ -46,10 +47,13 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, */ struct omap_i2c_dev_attr { u8 fifo_depth; - u8 flags; + u32 flags; }; void __init omap1_i2c_mux_pins(int bus_id); void __init omap2_i2c_mux_pins(int bus_id); +struct omap_hwmod; +int omap_i2c_reset(struct omap_hwmod *oh); + #endif /* __ASM__ARCH_OMAP_I2C_H */ diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index c884320..30e1071 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -357,6 +357,7 @@ #define INT_35XX_EMAC_C0_TX_PULSE_IRQ 69 #define INT_35XX_EMAC_C0_MISC_PULSE_IRQ 70 #define INT_35XX_USBOTG_IRQ 71 +#define INT_35XX_UART4 84 #define INT_35XX_CCDC_VD0_IRQ 88 #define INT_35XX_CCDC_VD1_IRQ 92 #define INT_35XX_CCDC_VD2_IRQ 93 @@ -407,11 +408,19 @@ #endif #define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS) +#define TWL6040_CODEC_IRQ_BASE TWL6030_IRQ_END +#ifdef CONFIG_TWL6040_CODEC +#define TWL6040_CODEC_NR_IRQS 6 +#else +#define TWL6040_CODEC_NR_IRQS 0 +#endif +#define TWL6040_CODEC_IRQ_END (TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS) + /* Total number of interrupts depends on the enabled blocks above */ -#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END) +#if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END) #define TWL_IRQ_END TWL4030_GPIO_IRQ_END #else -#define TWL_IRQ_END TWL6030_IRQ_END +#define TWL_IRQ_END TWL6040_CODEC_IRQ_END #endif /* GPMC related */ diff --git a/arch/arm/plat-omap/include/plat/omap4-keypad.h b/arch/arm/plat-omap/include/plat/omap4-keypad.h index 2b1d9bc..9fe6c87 100644 --- a/arch/arm/plat-omap/include/plat/omap4-keypad.h +++ b/arch/arm/plat-omap/include/plat/omap4-keypad.h @@ -10,5 +10,6 @@ struct omap4_keypad_platform_data { u8 cols; }; -extern int omap4_keyboard_init(struct omap4_keypad_platform_data *); +extern int omap4_keyboard_init(struct omap4_keypad_platform_data *, + struct omap_board_data *); #endif diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index ce06ac6..0e329ca 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -2,6 +2,7 @@ * omap_hwmod macros, structures * * Copyright (C) 2009-2011 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. * Paul Walmsley * * Created in collaboration with (alphabetical order): Benoît Cousson, @@ -79,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; #define HWMOD_IDLEMODE_SMART (1 << 2) #define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) +/* modulemode control type (SW or HW) */ +#define MODULEMODE_HWCTRL 1 +#define MODULEMODE_SWCTRL 2 + + /** * struct omap_hwmod_mux_info - hwmod specific mux configuration * @pads: array of omap_device_pad entries @@ -360,9 +366,11 @@ struct omap_hwmod_omap2_prcm { * @submodule_wkdep_bit: bit shift of the WKDEP range */ struct omap_hwmod_omap4_prcm { - void __iomem *clkctrl_reg; - void __iomem *rstctrl_reg; + u16 clkctrl_offs; + u16 rstctrl_offs; + u16 context_offs; u8 submodule_wkdep_bit; + u8 modulemode; }; @@ -515,6 +523,8 @@ struct omap_hwmod { const char *main_clk; struct clk *_clk; struct omap_hwmod_opt_clk *opt_clks; + char *clkdm_name; + struct clockdomain *clkdm; char *vdd_name; struct voltagedomain *voltdm; struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ @@ -566,6 +576,7 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh); void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs); u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); +int omap_hwmod_softreset(struct omap_hwmod *oh); int omap_hwmod_count_resources(struct omap_hwmod *oh); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 2723f91..de3b10c 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -56,6 +56,9 @@ #define TI816X_UART2_BASE 0x48022000 #define TI816X_UART3_BASE 0x48024000 +/* AM3505/3517 UART4 */ +#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ + /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 #define ZOOM_UART_VIRT 0xfa400000 diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index ac4b60d..a067484 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -148,6 +148,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) /* omap3 based boards using UART3 */ DEBUG_LL_OMAP3(3, cm_t35); DEBUG_LL_OMAP3(3, cm_t3517); + DEBUG_LL_OMAP3(3, cm_t3730); DEBUG_LL_OMAP3(3, craneboard); DEBUG_LL_OMAP3(3, devkit8000); DEBUG_LL_OMAP3(3, igep0020); diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 83a37c5..79e7fed 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -72,7 +72,7 @@ static size_t sgtable_len(const struct sg_table *sgt) for_each_sg(sgt->sgl, sg, sgt->nents, i) { size_t bytes; - bytes = sg_dma_len(sg); + bytes = sg->length; if (!iopgsz_ok(bytes)) { pr_err("%s: sg[%d] not iommu pagesize(%x)\n", @@ -198,7 +198,7 @@ static void *vmap_sg(const struct sg_table *sgt) int err; pa = sg_phys(sg); - bytes = sg_dma_len(sg); + bytes = sg->length; BUG_ON(bytes != PAGE_SIZE); @@ -423,9 +423,6 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, { unsigned int i; struct scatterlist *sg; - void *va; - - va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { unsigned bytes; @@ -476,7 +473,7 @@ static int map_iovm_area(struct iommu *obj, struct iovm_struct *new, struct iotlb_entry e; pa = sg_phys(sg); - bytes = sg_dma_len(sg); + bytes = sg->length; flags &= ~IOVMF_PGSZ_MASK; pgsz = bytes_to_iopgsz(bytes); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 3c1fbdc..6c62af1 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -966,6 +966,33 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx) } EXPORT_SYMBOL(omap_mcbsp_stop); +/* + * The following functions are only required on an OMAP1-only build. + * mach-omap2/mcbsp.c contains the real functions + */ +#ifndef CONFIG_ARCH_OMAP2PLUS +int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) +{ + WARN(1, "%s: should never be called on an OMAP1-only kernel\n", + __func__); + return -EINVAL; +} + +void omap2_mcbsp1_mux_clkr_src(u8 mux) +{ + WARN(1, "%s: should never be called on an OMAP1-only kernel\n", + __func__); + return; +} + +void omap2_mcbsp1_mux_fsr_src(u8 mux) +{ + WARN(1, "%s: should never be called on an OMAP1-only kernel\n", + __func__); + return; +} +#endif + #ifdef CONFIG_ARCH_OMAP3 #define max_thres(m) (mcbsp->pdata->buffer_size) #define valid_threshold(m, val) ((val) <= max_thres(m)) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 3471c65..02609ee 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -236,56 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) return 0; } +static void _add_clkdev(struct omap_device *od, const char *clk_alias, + const char *clk_name) +{ + struct clk *r; + struct clk_lookup *l; + + if (!clk_alias || !clk_name) + return; + + pr_debug("omap_device: %s: Creating %s -> %s\n", + dev_name(&od->pdev.dev), clk_alias, clk_name); + + r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias); + if (!IS_ERR(r)) { + pr_warning("omap_device: %s: alias %s already exists\n", + dev_name(&od->pdev.dev), clk_alias); + clk_put(r); + return; + } + + r = omap_clk_get_by_name(clk_name); + if (IS_ERR(r)) { + pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", + dev_name(&od->pdev.dev), clk_name); + return; + } + + l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev)); + if (!l) { + pr_err("omap_device: %s: clkdev_alloc for %s failed\n", + dev_name(&od->pdev.dev), clk_alias); + return; + } + + clkdev_add(l); +} + /** - * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks + * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks + * and main clock * @od: struct omap_device *od + * @oh: struct omap_hwmod *oh * - * For every optional clock present per hwmod per omap_device, this function - * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role> - * if it does not exist already. + * For the main clock and every optional clock present per hwmod per + * omap_device, this function adds an entry in the clkdev table of the + * form <dev-id=dev_name, con-id=role> if it does not exist already. * * The function is called from inside omap_device_build_ss(), after * omap_device_register. * * This allows drivers to get a pointer to its optional clocks based on its role * by calling clk_get(<dev*>, <role>). + * In the case of the main clock, a "fck" alias is used. * * No return value. */ -static void _add_optional_clock_clkdev(struct omap_device *od, - struct omap_hwmod *oh) +static void _add_hwmod_clocks_clkdev(struct omap_device *od, + struct omap_hwmod *oh) { int i; - for (i = 0; i < oh->opt_clks_cnt; i++) { - struct omap_hwmod_opt_clk *oc; - struct clk *r; - struct clk_lookup *l; - - oc = &oh->opt_clks[i]; - - if (!oc->_clk) - continue; - - r = clk_get_sys(dev_name(&od->pdev.dev), oc->role); - if (!IS_ERR(r)) - continue; /* clkdev entry exists */ + _add_clkdev(od, "fck", oh->main_clk); - r = omap_clk_get_by_name((char *)oc->clk); - if (IS_ERR(r)) { - pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", - dev_name(&od->pdev.dev), oc->clk); - continue; - } - - l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev)); - if (!l) { - pr_err("omap_device: %s: clkdev_alloc for %s failed\n", - dev_name(&od->pdev.dev), oc->role); - return; - } - clkdev_add(l); - } + for (i = 0; i < oh->opt_clks_cnt; i++) + _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk); } @@ -492,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, for (i = 0; i < oh_cnt; i++) { hwmods[i]->od = od; - _add_optional_clock_clkdev(od, hwmods[i]); + _add_hwmod_clocks_clkdev(od, hwmods[i]); } if (ret) @@ -600,6 +615,9 @@ static int _od_resume_noirq(struct device *dev) return pm_generic_resume_noirq(dev); } +#else +#define _od_suspend_noirq NULL +#define _od_resume_noirq NULL #endif static struct dev_pm_domain omap_device_pm_domain = { @@ -607,7 +625,8 @@ static struct dev_pm_domain omap_device_pm_domain = { SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, _od_runtime_idle) USE_PLATFORM_PM_SLEEP_OPS - SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq) + .suspend_noirq = _od_suspend_noirq, + .resume_noirq = _od_resume_noirq, } }; diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index e98f5c5..9843c95 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -39,6 +39,7 @@ config S5P_GPIO_INT config S5P_HRT bool + select SAMSUNG_DEV_PWM help Use the High Resolution timer support @@ -70,6 +71,16 @@ config S5P_DEV_FIMC3 help Compile in platform device definitions for FIMC controller 3 +config S5P_DEV_FIMD0 + bool + help + Compile in platform device definitions for FIMD controller 0 + +config S5P_DEV_MFC + bool + help + Compile in platform device definitions for MFC + config S5P_DEV_ONENAND bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index e234cc4..4b53e04 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -25,11 +25,12 @@ obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_S5P_HRT) += s5p-time.o # devices - +obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o +obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 02af235..5f84a3f 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -192,7 +192,7 @@ unsigned long s5p_spdif_get_rate(struct clk *clk) if (IS_ERR(pclk)) return -EINVAL; - rate = pclk->ops->get_rate(clk); + rate = pclk->ops->get_rate(pclk); clk_put(pclk); return rate; diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c new file mode 100644 index 0000000..f728bb5 --- /dev/null +++ b/arch/arm/plat-s5p/dev-fimd0.c @@ -0,0 +1,67 @@ +/* linux/arch/arm/plat-s5p/dev-fimd0.c + * + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Core file for Samsung Display Controller (FIMD) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/gfp.h> +#include <linux/dma-mapping.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/fb.h> +#include <plat/devs.h> +#include <plat/cpu.h> + +static struct resource s5p_fimd0_resource[] = { + [0] = { + .start = S5P_PA_FIMD0, + .end = S5P_PA_FIMD0 + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FIMD0_VSYNC, + .end = IRQ_FIMD0_VSYNC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_FIMD0_FIFO, + .end = IRQ_FIMD0_FIFO, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_FIMD0_SYSTEM, + .end = IRQ_FIMD0_SYSTEM, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fimd0_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5p_device_fimd0 = { + .name = "s5p-fb", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_fimd0_resource), + .resource = s5p_fimd0_resource, + .dev = { + .dma_mask = &fimd0_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), + &s5p_device_fimd0); +} diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c new file mode 100644 index 0000000..94226a0 --- /dev/null +++ b/arch/arm/plat-s5p/dev-mfc.c @@ -0,0 +1,123 @@ +/* linux/arch/arm/plat-s5p/dev-mfc.c + * + * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd + * + * Base S5P MFC resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/memblock.h> +#include <linux/ioport.h> + +#include <mach/map.h> +#include <plat/devs.h> +#include <plat/irqs.h> +#include <plat/mfc.h> + +static struct resource s5p_mfc_resource[] = { + [0] = { + .start = S5P_PA_MFC, + .end = S5P_PA_MFC + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MFC, + .end = IRQ_MFC, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device s5p_device_mfc = { + .name = "s5p-mfc", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_mfc_resource), + .resource = s5p_mfc_resource, +}; + +/* + * MFC hardware has 2 memory interfaces which are modelled as two separate + * platform devices to let dma-mapping distinguish between them. + * + * MFC parent device (s5p_device_mfc) must be registered before memory + * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r). + */ + +static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32); + +struct platform_device s5p_device_mfc_l = { + .name = "s5p-mfc-l", + .id = -1, + .dev = { + .parent = &s5p_device_mfc.dev, + .dma_mask = &s5p_mfc_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +struct platform_device s5p_device_mfc_r = { + .name = "s5p-mfc-r", + .id = -1, + .dev = { + .parent = &s5p_device_mfc.dev, + .dma_mask = &s5p_mfc_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +struct s5p_mfc_reserved_mem { + phys_addr_t base; + unsigned long size; + struct device *dev; +}; + +static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata; + +void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, + phys_addr_t lbase, unsigned int lsize) +{ + int i; + + s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev; + s5p_mfc_mem[0].base = rbase; + s5p_mfc_mem[0].size = rsize; + + s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev; + s5p_mfc_mem[1].base = lbase; + s5p_mfc_mem[1].size = lsize; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (memblock_remove(area->base, area->size)) { + printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + area->base = 0; + } + } +} + +static int __init s5p_mfc_memory_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { + struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; + if (!area->base) + continue; + + if (dma_declare_coherent_memory(area->dev, area->base, + area->base, area->size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) + printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n", + area->size, (unsigned long) area->base); + } + return 0; +} +device_initcall(s5p_mfc_memory_init); diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index d973d39..36d3551 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -35,9 +35,10 @@ #define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) #define S5P_VA_SCU S5P_VA_COREPERI(0x0) -#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) #define S5P_VA_TWD S5P_VA_COREPERI(0x600) -#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) + +#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000) +#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000) #define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000) diff --git a/arch/arm/plat-s5p/include/plat/mfc.h b/arch/arm/plat-s5p/include/plat/mfc.h new file mode 100644 index 0000000..6697f8c --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/mfc.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * + * 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. + */ + +#ifndef __PLAT_S5P_MFC_H +#define __PLAT_S5P_MFC_H + +/** + * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver + * @rbase: base address for MFC 'right' memory interface + * @rsize: size of the memory reserved for MFC 'right' interface + * @lbase: base address for MFC 'left' memory interface + * @lsize: size of the memory reserved for MFC 'left' interface + * + * This function reserves system memory for both MFC device memory + * interfaces and registers it to respective struct device entries as + * coherent memory. + */ +void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, + phys_addr_t lbase, unsigned int lsize); + +#endif /* __PLAT_S5P_MFC_H */ diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 327ab9f..f71078e 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -23,6 +23,8 @@ #include <plat/gpio-core.h> #include <plat/gpio-cfg.h> +#include <asm/mach/irq.h> + #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) #define CON_OFFSET 0x700 @@ -81,6 +83,9 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) int group, pend_offset, mask_offset; unsigned int pend, mask; + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); + for (group = 0; group < bank->nr_groups; group++) { struct s3c_gpio_chip *chip = bank->chips[group]; if (!chip) @@ -102,6 +107,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) pend &= ~BIT(offset); } } + chained_irq_exit(chip, desc); } static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index e8f2be2..ee8deef 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -21,6 +21,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/regulator/consumer.h> #include <plat/regs-adc.h> #include <plat/adc.h> @@ -39,8 +40,9 @@ */ enum s3c_cpu_type { - TYPE_S3C24XX, - TYPE_S3C64XX + TYPE_ADCV1, /* S3C24XX */ + TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */ + TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */ }; struct s3c_adc_client { @@ -71,6 +73,7 @@ struct adc_device { unsigned int prescale; int irq; + struct regulator *vdd; }; static struct adc_device *adc_dev; @@ -91,6 +94,7 @@ static inline void s3c_adc_select(struct adc_device *adc, struct s3c_adc_client *client) { unsigned con = readl(adc->regs + S3C2410_ADCCON); + enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data; client->select_cb(client, 1); @@ -98,8 +102,12 @@ static inline void s3c_adc_select(struct adc_device *adc, con &= ~S3C2410_ADCCON_STDBM; con &= ~S3C2410_ADCCON_STARTMASK; - if (!client->is_ts) - con |= S3C2410_ADCCON_SELMUX(client->channel); + if (!client->is_ts) { + if (cpu == TYPE_ADCV3) + writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); + else + con |= S3C2410_ADCCON_SELMUX(client->channel); + } writel(con, adc->regs + S3C2410_ADCCON); } @@ -285,8 +293,8 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) client->nr_samples--; - if (cpu == TYPE_S3C64XX) { - /* S3C64XX ADC resolution is 12-bit */ + if (cpu != TYPE_ADCV1) { + /* S3C64XX/S5P ADC resolution is 12-bit */ data0 &= 0xfff; data1 &= 0xfff; } else { @@ -312,7 +320,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) } exit: - if (cpu == TYPE_S3C64XX) { + if (cpu != TYPE_ADCV1) { /* Clear ADC interrupt */ writel(0, adc->regs + S3C64XX_ADCCLRINT); } @@ -338,17 +346,24 @@ static int s3c_adc_probe(struct platform_device *pdev) adc->pdev = pdev; adc->prescale = S3C2410_ADCCON_PRSCVL(49); + adc->vdd = regulator_get(dev, "vdd"); + if (IS_ERR(adc->vdd)) { + dev_err(dev, "operating without regulator \"vdd\" .\n"); + ret = PTR_ERR(adc->vdd); + goto err_alloc; + } + adc->irq = platform_get_irq(pdev, 1); if (adc->irq <= 0) { dev_err(dev, "failed to get adc irq\n"); ret = -ENOENT; - goto err_alloc; + goto err_reg; } ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc); if (ret < 0) { dev_err(dev, "failed to attach adc irq\n"); - goto err_alloc; + goto err_reg; } adc->clk = clk_get(dev, "adc"); @@ -372,10 +387,14 @@ static int s3c_adc_probe(struct platform_device *pdev) goto err_clk; } + ret = regulator_enable(adc->vdd); + if (ret) + goto err_ioremap; + clk_enable(adc->clk); tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; - if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) { + if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) { /* Enable 12-bit ADC resolution */ tmp |= S3C64XX_ADCCON_RESSEL; } @@ -388,12 +407,15 @@ static int s3c_adc_probe(struct platform_device *pdev) return 0; + err_ioremap: + iounmap(adc->regs); err_clk: clk_put(adc->clk); err_irq: free_irq(adc->irq, adc); - + err_reg: + regulator_put(adc->vdd); err_alloc: kfree(adc); return ret; @@ -406,6 +428,8 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev) iounmap(adc->regs); free_irq(adc->irq, adc); clk_disable(adc->clk); + regulator_disable(adc->vdd); + regulator_put(adc->vdd); clk_put(adc->clk); kfree(adc); @@ -413,8 +437,10 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) +static int s3c_adc_suspend(struct device *dev) { + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); struct adc_device *adc = platform_get_drvdata(pdev); unsigned long flags; u32 con; @@ -428,19 +454,30 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) disable_irq(adc->irq); spin_unlock_irqrestore(&adc->lock, flags); clk_disable(adc->clk); + regulator_disable(adc->vdd); return 0; } -static int s3c_adc_resume(struct platform_device *pdev) +static int s3c_adc_resume(struct device *dev) { + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); struct adc_device *adc = platform_get_drvdata(pdev); + int ret; + unsigned long tmp; + ret = regulator_enable(adc->vdd); + if (ret) + return ret; clk_enable(adc->clk); enable_irq(adc->irq); - writel(adc->prescale | S3C2410_ADCCON_PRSCEN, - adc->regs + S3C2410_ADCCON); + tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; + /* Enable 12-bit ADC resolution */ + if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) + tmp |= S3C64XX_ADCCON_RESSEL; + writel(tmp, adc->regs + S3C2410_ADCCON); return 0; } @@ -453,25 +490,32 @@ static int s3c_adc_resume(struct platform_device *pdev) static struct platform_device_id s3c_adc_driver_ids[] = { { .name = "s3c24xx-adc", - .driver_data = TYPE_S3C24XX, + .driver_data = TYPE_ADCV1, }, { .name = "s3c64xx-adc", - .driver_data = TYPE_S3C64XX, + .driver_data = TYPE_ADCV2, + }, { + .name = "samsung-adc-v3", + .driver_data = TYPE_ADCV3, }, { } }; MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids); +static const struct dev_pm_ops adc_pm_ops = { + .suspend = s3c_adc_suspend, + .resume = s3c_adc_resume, +}; + static struct platform_driver s3c_adc_driver = { .id_table = s3c_adc_driver_ids, .driver = { .name = "s3c-adc", .owner = THIS_MODULE, + .pm = &adc_pm_ops, }, .probe = s3c_adc_probe, .remove = __devexit_p(s3c_adc_remove), - .suspend = s3c_adc_suspend, - .resume = s3c_adc_resume, }; static int __init adc_init(void) @@ -485,4 +529,4 @@ static int __init adc_init(void) return ret; } -arch_initcall(adc_init); +module_init(adc_init); diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c index a068c4f..97e35d3 100644 --- a/arch/arm/plat-samsung/dev-asocdma.c +++ b/arch/arm/plat-samsung/dev-asocdma.c @@ -23,3 +23,13 @@ struct platform_device samsung_asoc_dma = { } }; EXPORT_SYMBOL(samsung_asoc_dma); + +struct platform_device samsung_asoc_idma = { + .name = "samsung-idma", + .id = -1, + .dev = { + .dma_mask = &audio_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +EXPORT_SYMBOL(samsung_asoc_idma); diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h index a0826ed..aa9875f 100644 --- a/arch/arm/plat-samsung/include/plat/audio.h +++ b/arch/arm/plat-samsung/include/plat/audio.h @@ -44,6 +44,7 @@ struct samsung_i2s { * Also corresponds to clocks of I2SMOD[10] */ const char **src_clk; + dma_addr_t idma_addr; }; /** diff --git a/arch/arm/plat-samsung/include/plat/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h index 51d8da8..ad530c7 100644 --- a/arch/arm/plat-samsung/include/plat/backlight.h +++ b/arch/arm/plat-samsung/include/plat/backlight.h @@ -20,7 +20,7 @@ struct samsung_bl_gpio_info { int func; }; -extern void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, +extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, struct platform_pwm_backlight_data *bl_data); #endif /* __ASM_PLAT_BACKLIGHT_H */ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index e3b31c2..24ebb1e 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -40,6 +40,7 @@ extern struct platform_device s3c64xx_device_spi0; extern struct platform_device s3c64xx_device_spi1; extern struct platform_device samsung_asoc_dma; +extern struct platform_device samsung_asoc_idma; extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; @@ -49,6 +50,7 @@ extern struct platform_device s3c64xx_device_ac97; extern struct platform_device s3c_device_ts; extern struct platform_device s3c_device_fb; +extern struct platform_device s5p_device_fimd0; extern struct platform_device s3c_device_ohci; extern struct platform_device s3c_device_lcd; extern struct platform_device s3c_device_wdt; @@ -112,6 +114,7 @@ extern struct platform_device exynos4_device_i2s2; extern struct platform_device exynos4_device_spdif; extern struct platform_device exynos4_device_pd[]; extern struct platform_device exynos4_device_ahci; +extern struct platform_device exynos4_device_dwmci; extern struct platform_device s5p6440_device_pcm; extern struct platform_device s5p6440_device_iis; @@ -136,6 +139,9 @@ extern struct platform_device s5p_device_fimc1; extern struct platform_device s5p_device_fimc2; extern struct platform_device s5p_device_fimc3; +extern struct platform_device s5p_device_mfc; +extern struct platform_device s5p_device_mfc_l; +extern struct platform_device s5p_device_mfc_r; extern struct platform_device s5p_device_mipi_csis0; extern struct platform_device s5p_device_mipi_csis1; diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h index bca383e..6abcbf1 100644 --- a/arch/arm/plat-samsung/include/plat/fb-core.h +++ b/arch/arm/plat-samsung/include/plat/fb-core.h @@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name) #endif } +/* Re-define device name depending on support. */ +static inline void s5p_fb_setname(int id, char *name) +{ + switch (id) { +#ifdef CONFIG_S5P_DEV_FIMD0 + case 0: + s5p_device_fimd0.name = name; + break; +#endif + default: + printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id); + break; + } +} + #endif /* __ASM_PLAT_FB_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h index cb3ca3a..01f10e4 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/plat-samsung/include/plat/fb.h @@ -74,6 +74,14 @@ struct s3c_fb_platdata { extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd); /** + * s5p_fimd0_set_platdata() - Setup the FB device with platform data. + * @pd: The platform data to set. The data is copied from the passed structure + * so the machine data can mark the data __initdata so that any unused + * machines will end up dumping their data at runtime. + */ +extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd); + +/** * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD * * Initialise the GPIO for an 24bpp LCD display on the RGB interface. @@ -94,4 +102,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void); */ extern void s5pv210_fb_gpio_setup_24bpp(void); +/** + * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0 + * + * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0. + */ +extern void exynos4_fimd0_gpio_setup_24bpp(void); + #endif /* __PLAT_S3C_FB_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h index 7554c4f..035e8c3 100644 --- a/arch/arm/plat-samsung/include/plat/regs-adc.h +++ b/arch/arm/plat-samsung/include/plat/regs-adc.h @@ -21,6 +21,7 @@ #define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) #define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) #define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) +#define S5P_ADCMUX S3C2410_ADCREG(0x1C) #define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 657405c..3014c72 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c @@ -19,6 +19,8 @@ #include <linux/irq.h> #include <linux/io.h> +#include <asm/mach/irq.h> + #include <mach/map.h> #include <plat/irq-uart.h> #include <plat/regs-serial.h> @@ -30,9 +32,12 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) { struct s3c_uart_irq *uirq = desc->irq_data.handler_data; + struct irq_chip *chip = irq_get_chip(irq); u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); int base = uirq->base_irq; + chained_irq_enter(chip, desc); + if (pend & (1 << 0)) generic_handle_irq(base); if (pend & (1 << 1)) @@ -41,6 +46,8 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) generic_handle_irq(base + 2); if (pend & (1 << 3)) generic_handle_irq(base + 3); + + chained_irq_exit(chip, desc); } static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index f714d06..51583cd 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -22,9 +22,14 @@ #include <plat/irq-vic-timer.h> #include <plat/regs-timer.h> +#include <asm/mach/irq.h> + static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) { + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); generic_handle_irq((int)desc->irq_data.handler_data); + chained_irq_exit(chip, desc); } /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 5fa1742..ae6f998 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -269,6 +269,7 @@ static int s3c_pm_enter(suspend_state_t state) /* save all necessary core registers not covered by the drivers */ s3c_pm_save_gpios(); + s3c_pm_saved_gpios(); s3c_pm_save_uarts(); s3c_pm_save_core(); @@ -306,6 +307,7 @@ static int s3c_pm_enter(suspend_state_t state) s3c_pm_restore_core(); s3c_pm_restore_uarts(); s3c_pm_restore_gpios(); + s3c_pm_restored_gpios(); s3c_pm_debug_init(); diff --git a/arch/arm/plat-spear/include/plat/clkdev.h b/arch/arm/plat-spear/include/plat/clkdev.h deleted file mode 100644 index a2d0112..0000000 --- a/arch/arm/plat-spear/include/plat/clkdev.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/clkdev.h - * - * Clock Dev framework definitions for SPEAr platform - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_CLKDEV_H -#define __PLAT_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif /* __PLAT_CLKDEV_H */ diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h deleted file mode 100644 index 04b37a8..0000000 --- a/arch/arm/plat-tcc/include/mach/clkdev.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_CLKDEV_H -#define __ASM_MACH_CLKDEV_H - -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) - -#endif diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 3b3776d..62cc8f9 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -351,7 +351,7 @@ centro MACH_CENTRO CENTRO 1944 nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955 omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967 cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 -eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 +eukrea_cpuimx27 MACH_EUKREA_CPUIMX27 EUKREA_CPUIMX27 1975 acs5k MACH_ACS5K ACS5K 1982 snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987 dsm320 MACH_DSM320 DSM320 1988 @@ -476,8 +476,8 @@ cns3420vb MACH_CNS3420VB CNS3420VB 2776 omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 ti8168evm MACH_TI8168EVM TI8168EVM 2800 teton_bga MACH_TETON_BGA TETON_BGA 2816 -eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820 -eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821 +eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25SD EUKREA_CPUIMX25SD 2820 +eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821 eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 smdkc210 MACH_SMDKC210 SMDKC210 2838 @@ -910,7 +910,7 @@ omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280 uemd MACH_UEMD UEMD 3281 ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282 rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283 -nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284 +encore MACH_ENCORE ENCORE 3284 hkdkc100 MACH_HKDKC100 HKDKC100 3285 ts42xx MACH_TS42XX TS42XX 3286 aebl MACH_AEBL AEBL 3287 diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index e9d689b..197e96f 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -10,6 +10,7 @@ config AVR32 select GENERIC_IRQ_PROBE select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW + select ARCH_HAVE_NMI_SAFE_CMPXCHG help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h index bbce6a1c..e0ac263 100644 --- a/arch/avr32/include/asm/atomic.h +++ b/arch/avr32/include/asm/atomic.h @@ -78,70 +78,63 @@ static inline int atomic_add_return(int i, atomic_t *v) /* * atomic_sub_unless - sub unless the number is a given value * @v: pointer of type atomic_t - * @a: the amount to add to v... + * @a: the amount to subtract from v... * @u: ...unless v is equal to u. * - * If the atomic value v is not equal to u, this function subtracts a - * from v, and returns non zero. If v is equal to u then it returns - * zero. This is done as an atomic operation. + * Atomically subtract @a from @v, so long as it was not @u. + * Returns the old value of @v. */ -static inline int atomic_sub_unless(atomic_t *v, int a, int u) +static inline void atomic_sub_unless(atomic_t *v, int a, int u) { - int tmp, result = 0; + int tmp; asm volatile( "/* atomic_sub_unless */\n" "1: ssrf 5\n" - " ld.w %0, %3\n" - " cp.w %0, %5\n" + " ld.w %0, %2\n" + " cp.w %0, %4\n" " breq 1f\n" - " sub %0, %4\n" - " stcond %2, %0\n" + " sub %0, %3\n" + " stcond %1, %0\n" " brne 1b\n" - " mov %1, 1\n" "1:" - : "=&r"(tmp), "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(a), "rKs21"(u), "1"(result) + : "=&r"(tmp), "=o"(v->counter) + : "m"(v->counter), "rKs21"(a), "rKs21"(u) : "cc", "memory"); - - return result; } /* - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * - * If the atomic value v is not equal to u, this function adds a to v, - * and returns non zero. If v is equal to u then it returns zero. This - * is done as an atomic operation. + * Atomically adds @a to @v, so long as it was not @u. + * Returns the old value of @v. */ -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { - int tmp, result; + int tmp, old = atomic_read(v); if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) - result = atomic_sub_unless(v, -a, u); + atomic_sub_unless(v, -a, u); else { - result = 0; asm volatile( - "/* atomic_add_unless */\n" + "/* __atomic_add_unless */\n" "1: ssrf 5\n" - " ld.w %0, %3\n" - " cp.w %0, %5\n" + " ld.w %0, %2\n" + " cp.w %0, %4\n" " breq 1f\n" - " add %0, %4\n" - " stcond %2, %0\n" + " add %0, %3\n" + " stcond %1, %0\n" " brne 1b\n" - " mov %1, 1\n" "1:" - : "=&r"(tmp), "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "r"(a), "ir"(u), "1"(result) + : "=&r"(tmp), "=o"(v->counter) + : "m"(v->counter), "r"(a), "ir"(u) : "cc", "memory"); } - return result; + return old; } /* @@ -188,7 +181,6 @@ static inline int atomic_sub_if_positive(int i, atomic_t *v) #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) #define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0) -#define atomic_inc_not_zero(v) atomic_add_unless(v, 1, 0) #define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) #define smp_mb__before_atomic_dec() barrier() @@ -196,6 +188,4 @@ static inline int atomic_sub_if_positive(int i, atomic_t *v) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> - #endif /* __ASM_AVR32_ATOMIC_H */ diff --git a/arch/avr32/include/asm/ptrace.h b/arch/avr32/include/asm/ptrace.h index e53dd0d..c67a007 100644 --- a/arch/avr32/include/asm/ptrace.h +++ b/arch/avr32/include/asm/ptrace.h @@ -132,8 +132,6 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs (struct pt_regs *); - static __inline__ int valid_user_regs(struct pt_regs *regs) { /* diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index c7fd394..6eba535 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S @@ -158,7 +158,7 @@ sys_call_table: .long sys_sched_rr_get_interval .long sys_nanosleep .long sys_poll - .long sys_nfsservctl /* 145 */ + .long sys_ni_syscall /* 145 was nfsservctl */ .long sys_setresgid .long sys_getresgid .long sys_prctl diff --git a/arch/blackfin/include/asm/atomic.h b/arch/blackfin/include/asm/atomic.h index 4c707db..1352256 100644 --- a/arch/blackfin/include/asm/atomic.h +++ b/arch/blackfin/include/asm/atomic.h @@ -89,15 +89,14 @@ static inline void atomic_set_mask(int mask, atomic_t *v) #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -#define atomic_add_unless(v, a, u) \ +#define __atomic_add_unless(v, a, u) \ ({ \ int c, old; \ c = atomic_read(v); \ while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ c = old; \ - c != (u); \ + c; \ }) -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* * atomic_inc_and_test - increment and test @@ -112,10 +111,7 @@ static inline void atomic_set_mask(int mask, atomic_t *v) #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#include <asm-generic/atomic-long.h> #endif -#include <asm-generic/atomic64.h> - #endif diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index d9dbc1a..dac0c97 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -10,7 +10,7 @@ #include <linux/interrupt.h> #include <mach/dma.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/blackfin.h> #include <asm/page.h> #include <asm-generic/dma.h> diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h index 9e0cc0e..17b5e92 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h @@ -32,7 +32,7 @@ #include <asm/ptrace.h> #include <asm/irq.h> #include <asm/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/traps.h> #include <asm/bitsperlong.h> diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h index 7854d43..10d8641 100644 --- a/arch/blackfin/include/asm/ptrace.h +++ b/arch/blackfin/include/asm/ptrace.h @@ -102,7 +102,6 @@ struct pt_regs { /* user_mode returns true if only one bit is set in IPEND, other than the master interrupt enable. */ #define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1))) -extern void show_regs(struct pt_regs *); #define arch_has_single_step() (1) /* common code demands this function */ diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index 2336093..490c7ca 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -11,7 +11,7 @@ # include <asm-generic/spinlock.h> #else -#include <asm/atomic.h> +#include <linux/atomic.h> asmlinkage int __raw_spin_is_locked_asm(volatile int *ptr); asmlinkage void __raw_spin_lock_asm(volatile int *ptr); diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c index 48808a1..9277905 100644 --- a/arch/blackfin/kernel/ftrace.c +++ b/arch/blackfin/kernel/ftrace.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/uaccess.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #ifdef CONFIG_DYNAMIC_FTRACE diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 486426f..dbe1122 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -32,7 +32,7 @@ #include <linux/unistd.h> #include <linux/io.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq_handler.h> DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c index 679d0db..9919d29 100644 --- a/arch/blackfin/kernel/nmi.c +++ b/arch/blackfin/kernel/nmi.c @@ -18,7 +18,7 @@ #include <linux/smp.h> #include <linux/timer.h> #include <asm/blackfin.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/bfin_watchdog.h> diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 225d311..e413729 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -1543,7 +1543,7 @@ ENTRY(_sys_call_table) .long _sys_ni_syscall /* for vm86 */ .long _sys_ni_syscall /* old "query_module" */ .long _sys_ni_syscall /* sys_poll */ - .long _sys_nfsservctl + .long _sys_ni_syscall /* old nfsservctl */ .long _sys_setresgid /* setresgid16 */ /* 170 */ .long _sys_getresgid /* getresgid16 */ .long _sys_prctl diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 1c143a4..107622a 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -23,7 +23,7 @@ #include <linux/seq_file.h> #include <linux/irq.h> #include <linux/slab.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/irq_handler.h> #include <asm/mmu_context.h> diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 85026537..466af40 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); static int sync_serial_release(struct inode *inode, struct file *file); static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); -static int sync_serial_ioctl(struct file *file, +static long sync_serial_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file *file, const char *buf, size_t count, loff_t *ppos); @@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - ret = 0; + err = 0; out: mutex_unlock(&sync_serial_mutex); - return ret; + return err; } static int sync_serial_release(struct inode *inode, struct file *file) diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 1161883..592fbe9 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S @@ -771,7 +771,7 @@ sys_call_table: .long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 907cfb5..ba0e596 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -20,6 +20,9 @@ #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); +extern void kgdb_init(void); +extern void breakpoint(void); + /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. */ diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index c03bc3b..642c6fe 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -16,7 +16,7 @@ #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/list.h> #include <linux/interrupt.h> diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 84fed7e..c3ea4694 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -714,7 +714,7 @@ sys_call_table: .long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* Old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index a0843a7..0b99df7 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -7,7 +7,7 @@ #include <asm/mmu_context.h> #include <hwregs/asm/mmu_defs_asm.h> #include <hwregs/supp_reg.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/err.h> #include <linux/init.h> diff --git a/arch/cris/include/arch-v10/arch/ptrace.h b/arch/cris/include/arch-v10/arch/ptrace.h index 2f464ea..1a23273 100644 --- a/arch/cris/include/arch-v10/arch/ptrace.h +++ b/arch/cris/include/arch-v10/arch/ptrace.h @@ -112,7 +112,6 @@ struct switch_stack { #define user_mode(regs) (((regs)->dccr & 0x100) != 0) #define instruction_pointer(regs) ((regs)->irp) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); #endif /* __KERNEL__ */ diff --git a/arch/cris/include/arch-v32/arch/ptrace.h b/arch/cris/include/arch-v32/arch/ptrace.h index ffca8d0..19773d3 100644 --- a/arch/cris/include/arch-v32/arch/ptrace.h +++ b/arch/cris/include/arch-v32/arch/ptrace.h @@ -111,7 +111,6 @@ struct switch_stack { #define arch_has_single_step() (1) #define user_mode(regs) (((regs)->ccs & (1 << (U_CCS_BITNR + CCS_SHIFT))) != 0) #define instruction_pointer(regs) ((regs)->erp) -extern void show_regs(struct pt_regs *); #define profile_pc(regs) instruction_pointer(regs) #endif /* __KERNEL__ */ diff --git a/arch/cris/include/asm/atomic.h b/arch/cris/include/asm/atomic.h index 88dc9b9..bbf09381 100644 --- a/arch/cris/include/asm/atomic.h +++ b/arch/cris/include/asm/atomic.h @@ -138,7 +138,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int ret; unsigned long flags; @@ -148,9 +148,8 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) if (ret != u) v->counter += a; cris_atomic_restore(v, flags); - return ret != u; + return ret; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() @@ -158,5 +157,4 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h index 310e0de..a78a2d7 100644 --- a/arch/cris/include/asm/bitops.h +++ b/arch/cris/include/asm/bitops.h @@ -20,7 +20,7 @@ #include <arch/bitops.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/compiler.h> /* @@ -156,8 +156,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) -#define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/sched.h> diff --git a/arch/cris/include/asm/serial.h b/arch/cris/include/asm/serial.h new file mode 100644 index 0000000..af7535a --- /dev/null +++ b/arch/cris/include/asm/serial.h @@ -0,0 +1,9 @@ +#ifndef _ASM_SERIAL_H +#define _ASM_SERIAL_H + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + */ +#define BASE_BAUD (1843200 / 16) + +#endif /* _ASM_SERIAL_H */ diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index 29b74a1..332f19c 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h @@ -11,8 +11,6 @@ #ifdef __KERNEL__ -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR - #ifndef __ASSEMBLY__ #include <asm/types.h> #include <asm/processor.h> @@ -67,8 +65,10 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR /* thread information allocation */ -#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) +#define alloc_thread_info_node(tsk, node) \ + ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* !__ASSEMBLY__ */ diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index c99aeab..aa585e4 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -12,7 +12,7 @@ * This file handles the architecture-dependent parts of process handling.. */ -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/irq.h> diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index cb884e4..bad27a6 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -7,6 +7,7 @@ config FRV select HAVE_PERF_EVENTS select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW + select ARCH_HAVE_NMI_SAFE_CMPXCHG config ZONE_DMA bool diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h index fae32c7f..0d8a7d6 100644 --- a/arch/frv/include/asm/atomic.h +++ b/arch/frv/include/asm/atomic.h @@ -241,7 +241,7 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter)) #define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter)) -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -253,10 +253,8 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) -#include <asm-generic/atomic-long.h> #endif /* _ASM_ATOMIC_H */ diff --git a/arch/frv/include/asm/bitops.h b/arch/frv/include/asm/bitops.h index a1d00b0..57bf85d 100644 --- a/arch/frv/include/asm/bitops.h +++ b/arch/frv/include/asm/bitops.h @@ -403,8 +403,7 @@ int __ilog2_u64(u64 n) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit ((nr) ^ 0x18, (addr)) -#define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr) ^ 0x18, (addr)) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/frv/include/asm/hardirq.h b/arch/frv/include/asm/hardirq.h index 5fc8b6f..c62833d 100644 --- a/arch/frv/include/asm/hardirq.h +++ b/arch/frv/include/asm/hardirq.h @@ -12,7 +12,7 @@ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H -#include <asm/atomic.h> +#include <linux/atomic.h> extern atomic_t irq_err_count; static inline void ack_bad_irq(int irq) diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index 4b789ab..81c2e27 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -97,7 +97,6 @@ extern struct task_struct *__kernel_current_task; */ #define start_thread(_regs, _pc, _usp) \ do { \ - set_fs(USER_DS); /* reads from user space */ \ __frame = __kernel_frame0_ptr; \ __frame->pc = (_pc); \ __frame->psr &= ~PSR_S; \ diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h index 6bfad4c..ef6635c 100644 --- a/arch/frv/include/asm/ptrace.h +++ b/arch/frv/include/asm/ptrace.h @@ -78,7 +78,6 @@ register struct pt_regs *__frame asm("gr28"); #define user_stack_pointer(regs) ((regs)->sp) extern unsigned long user_stack(const struct pt_regs *); -extern void show_regs(struct pt_regs *); #define profile_pc(regs) ((regs)->pc) #define task_pt_regs(task) ((task)->thread.frame0) diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 017d6d7..5ba23f7 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1358,7 +1358,7 @@ sys_call_table: .long sys_ni_syscall /* for vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* Old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index a5f624a..3facbc2 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c @@ -25,7 +25,7 @@ #include <linux/module.h> #include <linux/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/io.h> #include <asm/smp.h> #include <asm/system.h> diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 9d35975..3901df1 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c @@ -143,10 +143,7 @@ void machine_power_off(void) void flush_thread(void) { -#if 0 //ndef NO_FPU - unsigned long zero = 0; -#endif - set_fs(USER_DS); + /* nothing */ } inline unsigned long user_stack(const struct pt_regs *regs) diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index c42c83d..4fb63a3 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c @@ -133,13 +133,7 @@ void pgd_dtor(void *pgd) pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *pgd; - - pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); - if (!pgd) - return pgd; - - return pgd; + return quicklist_alloc(0, GFP_KERNEL, pgd_ctor); } void pgd_free(struct mm_struct *mm, pgd_t *pgd) diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h index 984221a..f5a38c1 100644 --- a/arch/h8300/include/asm/atomic.h +++ b/arch/h8300/include/asm/atomic.h @@ -104,7 +104,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int ret; unsigned long flags; @@ -114,9 +114,8 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) if (ret != u) v->counter += a; local_irq_restore(flags); - return ret != u; + return ret; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) { @@ -146,5 +145,4 @@ static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif /* __ARCH_H8300_ATOMIC __ */ diff --git a/arch/h8300/include/asm/posix_types.h b/arch/h8300/include/asm/posix_types.h index 5c55392..6f833a1 100644 --- a/arch/h8300/include/asm/posix_types.h +++ b/arch/h8300/include/asm/posix_types.h @@ -50,7 +50,7 @@ typedef struct { #define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) #undef __FD_ISSET -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) #undef __FD_ZERO #define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h index d866c0e..d09c440 100644 --- a/arch/h8300/include/asm/ptrace.h +++ b/arch/h8300/include/asm/ptrace.h @@ -60,7 +60,6 @@ struct pt_regs { #define user_mode(regs) (!((regs)->ccr & PS_S)) #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _H8300_PTRACE_H */ diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S index f4b2e67..4be2ea2 100644 --- a/arch/h8300/kernel/syscalls.S +++ b/arch/h8300/kernel/syscalls.S @@ -183,7 +183,7 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */ .long SYMBOL_NAME(sys_poll) - .long SYMBOL_NAME(sys_nfsservctl) + .long SYMBOL_NAME(sys_ni_syscall) /* old nfsservctl */ .long SYMBOL_NAME(sys_setresgid16) /* 170 */ .long SYMBOL_NAME(sys_getresgid16) .long SYMBOL_NAME(sys_prctl) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 137b277..3ff7785 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -27,6 +27,8 @@ config IA64 select GENERIC_PENDING_IRQ if SMP select IRQ_PER_CPU select GENERIC_IRQ_SHOW + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_HAVE_NMI_SAFE_CMPXCHG default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -89,6 +91,9 @@ config GENERIC_TIME_VSYSCALL config HAVE_SETUP_PER_CPU_AREA def_bool y +config GENERIC_GPIO + def_bool y + config DMI bool default y @@ -157,7 +162,6 @@ config IA64_GENERIC select ACPI_NUMA select SWIOTLB select PCI_MSI - select DMAR help This selects the system type of your hardware. A "generic" kernel will run on any supported IA-64 system. However, if you configure diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 1d7bca0..0e5cd14 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -234,3 +234,4 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y CONFIG_MISC_DEVICES=y +CONFIG_DMAR=y diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 4468814..3fad89e 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -90,7 +90,7 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -102,10 +102,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) static __inline__ long atomic64_add_unless(atomic64_t *v, long a, long u) { @@ -216,5 +215,4 @@ atomic64_add_negative (__s64 i, atomic64_t *v) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif /* _ASM_IA64_ATOMIC_H */ diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h index b76f7e0..8e20bff 100644 --- a/arch/ia64/include/asm/bitops.h +++ b/arch/ia64/include/asm/bitops.h @@ -458,8 +458,7 @@ static __inline__ unsigned long __arch_hweight64(unsigned long x) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) -#define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/sched.h> diff --git a/arch/ia64/include/asm/gpio.h b/arch/ia64/include/asm/gpio.h new file mode 100644 index 0000000..590a20d --- /dev/null +++ b/arch/ia64/include/asm/gpio.h @@ -0,0 +1,55 @@ +/* + * Generic GPIO API implementation for IA-64. + * + * A stright copy of that for PowerPC which was: + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.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. + */ + +#ifndef _ASM_IA64_GPIO_H +#define _ASM_IA64_GPIO_H + +#include <linux/errno.h> +#include <asm-generic/gpio.h> + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ + return __gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ASM_IA64_GPIO_H */ diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 03afe79..d9f397f 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -75,7 +75,7 @@ #include <asm/percpu.h> #include <asm/rse.h> #include <asm/unwind.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #ifdef CONFIG_NUMA #include <asm/nodedata.h> #endif diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h index 7ae9c3f..f5cb276 100644 --- a/arch/ia64/include/asm/ptrace.h +++ b/arch/ia64/include/asm/ptrace.h @@ -286,7 +286,6 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs) struct task_struct; /* forward decl */ struct unw_frame_info; /* forward decl */ - extern void show_regs (struct pt_regs *); extern void ia64_do_show_stack (struct unw_frame_info *, void *); extern unsigned long ia64_get_user_rbs_end (struct task_struct *, struct pt_regs *, unsigned long *); diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index 1a91c91..b77768d 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -13,7 +13,7 @@ #include <linux/kernel.h> #include <linux/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/intrinsics.h> #include <asm/system.h> diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 6fc03af..c38d22e 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -156,7 +156,7 @@ prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, \ #define STUB_SET_VARIABLE(prefix, adjust_arg) \ static efi_status_t \ prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \ - unsigned long attr, unsigned long data_size, \ + u32 attr, unsigned long data_size, \ void *data) \ { \ struct ia64_fpreg fr[6]; \ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 97dd2ab..198c753 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1614,7 +1614,7 @@ sys_call_table: data8 sys_sched_get_priority_min data8 sys_sched_rr_get_interval data8 sys_nanosleep - data8 sys_nfsservctl + data8 sys_ni_syscall // old nfsservctl data8 sys_prctl // 1170 data8 sys_getpagesize data8 sys_mmap2 diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index be450a3..0bd537b 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -32,7 +32,7 @@ #include <linux/bitops.h> #include <linux/kexec.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/current.h> #include <asm/delay.h> #include <asm/machvec.h> diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 14ec641..5590979 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -40,7 +40,7 @@ #include <linux/percpu.h> #include <linux/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cache.h> #include <asm/current.h> #include <asm/delay.h> diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index c4696d2..6a867dc 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -25,7 +25,7 @@ #include <asm/pal.h> #include <asm/system.h> #include <asm/pgtable.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/tlbflush.h> #include <asm/sn/arch.h> diff --git a/arch/m32r/include/asm/atomic.h b/arch/m32r/include/asm/atomic.h index d44a51e..1e7f29f 100644 --- a/arch/m32r/include/asm/atomic.h +++ b/arch/m32r/include/asm/atomic.h @@ -239,15 +239,15 @@ static __inline__ int atomic_dec_return(atomic_t *v) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -259,10 +259,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr) { @@ -314,5 +313,4 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t *addr) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif /* _ASM_M32R_ATOMIC_H */ diff --git a/arch/m32r/include/asm/mmu_context.h b/arch/m32r/include/asm/mmu_context.h index a70a3df..a979a41 100644 --- a/arch/m32r/include/asm/mmu_context.h +++ b/arch/m32r/include/asm/mmu_context.h @@ -11,7 +11,7 @@ #ifndef __ASSEMBLY__ -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pgalloc.h> #include <asm/mmu.h> #include <asm/tlbflush.h> diff --git a/arch/m32r/include/asm/ptrace.h b/arch/m32r/include/asm/ptrace.h index 840a123..5275275 100644 --- a/arch/m32r/include/asm/ptrace.h +++ b/arch/m32r/include/asm/ptrace.h @@ -138,8 +138,6 @@ extern void init_debug_traps(struct task_struct *); #define instruction_pointer(regs) ((regs)->bpc) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); - extern void withdraw_debug_trap(struct pt_regs *regs); #define task_pt_regs(task) \ diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 179a064..b0ea2f2 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -10,7 +10,7 @@ */ #include <linux/compiler.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/page.h> /* diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index 092d40a..ce7aea3 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c @@ -26,7 +26,7 @@ #include <asm/cacheflush.h> #include <asm/pgalloc.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/io.h> #include <asm/mmu_context.h> #include <asm/m32r.h> diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S index 528f2e6..f365c19 100644 --- a/arch/m32r/kernel/syscall_table.S +++ b/arch/m32r/kernel/syscall_table.S @@ -168,7 +168,7 @@ ENTRY(sys_call_table) .long sys_tas /* vm86 syscall holder */ .long sys_ni_syscall /* query_module syscall holder */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* was nfsservctl */ .long sys_setresgid /* 170 */ .long sys_getresgid .long sys_prctl diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index fbd1090..ee6a919 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c @@ -21,7 +21,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 284cd37..9e8ee9d 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -6,6 +6,7 @@ config M68K select GENERIC_ATOMIC64 if MMU select HAVE_GENERIC_HARDIRQS if !MMU select GENERIC_IRQ_SHOW if !MMU + select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS config RWSEM_GENERIC_SPINLOCK bool diff --git a/arch/m68k/Kconfig.mmu b/arch/m68k/Kconfig.mmu index 16539b1..13e20bb 100644 --- a/arch/m68k/Kconfig.mmu +++ b/arch/m68k/Kconfig.mmu @@ -372,12 +372,6 @@ config AMIGA_PCMCIA Include support in the kernel for pcmcia on Amiga 1200 and Amiga 600. If you intend to use pcmcia cards say Y; otherwise say N. -config STRAM_PROC - bool "ST-RAM statistics in /proc" - depends on ATARI - help - Say Y here to report ST-RAM usage statistics in /proc/stram. - config HEARTBEAT bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index dd0447d..99449fb 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -16,6 +16,7 @@ #include <linux/string.h> #include <linux/module.h> +#include <asm/atomic.h> #include <asm/page.h> #include <asm/amigahw.h> @@ -23,111 +24,100 @@ unsigned long amiga_chip_size; EXPORT_SYMBOL(amiga_chip_size); static struct resource chipram_res = { - .name = "Chip RAM", .start = CHIP_PHYSADDR + .name = "Chip RAM", .start = CHIP_PHYSADDR }; -static unsigned long chipavail; +static atomic_t chipavail; void __init amiga_chip_init(void) { - if (!AMIGAHW_PRESENT(CHIP_RAM)) - return; + if (!AMIGAHW_PRESENT(CHIP_RAM)) + return; - chipram_res.end = amiga_chip_size-1; - request_resource(&iomem_resource, &chipram_res); + chipram_res.end = CHIP_PHYSADDR + amiga_chip_size - 1; + request_resource(&iomem_resource, &chipram_res); - chipavail = amiga_chip_size; + atomic_set(&chipavail, amiga_chip_size); } void *amiga_chip_alloc(unsigned long size, const char *name) { - struct resource *res; + struct resource *res; + void *p; - /* round up */ - size = PAGE_ALIGN(size); + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + if (!res) + return NULL; -#ifdef DEBUG - printk("amiga_chip_alloc: allocate %ld bytes\n", size); -#endif - res = kzalloc(sizeof(struct resource), GFP_KERNEL); - if (!res) - return NULL; - res->name = name; + res->name = name; + p = amiga_chip_alloc_res(size, res); + if (!p) { + kfree(res); + return NULL; + } - if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) { - kfree(res); - return NULL; - } - chipavail -= size; -#ifdef DEBUG - printk("amiga_chip_alloc: returning %lx\n", res->start); -#endif - return (void *)ZTWO_VADDR(res->start); + return p; } EXPORT_SYMBOL(amiga_chip_alloc); - /* - * Warning: - * amiga_chip_alloc_res is meant only for drivers that need to allocate - * Chip RAM before kmalloc() is functional. As a consequence, those - * drivers must not free that Chip RAM afterwards. - */ + /* + * Warning: + * amiga_chip_alloc_res is meant only for drivers that need to + * allocate Chip RAM before kmalloc() is functional. As a consequence, + * those drivers must not free that Chip RAM afterwards. + */ -void * __init amiga_chip_alloc_res(unsigned long size, struct resource *res) +void *amiga_chip_alloc_res(unsigned long size, struct resource *res) { - unsigned long start; - - /* round up */ - size = PAGE_ALIGN(size); - /* dmesg into chipmem prefers memory at the safe end */ - start = CHIP_PHYSADDR + chipavail - size; - -#ifdef DEBUG - printk("amiga_chip_alloc_res: allocate %ld bytes\n", size); -#endif - if (allocate_resource(&chipram_res, res, size, start, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) { - printk("amiga_chip_alloc_res: first alloc failed!\n"); - if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) - return NULL; - } - chipavail -= size; -#ifdef DEBUG - printk("amiga_chip_alloc_res: returning %lx\n", res->start); -#endif - return (void *)ZTWO_VADDR(res->start); + int error; + + /* round up */ + size = PAGE_ALIGN(size); + + pr_debug("amiga_chip_alloc_res: allocate %lu bytes\n", size); + error = allocate_resource(&chipram_res, res, size, 0, UINT_MAX, + PAGE_SIZE, NULL, NULL); + if (error < 0) { + pr_err("amiga_chip_alloc_res: allocate_resource() failed %d!\n", + error); + return NULL; + } + + atomic_sub(size, &chipavail); + pr_debug("amiga_chip_alloc_res: returning %pR\n", res); + return (void *)ZTWO_VADDR(res->start); } void amiga_chip_free(void *ptr) { - unsigned long start = ZTWO_PADDR(ptr); - struct resource **p, *res; - unsigned long size; - - for (p = &chipram_res.child; (res = *p); p = &res->sibling) { - if (res->start != start) - continue; - *p = res->sibling; - size = res->end-start; -#ifdef DEBUG - printk("amiga_chip_free: free %ld bytes at %p\n", size, ptr); -#endif - chipavail += size; + unsigned long start = ZTWO_PADDR(ptr); + struct resource *res; + unsigned long size; + + res = lookup_resource(&chipram_res, start); + if (!res) { + pr_err("amiga_chip_free: trying to free nonexistent region at " + "%p\n", ptr); + return; + } + + size = resource_size(res); + pr_debug("amiga_chip_free: free %lu bytes at %p\n", size, ptr); + atomic_add(size, &chipavail); + release_resource(res); kfree(res); - return; - } - printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr); } EXPORT_SYMBOL(amiga_chip_free); unsigned long amiga_chip_avail(void) { -#ifdef DEBUG - printk("amiga_chip_avail : %ld bytes\n", chipavail); -#endif - return chipavail; + unsigned long n = atomic_read(&chipavail); + + pr_debug("amiga_chip_avail : %lu bytes\n", n); + return n; } EXPORT_SYMBOL(amiga_chip_avail); diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index 6ec3b7f..0810c8d 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -1,5 +1,5 @@ /* - * arch/m68k/atari/stram.c: Functions for ST-RAM allocations + * Functions for ST-RAM allocations * * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> * @@ -30,91 +30,35 @@ #include <asm/atari_stram.h> #include <asm/io.h> -#undef DEBUG - -#ifdef DEBUG -#define DPRINTK(fmt,args...) printk( fmt, ##args ) -#else -#define DPRINTK(fmt,args...) -#endif - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC) -/* abbrev for the && above... */ -#define DO_PROC -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#endif /* - * ++roman: - * - * New version of ST-Ram buffer allocation. Instead of using the - * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000 - * (1 MB granularity!), such buffers are reserved like this: - * - * - If the kernel resides in ST-Ram anyway, we can take the buffer - * from behind the current kernel data space the normal way - * (incrementing start_mem). - * - * - If the kernel is in TT-Ram, stram_init() initializes start and - * end of the available region. Buffers are allocated from there - * and mem_init() later marks the such used pages as reserved. - * Since each TT-Ram chunk is at least 4 MB in size, I hope there - * won't be an overrun of the ST-Ram region by normal kernel data - * space. - * - * For that, ST-Ram may only be allocated while kernel initialization - * is going on, or exactly: before mem_init() is called. There is also - * no provision now for freeing ST-Ram buffers. It seems that isn't - * really needed. - * + * The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of + * configurable size, set aside on ST-RAM init. + * As long as this pool is not exhausted, allocation of real ST-RAM can be + * guaranteed. */ -/* Start and end (virtual) of ST-RAM */ -static void *stram_start, *stram_end; - -/* set after memory_init() executed and allocations via start_mem aren't - * possible anymore */ -static int mem_init_done; - /* set if kernel is in ST-RAM */ static int kernel_in_stram; -typedef struct stram_block { - struct stram_block *next; - void *start; - unsigned long size; - unsigned flags; - const char *owner; -} BLOCK; - -/* values for flags field */ -#define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */ -#define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */ -#define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */ +static struct resource stram_pool = { + .name = "ST-RAM Pool" +}; -/* list of allocated blocks */ -static BLOCK *alloc_list; +static unsigned long pool_size = 1024*1024; -/* We can't always use kmalloc() to allocate BLOCK structures, since - * stram_alloc() can be called rather early. So we need some pool of - * statically allocated structures. 20 of them is more than enough, so in most - * cases we never should need to call kmalloc(). */ -#define N_STATIC_BLOCKS 20 -static BLOCK static_blocks[N_STATIC_BLOCKS]; -/***************************** Prototypes *****************************/ +static int __init atari_stram_setup(char *arg) +{ + if (!MACH_IS_ATARI) + return 0; -static BLOCK *add_region( void *addr, unsigned long size ); -static BLOCK *find_region( void *addr ); -static int remove_region( BLOCK *block ); + pool_size = memparse(arg, NULL); + return 0; +} -/************************* End of Prototypes **************************/ +early_param("stram_pool", atari_stram_setup); - -/* ------------------------------------------------------------------------ */ -/* Public Interface */ -/* ------------------------------------------------------------------------ */ /* * This init function is called very early by atari/config.c @@ -123,25 +67,23 @@ static int remove_region( BLOCK *block ); void __init atari_stram_init(void) { int i; + void *stram_start; - /* initialize static blocks */ - for( i = 0; i < N_STATIC_BLOCKS; ++i ) - static_blocks[i].flags = BLOCK_FREE; - - /* determine whether kernel code resides in ST-RAM (then ST-RAM is the - * first memory block at virtual 0x0) */ + /* + * determine whether kernel code resides in ST-RAM + * (then ST-RAM is the first memory block at virtual 0x0) + */ stram_start = phys_to_virt(0); kernel_in_stram = (stram_start == 0); - for( i = 0; i < m68k_num_memory; ++i ) { + for (i = 0; i < m68k_num_memory; ++i) { if (m68k_memory[i].addr == 0) { - /* skip first 2kB or page (supervisor-only!) */ - stram_end = stram_start + m68k_memory[i].size; return; } } + /* Should never come here! (There is always ST-Ram!) */ - panic( "atari_stram_init: no ST-RAM found!" ); + panic("atari_stram_init: no ST-RAM found!"); } @@ -151,226 +93,68 @@ void __init atari_stram_init(void) */ void __init atari_stram_reserve_pages(void *start_mem) { - /* always reserve first page of ST-RAM, the first 2 kB are - * supervisor-only! */ + /* + * always reserve first page of ST-RAM, the first 2 KiB are + * supervisor-only! + */ if (!kernel_in_stram) reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); -} + stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size); + stram_pool.end = stram_pool.start + pool_size - 1; + request_resource(&iomem_resource, &stram_pool); -void atari_stram_mem_init_hook (void) -{ - mem_init_done = 1; + pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n", + pool_size, &stram_pool); } -/* - * This is main public interface: somehow allocate a ST-RAM block - * - * - If we're before mem_init(), we have to make a static allocation. The - * region is taken in the kernel data area (if the kernel is in ST-RAM) or - * from the start of ST-RAM (if the kernel is in TT-RAM) and added to the - * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel - * address space in the latter case. - * - * - If mem_init() already has been called, try with __get_dma_pages(). - * This has the disadvantage that it's very hard to get more than 1 page, - * and it is likely to fail :-( - * - */ -void *atari_stram_alloc(long size, const char *owner) +void *atari_stram_alloc(unsigned long size, const char *owner) { - void *addr = NULL; - BLOCK *block; - int flags; - - DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner); - - if (!mem_init_done) - return alloc_bootmem_low(size); - else { - /* After mem_init(): can only resort to __get_dma_pages() */ - addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size)); - flags = BLOCK_GFP; - DPRINTK( "atari_stram_alloc: after mem_init, " - "get_pages=%p\n", addr ); + struct resource *res; + int error; + + pr_debug("atari_stram_alloc: allocate %lu bytes\n", size); + + /* round up */ + size = PAGE_ALIGN(size); + + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + if (!res) + return NULL; + + res->name = owner; + error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX, + PAGE_SIZE, NULL, NULL); + if (error < 0) { + pr_err("atari_stram_alloc: allocate_resource() failed %d!\n", + error); + kfree(res); + return NULL; } - if (addr) { - if (!(block = add_region( addr, size ))) { - /* out of memory for BLOCK structure :-( */ - DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- " - "freeing again\n" ); - free_pages((unsigned long)addr, get_order(size)); - return( NULL ); - } - block->owner = owner; - block->flags |= flags; - } - return( addr ); + pr_debug("atari_stram_alloc: returning %pR\n", res); + return (void *)res->start; } EXPORT_SYMBOL(atari_stram_alloc); -void atari_stram_free( void *addr ) +void atari_stram_free(void *addr) { - BLOCK *block; - - DPRINTK( "atari_stram_free(addr=%p)\n", addr ); + unsigned long start = (unsigned long)addr; + struct resource *res; + unsigned long size; - if (!(block = find_region( addr ))) { - printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p " - "from %p\n", addr, __builtin_return_address(0) ); + res = lookup_resource(&stram_pool, start); + if (!res) { + pr_err("atari_stram_free: trying to free nonexistent region " + "at %p\n", addr); return; } - DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, " - "flags=%02x\n", block, block->size, block->owner, block->flags ); - - if (!(block->flags & BLOCK_GFP)) - goto fail; - DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n", - get_order(block->size)); - free_pages((unsigned long)addr, get_order(block->size)); - remove_region( block ); - return; - - fail: - printk( KERN_ERR "atari_stram_free: cannot free block at %p " - "(called from %p)\n", addr, __builtin_return_address(0) ); + size = resource_size(res); + pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr); + release_resource(res); + kfree(res); } EXPORT_SYMBOL(atari_stram_free); - - -/* ------------------------------------------------------------------------ */ -/* Region Management */ -/* ------------------------------------------------------------------------ */ - - -/* insert a region into the alloced list (sorted) */ -static BLOCK *add_region( void *addr, unsigned long size ) -{ - BLOCK **p, *n = NULL; - int i; - - for( i = 0; i < N_STATIC_BLOCKS; ++i ) { - if (static_blocks[i].flags & BLOCK_FREE) { - n = &static_blocks[i]; - n->flags = 0; - break; - } - } - if (!n && mem_init_done) { - /* if statics block pool exhausted and we can call kmalloc() already - * (after mem_init()), try that */ - n = kmalloc( sizeof(BLOCK), GFP_KERNEL ); - if (n) - n->flags = BLOCK_KMALLOCED; - } - if (!n) { - printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" ); - return( NULL ); - } - n->start = addr; - n->size = size; - - for( p = &alloc_list; *p; p = &((*p)->next) ) - if ((*p)->start > addr) break; - n->next = *p; - *p = n; - - return( n ); -} - - -/* find a region (by start addr) in the alloced list */ -static BLOCK *find_region( void *addr ) -{ - BLOCK *p; - - for( p = alloc_list; p; p = p->next ) { - if (p->start == addr) - return( p ); - if (p->start > addr) - break; - } - return( NULL ); -} - - -/* remove a block from the alloced list */ -static int remove_region( BLOCK *block ) -{ - BLOCK **p; - - for( p = &alloc_list; *p; p = &((*p)->next) ) - if (*p == block) break; - if (!*p) - return( 0 ); - - *p = block->next; - if (block->flags & BLOCK_KMALLOCED) - kfree( block ); - else - block->flags |= BLOCK_FREE; - return( 1 ); -} - - - -/* ------------------------------------------------------------------------ */ -/* /proc statistics file stuff */ -/* ------------------------------------------------------------------------ */ - -#ifdef DO_PROC - -#define PRINT_PROC(fmt,args...) seq_printf( m, fmt, ##args ) - -static int stram_proc_show(struct seq_file *m, void *v) -{ - BLOCK *p; - - PRINT_PROC("Total ST-RAM: %8u kB\n", - (stram_end - stram_start) >> 10); - PRINT_PROC( "Allocated regions:\n" ); - for( p = alloc_list; p; p = p->next ) { - PRINT_PROC("0x%08lx-0x%08lx: %s (", - virt_to_phys(p->start), - virt_to_phys(p->start+p->size-1), - p->owner); - if (p->flags & BLOCK_GFP) - PRINT_PROC( "page-alloced)\n" ); - else - PRINT_PROC( "??)\n" ); - } - - return 0; -} - -static int stram_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stram_proc_show, NULL); -} - -static const struct file_operations stram_proc_fops = { - .open = stram_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init proc_stram_init(void) -{ - proc_create("stram", 0, NULL, &stram_proc_fops); - return 0; -} -module_init(proc_stram_init); -#endif - - -/* - * Local variables: - * c-indent-level: 4 - * tab-width: 4 - * End: - */ diff --git a/arch/m68k/include/asm/atari_stram.h b/arch/m68k/include/asm/atari_stram.h index 7546d13..62e2759 100644 --- a/arch/m68k/include/asm/atari_stram.h +++ b/arch/m68k/include/asm/atari_stram.h @@ -6,12 +6,11 @@ */ /* public interface */ -void *atari_stram_alloc(long size, const char *owner); +void *atari_stram_alloc(unsigned long size, const char *owner); void atari_stram_free(void *); /* functions called internally by other parts of the kernel */ void atari_stram_init(void); void atari_stram_reserve_pages(void *start_mem); -void atari_stram_mem_init_hook (void); #endif /*_M68K_ATARI_STRAM_H */ diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h index f51f709..0392b2865 100644 --- a/arch/m68k/include/asm/atarihw.h +++ b/arch/m68k/include/asm/atarihw.h @@ -399,8 +399,8 @@ struct CODEC #define CODEC_OVERFLOW_LEFT 2 u_char unused2, unused3, unused4, unused5; u_char gpio_directions; -#define GPIO_IN 0 -#define GPIO_OUT 1 +#define CODEC_GPIO_IN 0 +#define CODEC_GPIO_OUT 1 u_char unused6; u_char gpio_data; }; diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h index 307a573..65c6be6 100644 --- a/arch/m68k/include/asm/atomic.h +++ b/arch/m68k/include/asm/atomic.h @@ -183,7 +183,7 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v) __asm__ __volatile__("orl %1,%0" : "+m" (*v) : ASM_DI (mask)); } -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -195,10 +195,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() @@ -206,6 +205,4 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> -#include <asm-generic/atomic64.h> #endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h index 31d5570..89f2014 100644 --- a/arch/m68k/include/asm/page_mm.h +++ b/arch/m68k/include/asm/page_mm.h @@ -162,7 +162,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void) pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \ }) #define page_to_pfn(_page) ({ \ - struct page *__p = (_page); \ + const struct page *__p = (_page); \ struct pglist_data *pgdat; \ pgdat = &pg_data_map[page_to_nid(__p)]; \ ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \ diff --git a/arch/m68k/include/asm/posix_types.h b/arch/m68k/include/asm/posix_types.h index 63cdcc1..98d0970 100644 --- a/arch/m68k/include/asm/posix_types.h +++ b/arch/m68k/include/asm/posix_types.h @@ -51,7 +51,7 @@ typedef struct { #define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) #undef __FD_ISSET -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) #undef __FD_ZERO #define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h index 6e6e3ac..65322b17 100644 --- a/arch/m68k/include/asm/ptrace.h +++ b/arch/m68k/include/asm/ptrace.h @@ -85,7 +85,6 @@ struct switch_stack { #define user_mode(regs) (!((regs)->sr & PS_S)) #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); #define arch_has_single_step() (1) diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index 334d836..c3b4506 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -216,7 +216,9 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) void __init setup_arch(char **cmdline_p) { +#ifndef CONFIG_SUN3 int i; +#endif /* The bootinfo is located right after the kernel bss */ m68k_parse_bootinfo((const struct bi_record *)_end); diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 00d1452..c468f2e 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -189,7 +189,7 @@ ENTRY(sys_call_table) .long sys_getpagesize .long sys_ni_syscall /* old "query_module" */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c index 367ecee..3384a52 100644 --- a/arch/m68k/math-emu/fp_log.c +++ b/arch/m68k/math-emu/fp_log.c @@ -105,9 +105,6 @@ fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src) fp_monadic_check(dest, src); - if (IS_ZERO(dest)) - return dest; - return dest; } diff --git a/arch/m68k/math-emu/multi_arith.h b/arch/m68k/math-emu/multi_arith.h index 4ad0ca9..4b5eb3d 100644 --- a/arch/m68k/math-emu/multi_arith.h +++ b/arch/m68k/math-emu/multi_arith.h @@ -19,246 +19,6 @@ #ifndef MULTI_ARITH_H #define MULTI_ARITH_H -#if 0 /* old code... */ - -/* Unsigned only, because we don't need signs to multiply and divide. */ -typedef unsigned int int128[4]; - -/* Word order */ -enum { - MSW128, - NMSW128, - NLSW128, - LSW128 -}; - -/* big-endian */ -#define LO_WORD(ll) (((unsigned int *) &ll)[1]) -#define HI_WORD(ll) (((unsigned int *) &ll)[0]) - -/* Convenience functions to stuff various integer values into int128s */ - -static inline void zero128(int128 a) -{ - a[LSW128] = a[NLSW128] = a[NMSW128] = a[MSW128] = 0; -} - -/* Human-readable word order in the arguments */ -static inline void set128(unsigned int i3, unsigned int i2, unsigned int i1, - unsigned int i0, int128 a) -{ - a[LSW128] = i0; - a[NLSW128] = i1; - a[NMSW128] = i2; - a[MSW128] = i3; -} - -/* Convenience functions (for testing as well) */ -static inline void int64_to_128(unsigned long long src, int128 dest) -{ - dest[LSW128] = (unsigned int) src; - dest[NLSW128] = src >> 32; - dest[NMSW128] = dest[MSW128] = 0; -} - -static inline void int128_to_64(const int128 src, unsigned long long *dest) -{ - *dest = src[LSW128] | (long long) src[NLSW128] << 32; -} - -static inline void put_i128(const int128 a) -{ - printk("%08x %08x %08x %08x\n", a[MSW128], a[NMSW128], - a[NLSW128], a[LSW128]); -} - -/* Internal shifters: - - Note that these are only good for 0 < count < 32. - */ - -static inline void _lsl128(unsigned int count, int128 a) -{ - a[MSW128] = (a[MSW128] << count) | (a[NMSW128] >> (32 - count)); - a[NMSW128] = (a[NMSW128] << count) | (a[NLSW128] >> (32 - count)); - a[NLSW128] = (a[NLSW128] << count) | (a[LSW128] >> (32 - count)); - a[LSW128] <<= count; -} - -static inline void _lsr128(unsigned int count, int128 a) -{ - a[LSW128] = (a[LSW128] >> count) | (a[NLSW128] << (32 - count)); - a[NLSW128] = (a[NLSW128] >> count) | (a[NMSW128] << (32 - count)); - a[NMSW128] = (a[NMSW128] >> count) | (a[MSW128] << (32 - count)); - a[MSW128] >>= count; -} - -/* Should be faster, one would hope */ - -static inline void lslone128(int128 a) -{ - asm volatile ("lsl.l #1,%0\n" - "roxl.l #1,%1\n" - "roxl.l #1,%2\n" - "roxl.l #1,%3\n" - : - "=d" (a[LSW128]), - "=d"(a[NLSW128]), - "=d"(a[NMSW128]), - "=d"(a[MSW128]) - : - "0"(a[LSW128]), - "1"(a[NLSW128]), - "2"(a[NMSW128]), - "3"(a[MSW128])); -} - -static inline void lsrone128(int128 a) -{ - asm volatile ("lsr.l #1,%0\n" - "roxr.l #1,%1\n" - "roxr.l #1,%2\n" - "roxr.l #1,%3\n" - : - "=d" (a[MSW128]), - "=d"(a[NMSW128]), - "=d"(a[NLSW128]), - "=d"(a[LSW128]) - : - "0"(a[MSW128]), - "1"(a[NMSW128]), - "2"(a[NLSW128]), - "3"(a[LSW128])); -} - -/* Generalized 128-bit shifters: - - These bit-shift to a multiple of 32, then move whole longwords. */ - -static inline void lsl128(unsigned int count, int128 a) -{ - int wordcount, i; - - if (count % 32) - _lsl128(count % 32, a); - - if (0 == (wordcount = count / 32)) - return; - - /* argh, gak, endian-sensitive */ - for (i = 0; i < 4 - wordcount; i++) { - a[i] = a[i + wordcount]; - } - for (i = 3; i >= 4 - wordcount; --i) { - a[i] = 0; - } -} - -static inline void lsr128(unsigned int count, int128 a) -{ - int wordcount, i; - - if (count % 32) - _lsr128(count % 32, a); - - if (0 == (wordcount = count / 32)) - return; - - for (i = 3; i >= wordcount; --i) { - a[i] = a[i - wordcount]; - } - for (i = 0; i < wordcount; i++) { - a[i] = 0; - } -} - -static inline int orl128(int a, int128 b) -{ - b[LSW128] |= a; -} - -static inline int btsthi128(const int128 a) -{ - return a[MSW128] & 0x80000000; -} - -/* test bits (numbered from 0 = LSB) up to and including "top" */ -static inline int bftestlo128(int top, const int128 a) -{ - int r = 0; - - if (top > 31) - r |= a[LSW128]; - if (top > 63) - r |= a[NLSW128]; - if (top > 95) - r |= a[NMSW128]; - - r |= a[3 - (top / 32)] & ((1 << (top % 32 + 1)) - 1); - - return (r != 0); -} - -/* Aargh. We need these because GCC is broken */ -/* FIXME: do them in assembly, for goodness' sake! */ -static inline void mask64(int pos, unsigned long long *mask) -{ - *mask = 0; - - if (pos < 32) { - LO_WORD(*mask) = (1 << pos) - 1; - return; - } - LO_WORD(*mask) = -1; - HI_WORD(*mask) = (1 << (pos - 32)) - 1; -} - -static inline void bset64(int pos, unsigned long long *dest) -{ - /* This conditional will be optimized away. Thanks, GCC! */ - if (pos < 32) - asm volatile ("bset %1,%0":"=m" - (LO_WORD(*dest)):"id"(pos)); - else - asm volatile ("bset %1,%0":"=m" - (HI_WORD(*dest)):"id"(pos - 32)); -} - -static inline int btst64(int pos, unsigned long long dest) -{ - if (pos < 32) - return (0 != (LO_WORD(dest) & (1 << pos))); - else - return (0 != (HI_WORD(dest) & (1 << (pos - 32)))); -} - -static inline void lsl64(int count, unsigned long long *dest) -{ - if (count < 32) { - HI_WORD(*dest) = (HI_WORD(*dest) << count) - | (LO_WORD(*dest) >> count); - LO_WORD(*dest) <<= count; - return; - } - count -= 32; - HI_WORD(*dest) = LO_WORD(*dest) << count; - LO_WORD(*dest) = 0; -} - -static inline void lsr64(int count, unsigned long long *dest) -{ - if (count < 32) { - LO_WORD(*dest) = (LO_WORD(*dest) >> count) - | (HI_WORD(*dest) << (32 - count)); - HI_WORD(*dest) >>= count; - return; - } - count -= 32; - LO_WORD(*dest) = HI_WORD(*dest) >> count; - HI_WORD(*dest) = 0; -} -#endif - static inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) { reg->exp += cnt; @@ -481,117 +241,6 @@ static inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, } } -#if 0 -static inline unsigned int fp_fls128(union fp_mant128 *src) -{ - unsigned long data; - unsigned int res, off; - - if ((data = src->m32[0])) - off = 0; - else if ((data = src->m32[1])) - off = 32; - else if ((data = src->m32[2])) - off = 64; - else if ((data = src->m32[3])) - off = 96; - else - return 128; - - asm ("bfffo %1{#0,#32},%0" : "=d" (res) : "dm" (data)); - return res + off; -} - -static inline void fp_shiftmant128(union fp_mant128 *src, int shift) -{ - unsigned long sticky; - - switch (shift) { - case 0: - return; - case 1: - asm volatile ("lsl.l #1,%0" - : "=d" (src->m32[3]) : "0" (src->m32[3])); - asm volatile ("roxl.l #1,%0" - : "=d" (src->m32[2]) : "0" (src->m32[2])); - asm volatile ("roxl.l #1,%0" - : "=d" (src->m32[1]) : "0" (src->m32[1])); - asm volatile ("roxl.l #1,%0" - : "=d" (src->m32[0]) : "0" (src->m32[0])); - return; - case 2 ... 31: - src->m32[0] = (src->m32[0] << shift) | (src->m32[1] >> (32 - shift)); - src->m32[1] = (src->m32[1] << shift) | (src->m32[2] >> (32 - shift)); - src->m32[2] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); - src->m32[3] = (src->m32[3] << shift); - return; - case 32 ... 63: - shift -= 32; - src->m32[0] = (src->m32[1] << shift) | (src->m32[2] >> (32 - shift)); - src->m32[1] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); - src->m32[2] = (src->m32[3] << shift); - src->m32[3] = 0; - return; - case 64 ... 95: - shift -= 64; - src->m32[0] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); - src->m32[1] = (src->m32[3] << shift); - src->m32[2] = src->m32[3] = 0; - return; - case 96 ... 127: - shift -= 96; - src->m32[0] = (src->m32[3] << shift); - src->m32[1] = src->m32[2] = src->m32[3] = 0; - return; - case -31 ... -1: - shift = -shift; - sticky = 0; - if (src->m32[3] << (32 - shift)) - sticky = 1; - src->m32[3] = (src->m32[3] >> shift) | (src->m32[2] << (32 - shift)) | sticky; - src->m32[2] = (src->m32[2] >> shift) | (src->m32[1] << (32 - shift)); - src->m32[1] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)); - src->m32[0] = (src->m32[0] >> shift); - return; - case -63 ... -32: - shift = -shift - 32; - sticky = 0; - if ((src->m32[2] << (32 - shift)) || src->m32[3]) - sticky = 1; - src->m32[3] = (src->m32[2] >> shift) | (src->m32[1] << (32 - shift)) | sticky; - src->m32[2] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)); - src->m32[1] = (src->m32[0] >> shift); - src->m32[0] = 0; - return; - case -95 ... -64: - shift = -shift - 64; - sticky = 0; - if ((src->m32[1] << (32 - shift)) || src->m32[2] || src->m32[3]) - sticky = 1; - src->m32[3] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)) | sticky; - src->m32[2] = (src->m32[0] >> shift); - src->m32[1] = src->m32[0] = 0; - return; - case -127 ... -96: - shift = -shift - 96; - sticky = 0; - if ((src->m32[0] << (32 - shift)) || src->m32[1] || src->m32[2] || src->m32[3]) - sticky = 1; - src->m32[3] = (src->m32[0] >> shift) | sticky; - src->m32[2] = src->m32[1] = src->m32[0] = 0; - return; - } - - if (shift < 0 && (src->m32[0] || src->m32[1] || src->m32[2] || src->m32[3])) - src->m32[3] = 1; - else - src->m32[3] = 0; - src->m32[2] = 0; - src->m32[1] = 0; - src->m32[0] = 0; -} -#endif - static inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, int shift) { @@ -637,183 +286,4 @@ static inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, } } -#if 0 /* old code... */ -static inline int fls(unsigned int a) -{ - int r; - - asm volatile ("bfffo %1{#0,#32},%0" - : "=d" (r) : "md" (a)); - return r; -} - -/* fls = "find last set" (cf. ffs(3)) */ -static inline int fls128(const int128 a) -{ - if (a[MSW128]) - return fls(a[MSW128]); - if (a[NMSW128]) - return fls(a[NMSW128]) + 32; - /* XXX: it probably never gets beyond this point in actual - use, but that's indicative of a more general problem in the - algorithm (i.e. as per the actual 68881 implementation, we - really only need at most 67 bits of precision [plus - overflow]) so I'm not going to fix it. */ - if (a[NLSW128]) - return fls(a[NLSW128]) + 64; - if (a[LSW128]) - return fls(a[LSW128]) + 96; - else - return -1; -} - -static inline int zerop128(const int128 a) -{ - return !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); -} - -static inline int nonzerop128(const int128 a) -{ - return (a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); -} - -/* Addition and subtraction */ -/* Do these in "pure" assembly, because "extended" asm is unmanageable - here */ -static inline void add128(const int128 a, int128 b) -{ - /* rotating carry flags */ - unsigned int carry[2]; - - carry[0] = a[LSW128] > (0xffffffff - b[LSW128]); - b[LSW128] += a[LSW128]; - - carry[1] = a[NLSW128] > (0xffffffff - b[NLSW128] - carry[0]); - b[NLSW128] = a[NLSW128] + b[NLSW128] + carry[0]; - - carry[0] = a[NMSW128] > (0xffffffff - b[NMSW128] - carry[1]); - b[NMSW128] = a[NMSW128] + b[NMSW128] + carry[1]; - - b[MSW128] = a[MSW128] + b[MSW128] + carry[0]; -} - -/* Note: assembler semantics: "b -= a" */ -static inline void sub128(const int128 a, int128 b) -{ - /* rotating borrow flags */ - unsigned int borrow[2]; - - borrow[0] = b[LSW128] < a[LSW128]; - b[LSW128] -= a[LSW128]; - - borrow[1] = b[NLSW128] < a[NLSW128] + borrow[0]; - b[NLSW128] = b[NLSW128] - a[NLSW128] - borrow[0]; - - borrow[0] = b[NMSW128] < a[NMSW128] + borrow[1]; - b[NMSW128] = b[NMSW128] - a[NMSW128] - borrow[1]; - - b[MSW128] = b[MSW128] - a[MSW128] - borrow[0]; -} - -/* Poor man's 64-bit expanding multiply */ -static inline void mul64(unsigned long long a, unsigned long long b, int128 c) -{ - unsigned long long acc; - int128 acc128; - - zero128(acc128); - zero128(c); - - /* first the low words */ - if (LO_WORD(a) && LO_WORD(b)) { - acc = (long long) LO_WORD(a) * LO_WORD(b); - c[NLSW128] = HI_WORD(acc); - c[LSW128] = LO_WORD(acc); - } - /* Next the high words */ - if (HI_WORD(a) && HI_WORD(b)) { - acc = (long long) HI_WORD(a) * HI_WORD(b); - c[MSW128] = HI_WORD(acc); - c[NMSW128] = LO_WORD(acc); - } - /* The middle words */ - if (LO_WORD(a) && HI_WORD(b)) { - acc = (long long) LO_WORD(a) * HI_WORD(b); - acc128[NMSW128] = HI_WORD(acc); - acc128[NLSW128] = LO_WORD(acc); - add128(acc128, c); - } - /* The first and last words */ - if (HI_WORD(a) && LO_WORD(b)) { - acc = (long long) HI_WORD(a) * LO_WORD(b); - acc128[NMSW128] = HI_WORD(acc); - acc128[NLSW128] = LO_WORD(acc); - add128(acc128, c); - } -} - -/* Note: unsigned */ -static inline int cmp128(int128 a, int128 b) -{ - if (a[MSW128] < b[MSW128]) - return -1; - if (a[MSW128] > b[MSW128]) - return 1; - if (a[NMSW128] < b[NMSW128]) - return -1; - if (a[NMSW128] > b[NMSW128]) - return 1; - if (a[NLSW128] < b[NLSW128]) - return -1; - if (a[NLSW128] > b[NLSW128]) - return 1; - - return (signed) a[LSW128] - b[LSW128]; -} - -inline void div128(int128 a, int128 b, int128 c) -{ - int128 mask; - - /* Algorithm: - - Shift the divisor until it's at least as big as the - dividend, keeping track of the position to which we've - shifted it, i.e. the power of 2 which we've multiplied it - by. - - Then, for this power of 2 (the mask), and every one smaller - than it, subtract the mask from the dividend and add it to - the quotient until the dividend is smaller than the raised - divisor. At this point, divide the dividend and the mask - by 2 (i.e. shift one place to the right). Lather, rinse, - and repeat, until there are no more powers of 2 left. */ - - /* FIXME: needless to say, there's room for improvement here too. */ - - /* Shift up */ - /* XXX: since it just has to be "at least as big", we can - probably eliminate this horribly wasteful loop. I will - have to prove this first, though */ - set128(0, 0, 0, 1, mask); - while (cmp128(b, a) < 0 && !btsthi128(b)) { - lslone128(b); - lslone128(mask); - } - - /* Shift down */ - zero128(c); - do { - if (cmp128(a, b) >= 0) { - sub128(b, a); - add128(mask, c); - } - lsrone128(mask); - lsrone128(b); - } while (nonzerop128(mask)); - - /* The remainder is in a... */ -} -#endif - #endif /* MULTI_ARITH_H */ diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c index 9113c2f..bbe5254 100644 --- a/arch/m68k/mm/init_mm.c +++ b/arch/m68k/mm/init_mm.c @@ -83,11 +83,6 @@ void __init mem_init(void) int initpages = 0; int i; -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) - atari_stram_mem_init_hook(); -#endif - /* this will put all memory onto the freelists */ totalram_pages = num_physpages = 0; for_each_online_pgdat(pgdat) { diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h index d8f0133..7d6831a 100644 --- a/arch/microblaze/include/asm/cpuinfo.h +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -38,6 +38,7 @@ struct cpuinfo { u32 use_exc; u32 ver_code; u32 mmu; + u32 mmu_privins; u32 endian; /* CPU caches */ diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h index c4532f0..c9a6262 100644 --- a/arch/microblaze/include/asm/irqflags.h +++ b/arch/microblaze/include/asm/irqflags.h @@ -14,7 +14,7 @@ #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR -static inline unsigned long arch_local_irq_save(void) +static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags; asm volatile(" msrclr %0, %1 \n" @@ -25,7 +25,7 @@ static inline unsigned long arch_local_irq_save(void) return flags; } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { /* this uses r0 without declaring it - is that correct? */ asm volatile(" msrclr r0, %0 \n" @@ -35,7 +35,7 @@ static inline void arch_local_irq_disable(void) : "memory"); } -static inline void arch_local_irq_enable(void) +static inline notrace void arch_local_irq_enable(void) { /* this uses r0 without declaring it - is that correct? */ asm volatile(" msrset r0, %0 \n" @@ -47,7 +47,7 @@ static inline void arch_local_irq_enable(void) #else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ -static inline unsigned long arch_local_irq_save(void) +static inline notrace unsigned long arch_local_irq_save(void) { unsigned long flags, tmp; asm volatile (" mfs %0, rmsr \n" @@ -61,7 +61,7 @@ static inline unsigned long arch_local_irq_save(void) return flags; } -static inline void arch_local_irq_disable(void) +static inline notrace void arch_local_irq_disable(void) { unsigned long tmp; asm volatile(" mfs %0, rmsr \n" @@ -74,7 +74,7 @@ static inline void arch_local_irq_disable(void) : "memory"); } -static inline void arch_local_irq_enable(void) +static inline notrace void arch_local_irq_enable(void) { unsigned long tmp; asm volatile(" mfs %0, rmsr \n" @@ -89,7 +89,7 @@ static inline void arch_local_irq_enable(void) #endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ -static inline unsigned long arch_local_save_flags(void) +static inline notrace unsigned long arch_local_save_flags(void) { unsigned long flags; asm volatile(" mfs %0, rmsr \n" @@ -100,7 +100,7 @@ static inline unsigned long arch_local_save_flags(void) return flags; } -static inline void arch_local_irq_restore(unsigned long flags) +static inline notrace void arch_local_irq_restore(unsigned long flags) { asm volatile(" mts rmsr, %0 \n" " nop \n" @@ -109,12 +109,12 @@ static inline void arch_local_irq_restore(unsigned long flags) : "memory"); } -static inline bool arch_irqs_disabled_flags(unsigned long flags) +static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { return (flags & MSR_IE) == 0; } -static inline bool arch_irqs_disabled(void) +static inline notrace bool arch_irqs_disabled(void) { return arch_irqs_disabled_flags(arch_local_save_flags()); } diff --git a/arch/microblaze/include/asm/mmu_context_mm.h b/arch/microblaze/include/asm/mmu_context_mm.h index 3e5c254..d686477 100644 --- a/arch/microblaze/include/asm/mmu_context_mm.h +++ b/arch/microblaze/include/asm/mmu_context_mm.h @@ -11,7 +11,7 @@ #ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H #define _ASM_MICROBLAZE_MMU_CONTEXT_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/bitops.h> #include <asm/mmu.h> #include <asm-generic/mm_hooks.h> diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 242be57..32764cd 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -10,28 +10,19 @@ #include <linux/pci.h> #include <linux/list.h> #include <linux/ioport.h> +#include <asm-generic/pci-bridge.h> struct device_node; -enum { - /* Force re-assigning all resources (ignore firmware - * setup completely) - */ - PCI_REASSIGN_ALL_RSRC = 0x00000001, - - /* Do not try to assign, just use existing setup */ - PCI_PROBE_ONLY = 0x00000004, - - /* Don't bother with ISA alignment unless the bridge has - * ISA forwarding enabled - */ - PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, - - /* Enable domain numbers in /proc */ - PCI_ENABLE_PROC_DOMAINS = 0x00000010, - /* ... except for domain 0 */ - PCI_COMPAT_DOMAIN_0 = 0x00000020, -}; +#ifdef CONFIG_PCI +extern struct list_head hose_list; +extern int pcibios_vaddr_is_ioport(void __iomem *address); +#else +static inline int pcibios_vaddr_is_ioport(void __iomem *address) +{ + return 0; +} +#endif /* * Structure of a PCI controller (host bridge) @@ -151,40 +142,5 @@ extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); extern void pcibios_free_controller(struct pci_controller *phb); extern void pcibios_setup_phb_resources(struct pci_controller *hose); -#ifdef CONFIG_PCI -extern unsigned int pci_flags; - -static inline void pci_set_flags(int flags) -{ - pci_flags = flags; -} - -static inline void pci_add_flags(int flags) -{ - pci_flags |= flags; -} - -static inline int pci_has_flag(int flag) -{ - return pci_flags & flag; -} - -extern struct list_head hose_list; - -extern int pcibios_vaddr_is_ioport(void __iomem *address); -#else -static inline int pcibios_vaddr_is_ioport(void __iomem *address) -{ - return 0; -} - -static inline void pci_set_flags(int flags) { } -static inline void pci_add_flags(int flags) { } -static inline int pci_has_flag(int flag) -{ - return 0; -} -#endif /* CONFIG_PCI */ - #endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */ diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index aed2a6b..7283bfb 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -125,9 +125,6 @@ struct thread_struct { .pgdir = swapper_pg_dir, \ } -/* Do necessary setup to start up a newly executed thread. */ -void start_thread(struct pt_regs *regs, - unsigned long pc, unsigned long usp); /* Free all resources held by a thread. */ extern inline void release_thread(struct task_struct *dead_task) diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 9bd01ec..20c5e8e 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -21,13 +21,17 @@ #include <linux/types.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #define HAVE_ARCH_DEVTREE_FIXUPS /* Other Prototypes */ -extern int early_uartlite_console(void); -extern int early_uart16550_console(void); +enum early_consoles { + UARTLITE = 1, + UART16550 = 2, +}; + +extern int of_early_console(void *version); /* * OF address retreival & translation diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h index d9b6630..816bee6 100644 --- a/arch/microblaze/include/asm/ptrace.h +++ b/arch/microblaze/include/asm/ptrace.h @@ -61,8 +61,6 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->pc) #define profile_pc(regs) instruction_pointer(regs) -void show_regs(struct pt_regs *); - #else /* __KERNEL__ */ /* pt_regs offsets used by gdbserver etc in ptrace syscalls */ diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h index a10bec6..4bbdb4c 100644 --- a/arch/microblaze/include/asm/pvr.h +++ b/arch/microblaze/include/asm/pvr.h @@ -111,16 +111,16 @@ struct pvr_s { /* Target family PVR mask */ #define PVR10_TARGET_FAMILY_MASK 0xFF000000 -/* MMU descrtiption */ +/* MMU description */ #define PVR11_USE_MMU 0xC0000000 #define PVR11_MMU_ITLB_SIZE 0x38000000 #define PVR11_MMU_DTLB_SIZE 0x07000000 #define PVR11_MMU_TLB_ACCESS 0x00C00000 #define PVR11_MMU_ZONES 0x003C0000 +#define PVR11_MMU_PRIVINS 0x00010000 /* MSR Reset value PVR mask */ #define PVR11_MSR_RESET_VALUE_MASK 0x000007FF - /* PVR access macros */ #define PVR_IS_FULL(_pvr) (_pvr.pvr[0] & PVR0_PVR_FULL_MASK) #define PVR_USE_BARREL(_pvr) (_pvr.pvr[0] & PVR0_USE_BARREL_MASK) @@ -216,6 +216,7 @@ struct pvr_s { #define PVR_MMU_DTLB_SIZE(_pvr) (_pvr.pvr[11] & PVR11_MMU_DTLB_SIZE) #define PVR_MMU_TLB_ACCESS(_pvr) (_pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) #define PVR_MMU_ZONES(_pvr) (_pvr.pvr[11] & PVR11_MMU_ZONES) +#define PVR_MMU_PRIVINS(pvr) (pvr.pvr[11] & PVR11_MMU_PRIVINS) /* endian */ #define PVR_ENDIAN(_pvr) (_pvr.pvr[0] & PVR0_ENDI) diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index 8f39689..904e5ef 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h @@ -23,6 +23,7 @@ extern char cmd_line[COMMAND_LINE_SIZE]; void early_printk(const char *fmt, ...); int setup_early_printk(char *opt); +void remap_early_printk(void); void disable_early_printk(void); #if defined(CONFIG_EARLY_PRINTK) diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index f70a604..916aaed 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) CI(pvr_user2, USER2); CI(mmu, USE_MMU); + CI(mmu_privins, MMU_PRIVINS); CI(endian, ENDIAN); CI(use_icache, USE_ICACHE); diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c index b16b994..592bb2e 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); ci->mmu = fcpu(cpu, "xlnx,use-mmu"); + ci->mmu_privins = fcpu(cpu, "xlnx,mmu-privileged-instr"); ci->endian = fcpu(cpu, "xlnx,endianness"); ci->ver_code = 0; diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index c1640c5..44394d8 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -88,4 +88,8 @@ void __init setup_cpuinfo(void) printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__); set_cpuinfo_static(&cpuinfo, cpu); } + + if (cpuinfo.mmu_privins) + printk(KERN_WARNING "%s: Stream instructions enabled" + " - USERSPACE CAN LOCK THIS KERNEL!\n", __func__); } diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c index b4048af..7b5dca7 100644 --- a/arch/microblaze/kernel/cpu/mb.c +++ b/arch/microblaze/kernel/cpu/mb.c @@ -97,6 +97,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "", (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : ""); + count += seq_printf(m, + "Stream-insns:\t%sprivileged\n", + cpuinfo.mmu_privins ? "un" : ""); + if (cpuinfo.use_icache) count += seq_printf(m, "Icache:\t\t%ukB\tline length:\t%dB\n", @@ -110,10 +114,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) "Dcache:\t\t%ukB\tline length:\t%dB\n", cpuinfo.dcache_size >> 10, cpuinfo.dcache_line_length); + seq_printf(m, "Dcache-Policy:\t"); if (cpuinfo.dcache_wb) - count += seq_printf(m, "\t\twrite-back\n"); + count += seq_printf(m, "write-back\n"); else - count += seq_printf(m, "\t\twrite-through\n"); + count += seq_printf(m, "write-through\n"); } else count += seq_printf(m, "Dcache:\t\tno\n"); diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index c3616a08..d26d92d 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c @@ -35,7 +35,7 @@ static void early_printk_uartlite_putc(char c) * we'll never timeout on a working UART. */ - unsigned retries = 10000; + unsigned retries = 1000000; /* read status bit - 0x8 offset */ while (--retries && (in_be32(base_addr + 8) & (1 << 3))) ; @@ -60,7 +60,7 @@ static void early_printk_uartlite_write(struct console *unused, static struct console early_serial_uartlite_console = { .name = "earlyser", .write = early_printk_uartlite_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; #endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ @@ -104,7 +104,7 @@ static void early_printk_uart16550_write(struct console *unused, static struct console early_serial_uart16550_console = { .name = "earlyser", .write = early_printk_uart16550_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; #endif /* CONFIG_SERIAL_8250_CONSOLE */ @@ -127,48 +127,56 @@ void early_printk(const char *fmt, ...) int __init setup_early_printk(char *opt) { + int version = 0; + if (early_console_initialized) return 1; -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE - base_addr = early_uartlite_console(); + base_addr = of_early_console(&version); if (base_addr) { - early_console_initialized = 1; #ifdef CONFIG_MMU early_console_reg_tlb_alloc(base_addr); #endif - early_console = &early_serial_uartlite_console; - early_printk("early_printk_console is enabled at 0x%08x\n", - base_addr); - - /* register_console(early_console); */ - - return 0; - } -#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ - + switch (version) { +#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE + case UARTLITE: + printk(KERN_INFO "Early console on uartlite " + "at 0x%08x\n", base_addr); + early_console = &early_serial_uartlite_console; + break; +#endif #ifdef CONFIG_SERIAL_8250_CONSOLE - base_addr = early_uart16550_console(); - base_addr &= ~3; /* clear register offset */ - if (base_addr) { - early_console_initialized = 1; -#ifdef CONFIG_MMU - early_console_reg_tlb_alloc(base_addr); + case UART16550: + printk(KERN_INFO "Early console on uart16650 " + "at 0x%08x\n", base_addr); + early_console = &early_serial_uart16550_console; + break; #endif - early_console = &early_serial_uart16550_console; - - early_printk("early_printk_console is enabled at 0x%08x\n", - base_addr); - - /* register_console(early_console); */ + default: + printk(KERN_INFO "Unsupported early console %d\n", + version); + return 1; + } + register_console(early_console); + early_console_initialized = 1; return 0; } -#endif /* CONFIG_SERIAL_8250_CONSOLE */ - return 1; } +/* Remap early console to virtual address and do not allocate one TLB + * only for early console because of performance degression */ +void __init remap_early_printk(void) +{ + if (!early_console_initialized || !early_console) + return; + printk(KERN_INFO "early_printk_console remaping from 0x%x to ", + base_addr); + base_addr = (u32) ioremap(base_addr, PAGE_SIZE); + printk(KERN_CONT "0x%x\n", base_addr); +} + void __init disable_early_printk(void) { if (!early_console_initialized || !early_console) diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 56572e9..e62be83 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -1113,23 +1113,23 @@ lw_r10_vm: R3_TO_LWREG_VM_V (10); lw_r11_vm: R3_TO_LWREG_VM_V (11); lw_r12_vm: R3_TO_LWREG_VM_V (12); lw_r13_vm: R3_TO_LWREG_VM_V (13); -lw_r14_vm: R3_TO_LWREG_VM (14); +lw_r14_vm: R3_TO_LWREG_VM_V (14); lw_r15_vm: R3_TO_LWREG_VM_V (15); -lw_r16_vm: R3_TO_LWREG_VM (16); +lw_r16_vm: R3_TO_LWREG_VM_V (16); lw_r17_vm: R3_TO_LWREG_VM_V (17); lw_r18_vm: R3_TO_LWREG_VM_V (18); -lw_r19_vm: R3_TO_LWREG_VM (19); -lw_r20_vm: R3_TO_LWREG_VM (20); -lw_r21_vm: R3_TO_LWREG_VM (21); -lw_r22_vm: R3_TO_LWREG_VM (22); -lw_r23_vm: R3_TO_LWREG_VM (23); -lw_r24_vm: R3_TO_LWREG_VM (24); -lw_r25_vm: R3_TO_LWREG_VM (25); -lw_r26_vm: R3_TO_LWREG_VM (26); -lw_r27_vm: R3_TO_LWREG_VM (27); -lw_r28_vm: R3_TO_LWREG_VM (28); -lw_r29_vm: R3_TO_LWREG_VM (29); -lw_r30_vm: R3_TO_LWREG_VM (30); +lw_r19_vm: R3_TO_LWREG_VM_V (19); +lw_r20_vm: R3_TO_LWREG_VM_V (20); +lw_r21_vm: R3_TO_LWREG_VM_V (21); +lw_r22_vm: R3_TO_LWREG_VM_V (22); +lw_r23_vm: R3_TO_LWREG_VM_V (23); +lw_r24_vm: R3_TO_LWREG_VM_V (24); +lw_r25_vm: R3_TO_LWREG_VM_V (25); +lw_r26_vm: R3_TO_LWREG_VM_V (26); +lw_r27_vm: R3_TO_LWREG_VM_V (27); +lw_r28_vm: R3_TO_LWREG_VM_V (28); +lw_r29_vm: R3_TO_LWREG_VM_V (29); +lw_r30_vm: R3_TO_LWREG_VM_V (30); lw_r31_vm: R3_TO_LWREG_VM_V (31); sw_table_vm: @@ -1147,23 +1147,23 @@ sw_r10_vm: SWREG_TO_R3_VM_V (10); sw_r11_vm: SWREG_TO_R3_VM_V (11); sw_r12_vm: SWREG_TO_R3_VM_V (12); sw_r13_vm: SWREG_TO_R3_VM_V (13); -sw_r14_vm: SWREG_TO_R3_VM (14); +sw_r14_vm: SWREG_TO_R3_VM_V (14); sw_r15_vm: SWREG_TO_R3_VM_V (15); -sw_r16_vm: SWREG_TO_R3_VM (16); +sw_r16_vm: SWREG_TO_R3_VM_V (16); sw_r17_vm: SWREG_TO_R3_VM_V (17); sw_r18_vm: SWREG_TO_R3_VM_V (18); -sw_r19_vm: SWREG_TO_R3_VM (19); -sw_r20_vm: SWREG_TO_R3_VM (20); -sw_r21_vm: SWREG_TO_R3_VM (21); -sw_r22_vm: SWREG_TO_R3_VM (22); -sw_r23_vm: SWREG_TO_R3_VM (23); -sw_r24_vm: SWREG_TO_R3_VM (24); -sw_r25_vm: SWREG_TO_R3_VM (25); -sw_r26_vm: SWREG_TO_R3_VM (26); -sw_r27_vm: SWREG_TO_R3_VM (27); -sw_r28_vm: SWREG_TO_R3_VM (28); -sw_r29_vm: SWREG_TO_R3_VM (29); -sw_r30_vm: SWREG_TO_R3_VM (30); +sw_r19_vm: SWREG_TO_R3_VM_V (19); +sw_r20_vm: SWREG_TO_R3_VM_V (20); +sw_r21_vm: SWREG_TO_R3_VM_V (21); +sw_r22_vm: SWREG_TO_R3_VM_V (22); +sw_r23_vm: SWREG_TO_R3_VM_V (23); +sw_r24_vm: SWREG_TO_R3_VM_V (24); +sw_r25_vm: SWREG_TO_R3_VM_V (25); +sw_r26_vm: SWREG_TO_R3_VM_V (26); +sw_r27_vm: SWREG_TO_R3_VM_V (27); +sw_r28_vm: SWREG_TO_R3_VM_V (28); +sw_r29_vm: SWREG_TO_R3_VM_V (29); +sw_r30_vm: SWREG_TO_R3_VM_V (30); sw_r31_vm: SWREG_TO_R3_VM_V (31); #endif /* CONFIG_MMU */ diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index c88f066..eb41441 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -134,7 +134,7 @@ void __init init_IRQ(void) intr_type = be32_to_cpup(of_get_property(intc, "xlnx,kind-of-intr", NULL)); - if (intr_type >= (1 << (nr_irq + 1))) + if (intr_type > (u32)((1ULL << nr_irq) - 1)) printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); #ifdef CONFIG_SELFMOD_INTC diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index 968648a..dbb8124 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c @@ -237,7 +237,6 @@ unsigned long get_wchan(struct task_struct *p) /* Set up a thread for executing a new program */ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) { - set_fs(USER_DS); regs->pc = pc; regs->r1 = usp; regs->pt_mode = 0; diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index b15cc21..977484a 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -53,69 +53,58 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) } #ifdef CONFIG_EARLY_PRINTK -/* MS this is Microblaze specifig function */ -static int __init early_init_dt_scan_serial(unsigned long node, - const char *uname, int depth, void *data) -{ - unsigned long l; - char *p; - const __be32 *addr; - - pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname); - -/* find all serial nodes */ - if (strncmp(uname, "serial", 6) != 0) - return 0; - -/* find compatible node with uartlite */ - p = of_get_flat_dt_prop(node, "compatible", &l); - if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && - (strncmp(p, "xlnx,opb-uartlite", 17) != 0) && - (strncmp(p, "xlnx,axi-uartlite", 17) != 0)) - return 0; - - addr = of_get_flat_dt_prop(node, "reg", &l); - return be32_to_cpup(addr); /* return address */ -} +char *stdout; -/* this function is looking for early uartlite console - Microblaze specific */ -int __init early_uartlite_console(void) -{ - return of_scan_flat_dt(early_init_dt_scan_serial, NULL); -} - -/* MS this is Microblaze specifig function */ -static int __init early_init_dt_scan_serial_full(unsigned long node, +int __init early_init_dt_scan_chosen_serial(unsigned long node, const char *uname, int depth, void *data) { unsigned long l; char *p; - unsigned int addr; - - pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); - -/* find all serial nodes */ - if (strncmp(uname, "serial", 6) != 0) - return 0; - early_init_dt_check_for_initrd(node); - -/* find compatible node with uartlite */ - p = of_get_flat_dt_prop(node, "compatible", &l); - - if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) && - (strncmp(p, "xlnx,axi-uart16550", 18) != 0)) - return 0; - - addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); - addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); - return be32_to_cpu(addr); /* return address */ + pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); + + if (depth == 1 && (strcmp(uname, "chosen") == 0 || + strcmp(uname, "chosen@0") == 0)) { + p = of_get_flat_dt_prop(node, "linux,stdout-path", &l); + if (p != NULL && l > 0) + stdout = p; /* store pointer to stdout-path */ + } + + if (stdout && strstr(stdout, uname)) { + p = of_get_flat_dt_prop(node, "compatible", &l); + pr_debug("Compatible string: %s\n", p); + + if ((strncmp(p, "xlnx,xps-uart16550", 18) == 0) || + (strncmp(p, "xlnx,axi-uart16550", 18) == 0)) { + unsigned int addr; + + *(u32 *)data = UART16550; + + addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); + addr += *(u32 *)of_get_flat_dt_prop(node, + "reg-offset", &l); + /* clear register offset */ + return be32_to_cpu(addr) & ~3; + } + if ((strncmp(p, "xlnx,xps-uartlite", 17) == 0) || + (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || + (strncmp(p, "xlnx,axi-uartlite", 17) == 0) || + (strncmp(p, "xlnx,mdm", 8) == 0)) { + unsigned int *addrp; + + *(u32 *)data = UARTLITE; + + addrp = of_get_flat_dt_prop(node, "reg", &l); + return be32_to_cpup(addrp); /* return address */ + } + } + return 0; } -/* this function is looking for early uartlite console - Microblaze specific */ -int __init early_uart16550_console(void) +/* this function is looking for early console - Microblaze specific */ +int __init of_early_console(void *version) { - return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL); + return of_scan_flat_dt(early_init_dt_scan_chosen_serial, version); } #endif diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 8e2c09b..0e654a1 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -59,6 +59,11 @@ void __init setup_arch(char **cmdline_p) setup_memory(); +#ifdef CONFIG_EARLY_PRINTK + /* remap early console to virtual address */ + remap_early_printk(); +#endif + xilinx_pci_init(); #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER) diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index d915a12..8789daa 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -173,7 +173,7 @@ ENTRY(sys_call_table) .long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* old nfsservctl */ .long sys_setresgid /* 170 */ .long sys_getresgid .long sys_prctl diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index aef6c91..5ce8029 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -16,6 +16,7 @@ platforms += lasat platforms += loongson platforms += mipssim platforms += mti-malta +platforms += netlogic platforms += pmc-sierra platforms += pnx833x platforms += pnx8550 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 884819c..53e3514 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -191,18 +191,6 @@ endif # include $(srctree)/arch/mips/Kbuild.platforms -# -# NETLOGIC SOC Common (common) -# -cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic -cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic - -# -# NETLOGIC XLR/XLS SoC, Simulator and boards -# -core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ -load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000 - cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index 2ca4ada..2460f9d 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c @@ -443,7 +443,7 @@ struct clk *clk_get(struct device *dev, const char *id) return &vbus_clk; if (!strcmp(id, "cpu")) return &cpu_clk; - if (!strcmp(id, "dsp")); + if (!strcmp(id, "dsp")) return &dsp_clk; if (!strcmp(id, "vbus")) return &vbus_clk; diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 7d2fab3..33ffecf 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -229,7 +229,7 @@ static struct resource cpmac_low_res[] = { .name = "irq", .flags = IORESOURCE_IRQ, .start = 27, - .end = 27, + .end = 27, }, }; diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c index 23818d2..8088c6f 100644 --- a/arch/mips/ar7/prom.c +++ b/arch/mips/ar7/prom.c @@ -77,7 +77,7 @@ struct psp_env_chunk { u16 csum; u8 len; char data[11]; -} __attribute__ ((packed)); +} __packed; struct psp_var_map_entry { u8 num; diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 4a02fe8..1d93f81 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -303,15 +303,15 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) #define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -323,9 +323,8 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic_dec_return(v) atomic_sub_return(1, (v)) #define atomic_inc_return(v) atomic_add_return(1, (v)) @@ -680,7 +679,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) { @@ -766,10 +765,6 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) */ #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) -#else /* !CONFIG_64BIT */ - -#include <asm-generic/atomic64.h> - #endif /* CONFIG_64BIT */ /* @@ -781,6 +776,4 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) #define smp_mb__before_atomic_inc() smp_mb__before_llsc() #define smp_mb__after_atomic_inc() smp_llsc_mb() -#include <asm-generic/atomic-long.h> - #endif /* _ASM_ATOMIC_H */ diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h index 0b89b83..98bcc98 100644 --- a/arch/mips/include/asm/fixmap.h +++ b/arch/mips/include/asm/fixmap.h @@ -14,6 +14,7 @@ #define _ASM_FIXMAP_H #include <asm/page.h> +#include <spaces.h> #ifdef CONFIG_HIGHMEM #include <linux/threads.h> #include <asm/kmap_types.h> @@ -67,15 +68,6 @@ enum fixed_addresses { * the start of the fixmap, and leave one page empty * at the top of mem.. */ -#ifdef CONFIG_BCM63XX -#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) -#else -#if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX) -#define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000)) -#else -#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) -#endif -#endif #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) diff --git a/arch/mips/include/asm/gt64120.h b/arch/mips/include/asm/gt64120.h index e64b410..0aa44ab 100644 --- a/arch/mips/include/asm/gt64120.h +++ b/arch/mips/include/asm/gt64120.h @@ -21,8 +21,6 @@ #ifndef _ASM_GT64120_H #define _ASM_GT64120_H -#include <linux/clocksource.h> - #include <asm/addrspace.h> #include <asm/byteorder.h> diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h index 77adda2..9e8ef59 100644 --- a/arch/mips/include/asm/hw_irq.h +++ b/arch/mips/include/asm/hw_irq.h @@ -8,7 +8,7 @@ #ifndef __ASM_HW_IRQ_H #define __ASM_HW_IRQ_H -#include <asm/atomic.h> +#include <linux/atomic.h> extern atomic_t irq_err_count; diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 0ec0129..2354c87 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -18,7 +18,6 @@ static inline void irq_dispose_mapping(unsigned int virq) { - return; } #ifdef CONFIG_I8259 diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h index fffc830..94fde8d 100644 --- a/arch/mips/include/asm/local.h +++ b/arch/mips/include/asm/local.h @@ -3,7 +3,7 @@ #include <linux/percpu.h> #include <linux/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cmpxchg.h> #include <asm/war.h> diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 85fd275..0ed5230 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -89,7 +89,6 @@ /* Interrupt Mask register */ #define PERF_IRQMASK_REG 0xc -#define PERF_IRQSTAT_REG 0x10 /* Interrupt Status register */ #define PERF_IRQSTAT_REG 0x10 diff --git a/arch/mips/include/asm/mach-bcm63xx/spaces.h b/arch/mips/include/asm/mach-bcm63xx/spaces.h new file mode 100644 index 0000000..61e750f --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/spaces.h @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle + * Copyright (C) 2000, 2002 Maciej W. Rozycki + * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. + */ +#ifndef _ASM_BCM63XX_SPACES_H +#define _ASM_BCM63XX_SPACES_H + +#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) + +#include <asm/mach-generic/spaces.h> + +#endif /* __ASM_BCM63XX_SPACES_H */ diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 8da9807..9c95177 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -49,7 +49,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline void plat_extra_sync_for_device(struct device *dev) { - return; } static inline int plat_dma_mapping_error(struct device *dev, diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index c9fa4b1..d7a9efd 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -82,4 +82,8 @@ #define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET) #endif +#ifndef FIXADDR_TOP +#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) +#endif + #endif /* __ASM_MACH_GENERIC_SPACES_H */ diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h index 016d098..06c4419 100644 --- a/arch/mips/include/asm/mach-ip27/dma-coherence.h +++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h @@ -60,7 +60,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline void plat_extra_sync_for_device(struct device *dev) { - return; } static inline int plat_dma_mapping_error(struct device *dev, diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h index 302101b..9fc1e9a 100644 --- a/arch/mips/include/asm/mach-jazz/dma-coherence.h +++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h @@ -50,7 +50,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline void plat_extra_sync_for_device(struct device *dev) { - return; } static inline int plat_dma_mapping_error(struct device *dev, diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 981c75f..e143305 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -55,7 +55,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline void plat_extra_sync_for_device(struct device *dev) { - return; } static inline int plat_dma_mapping_error(struct device *dev, diff --git a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h index 2848cea..37e3583 100644 --- a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h @@ -32,6 +32,7 @@ /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_clo_clz 1 #define cpu_has_nofpuex 0 /* #define cpu_has_64bits ? */ /* #define cpu_has_64bit_zero_reg ? */ @@ -58,6 +59,7 @@ /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_clo_clz 1 #define cpu_has_nofpuex 0 /* #define cpu_has_64bits ? */ /* #define cpu_has_64bit_zero_reg ? */ diff --git a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h b/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h index 779b022..27aaaa5 100644 --- a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h @@ -31,6 +31,7 @@ /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_clo_clz 1 #define cpu_has_nofpuex 0 /* #define cpu_has_64bits ? */ /* #define cpu_has_64bit_zero_reg ? */ @@ -56,6 +57,7 @@ /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_clo_clz 1 #define cpu_has_nofpuex 0 /* #define cpu_has_64bits ? */ /* #define cpu_has_64bit_zero_reg ? */ diff --git a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h new file mode 100644 index 0000000..f751e3e --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Cisco Systems, Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_ +#define _ASM_MACH_POWERTV_CPU_FEATURE_OVERRIDES_H_ +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_fpu 0 +#define cpu_has_counter 1 +#define cpu_has_watch 1 +#define cpu_has_divec 1 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_mcheck 1 +#define cpu_has_ejtag 1 +#define cpu_has_llsc 1 +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 +#define cpu_has_vtag_icache 0 +#define cpu_has_dc_aliases 0 +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 1 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 +#define cpu_has_dsp 0 +#define cpu_has_mipsmt 0 +#define cpu_has_userlocal 0 +#define cpu_has_nofpuex 0 +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 +#define cpu_has_vint 1 +#define cpu_has_veic 1 +#define cpu_has_inclusive_pcaches 0 + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#endif diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h index a8e72cf..62c0940 100644 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -102,7 +102,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline void plat_extra_sync_for_device(struct device *dev) { - return; } static inline int plat_dma_mapping_error(struct device *dev, diff --git a/arch/mips/include/asm/mach-tx39xx/spaces.h b/arch/mips/include/asm/mach-tx39xx/spaces.h new file mode 100644 index 0000000..151fe7a --- /dev/null +++ b/arch/mips/include/asm/mach-tx39xx/spaces.h @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle + * Copyright (C) 2000, 2002 Maciej W. Rozycki + * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. + */ +#ifndef _ASM_TX39XX_SPACES_H +#define _ASM_TX39XX_SPACES_H + +#define FIXADDR_TOP ((unsigned long)(long)(int)0xfefe0000) + +#include <asm/mach-generic/spaces.h> + +#endif /* __ASM_TX39XX_SPACES_H */ diff --git a/arch/mips/include/asm/mach-tx49xx/spaces.h b/arch/mips/include/asm/mach-tx49xx/spaces.h new file mode 100644 index 0000000..0cb10a6 --- /dev/null +++ b/arch/mips/include/asm/mach-tx49xx/spaces.h @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle + * Copyright (C) 2000, 2002 Maciej W. Rozycki + * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. + */ +#ifndef _ASM_TX49XX_SPACES_H +#define _ASM_TX49XX_SPACES_H + +#define FIXADDR_TOP ((unsigned long)(long)(int)0xfefe0000) + +#include <asm/mach-generic/spaces.h> + +#endif /* __ASM_TX49XX_SPACES_H */ diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 7e40f37..b2202a6 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -414,6 +414,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, * constraints placed on us by the cache architecture. */ #define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN /* * No page table caches to initialise diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h index 9e09af3..ef2a804 100644 --- a/arch/mips/include/asm/smp-ops.h +++ b/arch/mips/include/asm/smp-ops.h @@ -11,6 +11,8 @@ #ifndef __ASM_SMP_OPS_H #define __ASM_SMP_OPS_H +#include <linux/errno.h> + #ifdef CONFIG_SMP #include <linux/cpumask.h> @@ -56,8 +58,43 @@ static inline void register_smp_ops(struct plat_smp_ops *ops) #endif /* !CONFIG_SMP */ -extern struct plat_smp_ops up_smp_ops; -extern struct plat_smp_ops cmp_smp_ops; -extern struct plat_smp_ops vsmp_smp_ops; +static inline int register_up_smp_ops(void) +{ +#ifdef CONFIG_SMP_UP + extern struct plat_smp_ops up_smp_ops; + + register_smp_ops(&up_smp_ops); + + return 0; +#else + return -ENODEV; +#endif +} + +static inline int register_cmp_smp_ops(void) +{ +#ifdef CONFIG_MIPS_CMP + extern struct plat_smp_ops cmp_smp_ops; + + register_smp_ops(&cmp_smp_ops); + + return 0; +#else + return -ENODEV; +#endif +} + +static inline int register_vsmp_smp_ops(void) +{ +#ifdef CONFIG_MIPS_MT_SMP + extern struct plat_smp_ops vsmp_smp_ops; + + register_smp_ops(&vsmp_smp_ops); + + return 0; +#else + return -ENODEV; +#endif +} #endif /* __ASM_SMP_OPS_H */ diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index af42385..d4fb4d8 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -17,7 +17,7 @@ #include <linux/threads.h> #include <linux/cpumask.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp-ops.h> extern int smp_num_siblings; diff --git a/arch/mips/include/asm/smtc.h b/arch/mips/include/asm/smtc.h index ea60bf0..c9736fc 100644 --- a/arch/mips/include/asm/smtc.h +++ b/arch/mips/include/asm/smtc.h @@ -46,6 +46,7 @@ extern void smtc_prepare_cpus(int cpus); extern void smtc_smp_finish(void); extern void smtc_boot_secondary(int cpu, struct task_struct *t); extern void smtc_cpus_done(void); +extern void smtc_init_secondary(void); /* diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index dcbd4bb..504d40a 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -150,6 +150,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh) # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh) # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh) +# define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_dsrl_safe(buf, rs, rt, sh) # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh) # define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd) # define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd) @@ -165,6 +166,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ # define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh) # define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh) # define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) +# define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh) # define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh) # define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd) # define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd) diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 6fcfc48..ecea787 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -363,17 +363,18 @@ #define __NR_open_by_handle_at (__NR_Linux + 340) #define __NR_clock_adjtime (__NR_Linux + 341) #define __NR_syncfs (__NR_Linux + 342) -#define __NR_setns (__NR_Linux + 343) +#define __NR_sendmmsg (__NR_Linux + 343) +#define __NR_setns (__NR_Linux + 344) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 343 +#define __NR_Linux_syscalls 344 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 343 +#define __NR_O32_Linux_syscalls 344 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -683,17 +684,18 @@ #define __NR_open_by_handle_at (__NR_Linux + 299) #define __NR_clock_adjtime (__NR_Linux + 300) #define __NR_syncfs (__NR_Linux + 301) -#define __NR_setns (__NR_Linux + 302) +#define __NR_sendmmsg (__NR_Linux + 302) +#define __NR_setns (__NR_Linux + 303) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 302 +#define __NR_Linux_syscalls 303 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 302 +#define __NR_64_Linux_syscalls 303 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -1008,17 +1010,18 @@ #define __NR_open_by_handle_at (__NR_Linux + 304) #define __NR_clock_adjtime (__NR_Linux + 305) #define __NR_syncfs (__NR_Linux + 306) -#define __NR_setns (__NR_Linux + 307) +#define __NR_sendmmsg (__NR_Linux + 307) +#define __NR_setns (__NR_Linux + 308) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 307 +#define __NR_Linux_syscalls 308 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 307 +#define __NR_N32_Linux_syscalls 308 #ifdef __KERNEL__ diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index bb133d1..ebc0cd2 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -71,7 +71,6 @@ void r4k_wait_irqoff(void) local_irq_enable(); __asm__(" .globl __pastwait \n" "__pastwait: \n"); - return; } /* diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 9b734d7..b53970d 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -23,7 +23,7 @@ #include <linux/kgdb.h> #include <linux/ftrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/uaccess.h> diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 6e71b28..191eb52 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -103,14 +103,12 @@ void __init mips_cpu_irq_init(void) clear_c0_status(ST0_IM); clear_c0_cause(CAUSEF_IP); - /* - * Only MT is using the software interrupts currently, so we just - * leave them uninitialized for other processors. - */ - if (cpu_has_mipsmt) - for (i = irq_base; i < irq_base + 2; i++) - irq_set_chip_and_handler(i, &mips_mt_cpu_irq_controller, - handle_percpu_irq); + /* Software interrupts are used for MT/CMT IPI */ + for (i = irq_base; i < irq_base + 2; i++) + irq_set_chip_and_handler(i, cpu_has_mipsmt ? + &mips_mt_cpu_irq_controller : + &mips_cpu_irq_controller, + handle_percpu_irq); for (i = irq_base + 2; i < irq_base + 8; i++) irq_set_chip_and_handler(i, &mips_cpu_irq_controller, diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index b2259e7..594ca69 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -12,7 +12,7 @@ #include <asm/cpu.h> #include <asm/processor.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c index d0deaab..0aee944 100644 --- a/arch/mips/kernel/perf_event.c +++ b/arch/mips/kernel/perf_event.c @@ -192,8 +192,6 @@ again: local64_add(delta, &event->count); local64_sub(delta, &hwc->period_left); - - return; } static void mipspmu_start(struct perf_event *event, int flags) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index c28fbe6..b30cb25 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -103,7 +103,6 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) __init_dsp(); regs->cp0_epc = pc; regs->regs[29] = sp; - current_thread_info()->addr_limit = USER_DS; } void exit_thread(void) diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 557ef72..7a80b7cd 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -36,7 +36,7 @@ #include <asm/mipsmtregs.h> #include <asm/mips_mt.h> #include <asm/cacheflush.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cpu.h> #include <asm/processor.h> #include <asm/system.h> diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 99e656e..865bc7a 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -424,7 +424,7 @@ einval: li v0, -ENOSYS sys sys_getresuid 3 sys sys_ni_syscall 0 /* was sys_query_module */ sys sys_poll 3 - sys sys_nfsservctl 3 + sys sys_ni_syscall 0 /* was nfsservctl */ sys sys_setresgid 3 /* 4190 */ sys sys_getresgid 3 sys sys_prctl 5 @@ -589,6 +589,7 @@ einval: li v0, -ENOSYS sys sys_open_by_handle_at 3 /* 4340 */ sys sys_clock_adjtime 2 sys sys_syncfs 1 + sys sys_sendmmsg 4 sys sys_setns 2 .endm diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index fb0575f..fb7334b 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -299,7 +299,7 @@ sys_call_table: PTR sys_ni_syscall /* 5170, was get_kernel_syms */ PTR sys_ni_syscall /* was query_module */ PTR sys_quotactl - PTR sys_nfsservctl + PTR sys_ni_syscall /* was nfsservctl */ PTR sys_ni_syscall /* res. for getpmsg */ PTR sys_ni_syscall /* 5175 for putpmsg */ PTR sys_ni_syscall /* res. for afs_syscall */ @@ -428,5 +428,6 @@ sys_call_table: PTR sys_open_by_handle_at PTR sys_clock_adjtime /* 5300 */ PTR sys_syncfs + PTR sys_sendmmsg PTR sys_setns .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 4de0c55..f9296e8 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -294,7 +294,7 @@ EXPORT(sysn32_call_table) PTR sys_ni_syscall /* 6170, was get_kernel_syms */ PTR sys_ni_syscall /* was query_module */ PTR sys_quotactl - PTR compat_sys_nfsservctl + PTR sys_ni_syscall /* was nfsservctl */ PTR sys_ni_syscall /* res. for getpmsg */ PTR sys_ni_syscall /* 6175 for putpmsg */ PTR sys_ni_syscall /* res. for afs_syscall */ @@ -428,5 +428,6 @@ EXPORT(sysn32_call_table) PTR sys_open_by_handle_at PTR compat_sys_clock_adjtime /* 6305 */ PTR sys_syncfs + PTR compat_sys_sendmmsg PTR sys_setns .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 4a387de..4d7c982 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -392,7 +392,7 @@ sys_call_table: PTR sys_getresuid PTR sys_ni_syscall /* was query_module */ PTR sys_poll - PTR compat_sys_nfsservctl + PTR sys_ni_syscall /* was nfsservctl */ PTR sys_setresgid /* 4190 */ PTR sys_getresgid PTR sys_prctl @@ -546,5 +546,6 @@ sys_call_table: PTR compat_sys_open_by_handle_at /* 4340 */ PTR compat_sys_clock_adjtime PTR sys_syncfs + PTR compat_sys_sendmmsg PTR sys_setns .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index cc81771..fe30951 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -25,7 +25,7 @@ #include <linux/interrupt.h> #include <linux/compiler.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/cpu.h> #include <asm/processor.h> diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 1ec56e6..ce9e286 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -24,7 +24,7 @@ #include <linux/compiler.h> #include <linux/smp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/cpu.h> #include <asm/processor.h> diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 32a2561..32c1e95 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -34,7 +34,7 @@ #include <linux/err.h> #include <linux/ftrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cpu.h> #include <asm/processor.h> #include <asm/r4k-timer.h> diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c index fe25655..928a5a6 100644 --- a/arch/mips/kernel/smtc-proc.c +++ b/arch/mips/kernel/smtc-proc.c @@ -10,7 +10,7 @@ #include <asm/cpu.h> #include <asm/processor.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index cedac46..f0895e7 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -30,7 +30,7 @@ #include <asm/cpu.h> #include <asm/processor.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/hardirq.h> #include <asm/hazards.h> diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 05dd170..99f913c 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c @@ -16,7 +16,7 @@ #include <linux/cpumask.h> #include <asm/r4k-timer.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/barrier.h> #include <asm/mipsregs.h> diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index dbb6b40..2cd50ad 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -46,7 +46,7 @@ #include <asm/mipsregs.h> #include <asm/mipsmtregs.h> #include <asm/cacheflush.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cpu.h> #include <asm/mips_mt.h> #include <asm/processor.h> diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index 9456089..7e9c0ff 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c @@ -100,6 +100,19 @@ void clk_put(struct clk *clk) } EXPORT_SYMBOL(clk_put); +int clk_enable(struct clk *clk) +{ + /* not used */ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + /* not used */ +} +EXPORT_SYMBOL(clk_disable); + static inline u32 ltq_get_counter_resolution(void) { u32 res; diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c index 6405724..2b666d3 100644 --- a/arch/mips/loongson/lemote-2f/ec_kb3310b.c +++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.c @@ -45,8 +45,6 @@ void ec_write(unsigned short addr, unsigned char val) /* flush the write action */ inb(EC_IO_PORT_DATA); spin_unlock_irqrestore(&index_access_lock, flags); - - return; } EXPORT_SYMBOL_GPL(ec_write); diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 55f22a3..256e0cd 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -34,6 +34,7 @@ #include <asm/time.h> #include <asm/mips-boards/sim.h> #include <asm/mips-boards/simint.h> +#include <asm/smp-ops.h> static void __init serial_init(void); @@ -59,18 +60,17 @@ void __init prom_init(void) prom_meminit(); -#ifdef CONFIG_MIPS_MT_SMP - if (cpu_has_mipsmt) - register_smp_ops(&vsmp_smp_ops); - else - register_smp_ops(&up_smp_ops); -#endif + if (cpu_has_mipsmt) { + if (!register_vsmp_smp_ops()) + return; + #ifdef CONFIG_MIPS_MT_SMTC - if (cpu_has_mipsmt) register_smp_ops(&ssmtc_smp_ops); - else - register_smp_ops(&up_smp_ops); + return; #endif + } + + register_up_smp_ops(); } static void __init serial_init(void) diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c index 30df472..9150639 100644 --- a/arch/mips/mipssim/sim_smtc.c +++ b/arch/mips/mipssim/sim_smtc.c @@ -24,7 +24,7 @@ #include <linux/interrupt.h> #include <linux/smp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/cpu.h> #include <asm/processor.h> #include <asm/smtc.h> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index eeb642e..b9aabb9 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -604,6 +604,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) r4k_blast_scache(); else blast_scache_range(addr, addr + size); + __sync(); return; } @@ -620,6 +621,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) } bc_wback_inv(addr, size); + __sync(); } static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) @@ -647,6 +649,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) (addr + size - 1) & almask); blast_inv_scache_range(addr, addr + size); } + __sync(); return; } @@ -663,6 +666,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) } bc_inv(addr, size); + __sync(); } #endif /* CONFIG_DMA_NONCOHERENT */ diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 21ea14e..4608491 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -15,18 +15,18 @@ #include <linux/scatterlist.h> #include <linux/string.h> #include <linux/gfp.h> +#include <linux/highmem.h> #include <asm/cache.h> #include <asm/io.h> #include <dma-coherence.h> -static inline unsigned long dma_addr_to_virt(struct device *dev, +static inline struct page *dma_addr_to_page(struct device *dev, dma_addr_t dma_addr) { - unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr); - - return (unsigned long)phys_to_virt(addr); + return pfn_to_page( + plat_dma_addr_to_phys(dev, dma_addr) >> PAGE_SHIFT); } /* @@ -148,20 +148,20 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, free_pages(addr, get_order(size)); } -static inline void __dma_sync(unsigned long addr, size_t size, +static inline void __dma_sync_virtual(void *addr, size_t size, enum dma_data_direction direction) { switch (direction) { case DMA_TO_DEVICE: - dma_cache_wback(addr, size); + dma_cache_wback((unsigned long)addr, size); break; case DMA_FROM_DEVICE: - dma_cache_inv(addr, size); + dma_cache_inv((unsigned long)addr, size); break; case DMA_BIDIRECTIONAL: - dma_cache_wback_inv(addr, size); + dma_cache_wback_inv((unsigned long)addr, size); break; default: @@ -169,12 +169,49 @@ static inline void __dma_sync(unsigned long addr, size_t size, } } +/* + * A single sg entry may refer to multiple physically contiguous + * pages. But we still need to process highmem pages individually. + * If highmem is not configured then the bulk of this loop gets + * optimized out. + */ +static inline void __dma_sync(struct page *page, + unsigned long offset, size_t size, enum dma_data_direction direction) +{ + size_t left = size; + + do { + size_t len = left; + + if (PageHighMem(page)) { + void *addr; + + if (offset + len > PAGE_SIZE) { + if (offset >= PAGE_SIZE) { + page += offset >> PAGE_SHIFT; + offset &= ~PAGE_MASK; + } + len = PAGE_SIZE - offset; + } + + addr = kmap_atomic(page); + __dma_sync_virtual(addr + offset, len, direction); + kunmap_atomic(addr); + } else + __dma_sync_virtual(page_address(page) + offset, + size, direction); + offset = 0; + page++; + left -= len; + } while (left); +} + static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) { if (cpu_is_noncoherent_r10000(dev)) - __dma_sync(dma_addr_to_virt(dev, dma_addr), size, - direction); + __dma_sync(dma_addr_to_page(dev, dma_addr), + dma_addr & ~PAGE_MASK, size, direction); plat_unmap_dma_mem(dev, dma_addr, size, direction); } @@ -185,13 +222,11 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, int i; for (i = 0; i < nents; i++, sg++) { - unsigned long addr; - - addr = (unsigned long) sg_virt(sg); - if (!plat_device_is_coherent(dev) && addr) - __dma_sync(addr, sg->length, direction); - sg->dma_address = plat_map_dma_mem(dev, - (void *)addr, sg->length); + if (!plat_device_is_coherent(dev)) + __dma_sync(sg_page(sg), sg->offset, sg->length, + direction); + sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) + + sg->offset; } return nents; @@ -201,30 +236,23 @@ static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) { - unsigned long addr; - - addr = (unsigned long) page_address(page) + offset; - if (!plat_device_is_coherent(dev)) - __dma_sync(addr, size, direction); + __dma_sync(page, offset, size, direction); - return plat_map_dma_mem(dev, (void *)addr, size); + return plat_map_dma_mem_page(dev, page) + offset; } static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction, struct dma_attrs *attrs) { - unsigned long addr; int i; for (i = 0; i < nhwentries; i++, sg++) { if (!plat_device_is_coherent(dev) && - direction != DMA_TO_DEVICE) { - addr = (unsigned long) sg_virt(sg); - if (addr) - __dma_sync(addr, sg->length, direction); - } + direction != DMA_TO_DEVICE) + __dma_sync(sg_page(sg), sg->offset, sg->length, + direction); plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction); } } @@ -232,24 +260,18 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, static void mips_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - if (cpu_is_noncoherent_r10000(dev)) { - unsigned long addr; - - addr = dma_addr_to_virt(dev, dma_handle); - __dma_sync(addr, size, direction); - } + if (cpu_is_noncoherent_r10000(dev)) + __dma_sync(dma_addr_to_page(dev, dma_handle), + dma_handle & ~PAGE_MASK, size, direction); } static void mips_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { plat_extra_sync_for_device(dev); - if (!plat_device_is_coherent(dev)) { - unsigned long addr; - - addr = dma_addr_to_virt(dev, dma_handle); - __dma_sync(addr, size, direction); - } + if (!plat_device_is_coherent(dev)) + __dma_sync(dma_addr_to_page(dev, dma_handle), + dma_handle & ~PAGE_MASK, size, direction); } static void mips_dma_sync_sg_for_cpu(struct device *dev, @@ -260,8 +282,8 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { if (cpu_is_noncoherent_r10000(dev)) - __dma_sync((unsigned long)page_address(sg_page(sg)), - sg->length, direction); + __dma_sync(sg_page(sg), sg->offset, sg->length, + direction); } } @@ -273,8 +295,8 @@ static void mips_dma_sync_sg_for_device(struct device *dev, /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { if (!plat_device_is_coherent(dev)) - __dma_sync((unsigned long)page_address(sg_page(sg)), - sg->length, direction); + __dma_sync(sg_page(sg), sg->offset, sg->length, + direction); } } @@ -295,7 +317,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, plat_extra_sync_for_device(dev); if (!plat_device_is_coherent(dev)) - __dma_sync((unsigned long)vaddr, size, direction); + __dma_sync_virtual(vaddr, size, direction); } EXPORT_SYMBOL(dma_cache_sync); diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 1aadeb4..b7ebc4f 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -277,11 +277,11 @@ void __init fixrange_init(unsigned long start, unsigned long end, k = __pmd_offset(vaddr); pgd = pgd_base + i; - for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { + for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { pud = (pud_t *)pgd; - for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) { + for ( ; (j < PTRS_PER_PUD) && (vaddr < end); pud++, j++) { pmd = (pmd_t *)pud; - for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { + for (; (k < PTRS_PER_PMD) && (vaddr < end); pmd++, k++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pmd(pmd, __pmd((unsigned long)pte)); @@ -368,7 +368,7 @@ void __init mem_init(void) #ifdef CONFIG_DISCONTIGMEM #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" #endif - max_mapnr = highend_pfn; + max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; #else max_mapnr = max_low_pfn; #endif diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index ae3c20a..9ff5d0f 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -10,6 +10,7 @@ #include <linux/mm.h> #include <linux/mman.h> #include <linux/module.h> +#include <linux/personality.h> #include <linux/random.h> #include <linux/sched.h> @@ -17,21 +18,65 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ EXPORT_SYMBOL(shm_align_mask); +/* gap between mmap and stack */ +#define MIN_GAP (128*1024*1024UL) +#define MAX_GAP ((TASK_SIZE)/6*5) + +static int mmap_is_legacy(void) +{ + if (current->personality & ADDR_COMPAT_LAYOUT) + return 1; + + if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) + return 1; + + return sysctl_legacy_va_layout; +} + +static unsigned long mmap_base(unsigned long rnd) +{ + unsigned long gap = rlimit(RLIMIT_STACK); + + if (gap < MIN_GAP) + gap = MIN_GAP; + else if (gap > MAX_GAP) + gap = MAX_GAP; + + return PAGE_ALIGN(TASK_SIZE - gap - rnd); +} + +static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr, + unsigned long pgoff) +{ + unsigned long base = addr & ~shm_align_mask; + unsigned long off = (pgoff << PAGE_SHIFT) & shm_align_mask; + + if (base + off <= addr) + return base + off; + + return base - off; +} + #define COLOUR_ALIGN(addr,pgoff) \ ((((addr) + shm_align_mask) & ~shm_align_mask) + \ (((pgoff) << PAGE_SHIFT) & shm_align_mask)) -unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) +enum mmap_allocation_direction {UP, DOWN}; + +static unsigned long arch_get_unmapped_area_foo(struct file *filp, + unsigned long addr0, unsigned long len, unsigned long pgoff, + unsigned long flags, enum mmap_allocation_direction dir) { - struct vm_area_struct * vmm; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long addr = addr0; int do_color_align; - if (len > TASK_SIZE) + if (unlikely(len > TASK_SIZE)) return -ENOMEM; if (flags & MAP_FIXED) { - /* Even MAP_FIXED mappings must reside within TASK_SIZE. */ + /* Even MAP_FIXED mappings must reside within TASK_SIZE */ if (TASK_SIZE - len < addr) return -EINVAL; @@ -48,34 +93,130 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; + + /* requesting a specific address */ if (addr) { if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); else addr = PAGE_ALIGN(addr); - vmm = find_vma(current->mm, addr); + + vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vmm || addr + len <= vmm->vm_start)) + (!vma || addr + len <= vma->vm_start)) return addr; } - addr = current->mm->mmap_base; - if (do_color_align) - addr = COLOUR_ALIGN(addr, pgoff); - else - addr = PAGE_ALIGN(addr); - for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { - /* At this point: (!vmm || addr < vmm->vm_end). */ - if (TASK_SIZE - len < addr) - return -ENOMEM; - if (!vmm || addr + len <= vmm->vm_start) - return addr; - addr = vmm->vm_end; + if (dir == UP) { + addr = mm->mmap_base; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vma || addr + len <= vma->vm_start) + return addr; + addr = vma->vm_end; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + } + } else { + /* check if free_area_cache is useful for us */ + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = mm->mmap_base; + } + + /* either no address requested or can't fit in requested address hole */ + addr = mm->free_area_cache; + if (do_color_align) { + unsigned long base = + COLOUR_ALIGN_DOWN(addr - len, pgoff); + + addr = base + len; + } + + /* make sure it can fit in the remaining address space */ + if (likely(addr > len)) { + vma = find_vma(mm, addr - len); + if (!vma || addr <= vma->vm_start) { + /* remember the address as a hint for next time */ + return mm->free_area_cache = addr-len; + } + } + + if (unlikely(mm->mmap_base < len)) + goto bottomup; + + addr = mm->mmap_base-len; if (do_color_align) - addr = COLOUR_ALIGN(addr, pgoff); + addr = COLOUR_ALIGN_DOWN(addr, pgoff); + + do { + /* + * Lookup failure means no vma is above this address, + * else if new region fits below vma->vm_start, + * return with success: + */ + vma = find_vma(mm, addr); + if (likely(!vma || addr+len <= vma->vm_start)) { + /* remember the address as a hint for next time */ + return mm->free_area_cache = addr; + } + + /* remember the largest hole we saw so far */ + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + + /* try just below the current vma->vm_start */ + addr = vma->vm_start-len; + if (do_color_align) + addr = COLOUR_ALIGN_DOWN(addr, pgoff); + } while (likely(len < vma->vm_start)); + +bottomup: + /* + * A failed mmap() very likely causes application failure, + * so fall back to the bottom-up function here. This scenario + * can happen with large stack limits and large mmap() + * allocations. + */ + mm->cached_hole_size = ~0UL; + mm->free_area_cache = TASK_UNMAPPED_BASE; + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); + /* + * Restore the topdown base: + */ + mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; + + return addr; } } +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + return arch_get_unmapped_area_foo(filp, + addr0, len, pgoff, flags, UP); +} + +/* + * There is no need to export this but sched.h declares the function as + * extern so making it static here results in an error. + */ +unsigned long arch_get_unmapped_area_topdown(struct file *filp, + unsigned long addr0, unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + return arch_get_unmapped_area_foo(filp, + addr0, len, pgoff, flags, DOWN); +} + void arch_pick_mmap_layout(struct mm_struct *mm) { unsigned long random_factor = 0UL; @@ -89,9 +230,15 @@ void arch_pick_mmap_layout(struct mm_struct *mm) random_factor &= 0xffffffful; } - mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; + if (mmap_is_legacy()) { + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { + mm->mmap_base = mmap_base(random_factor); + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } } static inline unsigned long brk_rnd(void) diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index 575e401..adc6911 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c @@ -52,7 +52,7 @@ void __init pagetable_init(void) * Fixed mappings: */ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - fixrange_init(vaddr, 0, pgd_base); + fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base); #ifdef CONFIG_HIGHMEM /* diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 78eaa4f..cda4e30 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -76,5 +76,5 @@ void __init pagetable_init(void) * Fixed mappings: */ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - fixrange_init(vaddr, 0, pgd_base); + fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base); } diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 424ed4b..b6e1cff 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -42,6 +42,18 @@ extern void tlb_do_page_fault_0(void); extern void tlb_do_page_fault_1(void); +struct work_registers { + int r1; + int r2; + int r3; +}; + +struct tlb_reg_save { + unsigned long a; + unsigned long b; +} ____cacheline_aligned_in_smp; + +static struct tlb_reg_save handler_reg_save[NR_CPUS]; static inline int r45k_bvahwbug(void) { @@ -248,6 +260,73 @@ static int scratch_reg __cpuinitdata; static int pgd_reg __cpuinitdata; enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch}; +static struct work_registers __cpuinit build_get_work_registers(u32 **p) +{ + struct work_registers r; + + int smp_processor_id_reg; + int smp_processor_id_sel; + int smp_processor_id_shift; + + if (scratch_reg > 0) { + /* Save in CPU local C0_KScratch? */ + UASM_i_MTC0(p, 1, 31, scratch_reg); + r.r1 = K0; + r.r2 = K1; + r.r3 = 1; + return r; + } + + if (num_possible_cpus() > 1) { +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT + smp_processor_id_shift = 51; + smp_processor_id_reg = 20; /* XContext */ + smp_processor_id_sel = 0; +#else +# ifdef CONFIG_32BIT + smp_processor_id_shift = 25; + smp_processor_id_reg = 4; /* Context */ + smp_processor_id_sel = 0; +# endif +# ifdef CONFIG_64BIT + smp_processor_id_shift = 26; + smp_processor_id_reg = 4; /* Context */ + smp_processor_id_sel = 0; +# endif +#endif + /* Get smp_processor_id */ + UASM_i_MFC0(p, K0, smp_processor_id_reg, smp_processor_id_sel); + UASM_i_SRL_SAFE(p, K0, K0, smp_processor_id_shift); + + /* handler_reg_save index in K0 */ + UASM_i_SLL(p, K0, K0, ilog2(sizeof(struct tlb_reg_save))); + + UASM_i_LA(p, K1, (long)&handler_reg_save); + UASM_i_ADDU(p, K0, K0, K1); + } else { + UASM_i_LA(p, K0, (long)&handler_reg_save); + } + /* K0 now points to save area, save $1 and $2 */ + UASM_i_SW(p, 1, offsetof(struct tlb_reg_save, a), K0); + UASM_i_SW(p, 2, offsetof(struct tlb_reg_save, b), K0); + + r.r1 = K1; + r.r2 = 1; + r.r3 = 2; + return r; +} + +static void __cpuinit build_restore_work_registers(u32 **p) +{ + if (scratch_reg > 0) { + UASM_i_MFC0(p, 1, 31, scratch_reg); + return; + } + /* K0 already points to save area, restore $1 and $2 */ + UASM_i_LW(p, 1, offsetof(struct tlb_reg_save, a), K0); + UASM_i_LW(p, 2, offsetof(struct tlb_reg_save, b), K0); +} + #ifndef CONFIG_MIPS_PGD_C0_CONTEXT /* @@ -1160,9 +1239,6 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) memset(relocs, 0, sizeof(relocs)); memset(final_handler, 0, sizeof(final_handler)); - if (scratch_reg == 0) - scratch_reg = allocate_kscratch(); - if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) { htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1, scratch_reg); @@ -1462,22 +1538,28 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, */ static void __cpuinit build_pte_present(u32 **p, struct uasm_reloc **r, - unsigned int pte, unsigned int ptr, enum label_id lid) + int pte, int ptr, int scratch, enum label_id lid) { + int t = scratch >= 0 ? scratch : pte; + if (kernel_uses_smartmips_rixi) { if (use_bbit_insns()) { uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid); uasm_i_nop(p); } else { - uasm_i_andi(p, pte, pte, _PAGE_PRESENT); - uasm_il_beqz(p, r, pte, lid); - iPTE_LW(p, pte, ptr); + uasm_i_andi(p, t, pte, _PAGE_PRESENT); + uasm_il_beqz(p, r, t, lid); + if (pte == t) + /* You lose the SMP race :-(*/ + iPTE_LW(p, pte, ptr); } } else { - uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); - uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); - uasm_il_bnez(p, r, pte, lid); - iPTE_LW(p, pte, ptr); + uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_READ); + uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_READ); + uasm_il_bnez(p, r, t, lid); + if (pte == t) + /* You lose the SMP race :-(*/ + iPTE_LW(p, pte, ptr); } } @@ -1497,19 +1579,19 @@ build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte, */ static void __cpuinit build_pte_writable(u32 **p, struct uasm_reloc **r, - unsigned int pte, unsigned int ptr, enum label_id lid) + unsigned int pte, unsigned int ptr, int scratch, + enum label_id lid) { - if (use_bbit_insns()) { - uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid); - uasm_i_nop(p); - uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid); - uasm_i_nop(p); - } else { - uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); - uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); - uasm_il_bnez(p, r, pte, lid); + int t = scratch >= 0 ? scratch : pte; + + uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_WRITE); + uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_WRITE); + uasm_il_bnez(p, r, t, lid); + if (pte == t) + /* You lose the SMP race :-(*/ iPTE_LW(p, pte, ptr); - } + else + uasm_i_nop(p); } /* Make PTE writable, update software status bits as well, then store @@ -1531,15 +1613,19 @@ build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte, */ static void __cpuinit build_pte_modifiable(u32 **p, struct uasm_reloc **r, - unsigned int pte, unsigned int ptr, enum label_id lid) + unsigned int pte, unsigned int ptr, int scratch, + enum label_id lid) { if (use_bbit_insns()) { uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid); uasm_i_nop(p); } else { - uasm_i_andi(p, pte, pte, _PAGE_WRITE); - uasm_il_beqz(p, r, pte, lid); - iPTE_LW(p, pte, ptr); + int t = scratch >= 0 ? scratch : pte; + uasm_i_andi(p, t, pte, _PAGE_WRITE); + uasm_il_beqz(p, r, t, lid); + if (pte == t) + /* You lose the SMP race :-(*/ + iPTE_LW(p, pte, ptr); } } @@ -1619,7 +1705,7 @@ static void __cpuinit build_r3000_tlb_load_handler(void) memset(relocs, 0, sizeof(relocs)); build_r3000_tlbchange_handler_head(&p, K0, K1); - build_pte_present(&p, &r, K0, K1, label_nopage_tlbl); + build_pte_present(&p, &r, K0, K1, -1, label_nopage_tlbl); uasm_i_nop(&p); /* load delay */ build_make_valid(&p, &r, K0, K1); build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); @@ -1649,7 +1735,7 @@ static void __cpuinit build_r3000_tlb_store_handler(void) memset(relocs, 0, sizeof(relocs)); build_r3000_tlbchange_handler_head(&p, K0, K1); - build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs); + build_pte_writable(&p, &r, K0, K1, -1, label_nopage_tlbs); uasm_i_nop(&p); /* load delay */ build_make_write(&p, &r, K0, K1); build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); @@ -1673,13 +1759,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) u32 *p = handle_tlbm; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; + struct work_registers wr; memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); build_r3000_tlbchange_handler_head(&p, K0, K1); - build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm); + build_pte_modifiable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbm); uasm_i_nop(&p); /* load delay */ build_make_write(&p, &r, K0, K1); build_r3000_pte_reload_tlbwi(&p, K0, K1); @@ -1702,15 +1789,16 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) /* * R4000 style TLB load/store/modify handlers. */ -static void __cpuinit +static struct work_registers __cpuinit build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, - struct uasm_reloc **r, unsigned int pte, - unsigned int ptr) + struct uasm_reloc **r) { + struct work_registers wr = build_get_work_registers(p); + #ifdef CONFIG_64BIT - build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */ + build_get_pmde64(p, l, r, wr.r1, wr.r2); /* get pmd in ptr */ #else - build_get_pgde32(p, pte, ptr); /* get pgd in ptr */ + build_get_pgde32(p, wr.r1, wr.r2); /* get pgd in ptr */ #endif #ifdef CONFIG_HUGETLB_PAGE @@ -1719,21 +1807,22 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, * instead contains the tlb pte. Check the PAGE_HUGE bit and * see if we need to jump to huge tlb processing. */ - build_is_huge_pte(p, r, pte, ptr, label_tlb_huge_update); + build_is_huge_pte(p, r, wr.r1, wr.r2, label_tlb_huge_update); #endif - UASM_i_MFC0(p, pte, C0_BADVADDR); - UASM_i_LW(p, ptr, 0, ptr); - UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2); - uasm_i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2); - UASM_i_ADDU(p, ptr, ptr, pte); + UASM_i_MFC0(p, wr.r1, C0_BADVADDR); + UASM_i_LW(p, wr.r2, 0, wr.r2); + UASM_i_SRL(p, wr.r1, wr.r1, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2); + uasm_i_andi(p, wr.r1, wr.r1, (PTRS_PER_PTE - 1) << PTE_T_LOG2); + UASM_i_ADDU(p, wr.r2, wr.r2, wr.r1); #ifdef CONFIG_SMP uasm_l_smp_pgtable_change(l, *p); #endif - iPTE_LW(p, pte, ptr); /* get even pte */ + iPTE_LW(p, wr.r1, wr.r2); /* get even pte */ if (!m4kc_tlbp_war()) build_tlb_probe_entry(p); + return wr; } static void __cpuinit @@ -1746,6 +1835,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, build_update_entries(p, tmp, ptr); build_tlb_write_entry(p, l, r, tlb_indexed); uasm_l_leave(l, *p); + build_restore_work_registers(p); uasm_i_eret(p); /* return from trap */ #ifdef CONFIG_64BIT @@ -1758,6 +1848,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void) u32 *p = handle_tlbl; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; + struct work_registers wr; memset(handle_tlbl, 0, sizeof(handle_tlbl)); memset(labels, 0, sizeof(labels)); @@ -1777,8 +1868,8 @@ static void __cpuinit build_r4000_tlb_load_handler(void) /* No need for uasm_i_nop */ } - build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); - build_pte_present(&p, &r, K0, K1, label_nopage_tlbl); + wr = build_r4000_tlbchange_handler_head(&p, &l, &r); + build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl); if (m4kc_tlbp_war()) build_tlb_probe_entry(&p); @@ -1788,44 +1879,43 @@ static void __cpuinit build_r4000_tlb_load_handler(void) * have triggered it. Skip the expensive test.. */ if (use_bbit_insns()) { - uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID), + uasm_il_bbit0(&p, &r, wr.r1, ilog2(_PAGE_VALID), label_tlbl_goaround1); } else { - uasm_i_andi(&p, K0, K0, _PAGE_VALID); - uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1); + uasm_i_andi(&p, wr.r3, wr.r1, _PAGE_VALID); + uasm_il_beqz(&p, &r, wr.r3, label_tlbl_goaround1); } uasm_i_nop(&p); uasm_i_tlbr(&p); /* Examine entrylo 0 or 1 based on ptr. */ if (use_bbit_insns()) { - uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8); + uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); } else { - uasm_i_andi(&p, K0, K1, sizeof(pte_t)); - uasm_i_beqz(&p, K0, 8); + uasm_i_andi(&p, wr.r3, wr.r2, sizeof(pte_t)); + uasm_i_beqz(&p, wr.r3, 8); } - - UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/ - UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */ + /* load it in the delay slot*/ + UASM_i_MFC0(&p, wr.r3, C0_ENTRYLO0); + /* load it if ptr is odd */ + UASM_i_MFC0(&p, wr.r3, C0_ENTRYLO1); /* - * If the entryLo (now in K0) is valid (bit 1), RI or + * If the entryLo (now in wr.r3) is valid (bit 1), RI or * XI must have triggered it. */ if (use_bbit_insns()) { - uasm_il_bbit1(&p, &r, K0, 1, label_nopage_tlbl); - /* Reload the PTE value */ - iPTE_LW(&p, K0, K1); + uasm_il_bbit1(&p, &r, wr.r3, 1, label_nopage_tlbl); + uasm_i_nop(&p); uasm_l_tlbl_goaround1(&l, p); } else { - uasm_i_andi(&p, K0, K0, 2); - uasm_il_bnez(&p, &r, K0, label_nopage_tlbl); - uasm_l_tlbl_goaround1(&l, p); - /* Reload the PTE value */ - iPTE_LW(&p, K0, K1); + uasm_i_andi(&p, wr.r3, wr.r3, 2); + uasm_il_bnez(&p, &r, wr.r3, label_nopage_tlbl); + uasm_i_nop(&p); } + uasm_l_tlbl_goaround1(&l, p); } - build_make_valid(&p, &r, K0, K1); - build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + build_make_valid(&p, &r, wr.r1, wr.r2); + build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); #ifdef CONFIG_HUGETLB_PAGE /* @@ -1833,8 +1923,8 @@ static void __cpuinit build_r4000_tlb_load_handler(void) * spots a huge page. */ uasm_l_tlb_huge_update(&l, p); - iPTE_LW(&p, K0, K1); - build_pte_present(&p, &r, K0, K1, label_nopage_tlbl); + iPTE_LW(&p, wr.r1, wr.r2); + build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl); build_tlb_probe_entry(&p); if (kernel_uses_smartmips_rixi) { @@ -1843,50 +1933,51 @@ static void __cpuinit build_r4000_tlb_load_handler(void) * have triggered it. Skip the expensive test.. */ if (use_bbit_insns()) { - uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID), + uasm_il_bbit0(&p, &r, wr.r1, ilog2(_PAGE_VALID), label_tlbl_goaround2); } else { - uasm_i_andi(&p, K0, K0, _PAGE_VALID); - uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2); + uasm_i_andi(&p, wr.r3, wr.r1, _PAGE_VALID); + uasm_il_beqz(&p, &r, wr.r3, label_tlbl_goaround2); } uasm_i_nop(&p); uasm_i_tlbr(&p); /* Examine entrylo 0 or 1 based on ptr. */ if (use_bbit_insns()) { - uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8); + uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); } else { - uasm_i_andi(&p, K0, K1, sizeof(pte_t)); - uasm_i_beqz(&p, K0, 8); + uasm_i_andi(&p, wr.r3, wr.r2, sizeof(pte_t)); + uasm_i_beqz(&p, wr.r3, 8); } - UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/ - UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */ + /* load it in the delay slot*/ + UASM_i_MFC0(&p, wr.r3, C0_ENTRYLO0); + /* load it if ptr is odd */ + UASM_i_MFC0(&p, wr.r3, C0_ENTRYLO1); /* - * If the entryLo (now in K0) is valid (bit 1), RI or + * If the entryLo (now in wr.r3) is valid (bit 1), RI or * XI must have triggered it. */ if (use_bbit_insns()) { - uasm_il_bbit0(&p, &r, K0, 1, label_tlbl_goaround2); + uasm_il_bbit0(&p, &r, wr.r3, 1, label_tlbl_goaround2); } else { - uasm_i_andi(&p, K0, K0, 2); - uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2); + uasm_i_andi(&p, wr.r3, wr.r3, 2); + uasm_il_beqz(&p, &r, wr.r3, label_tlbl_goaround2); } - /* Reload the PTE value */ - iPTE_LW(&p, K0, K1); /* * We clobbered C0_PAGEMASK, restore it. On the other branch * it is restored in build_huge_tlb_write_entry. */ - build_restore_pagemask(&p, &r, K0, label_nopage_tlbl, 0); + build_restore_pagemask(&p, &r, wr.r3, label_nopage_tlbl, 0); uasm_l_tlbl_goaround2(&l, p); } - uasm_i_ori(&p, K0, K0, (_PAGE_ACCESSED | _PAGE_VALID)); - build_huge_handler_tail(&p, &r, &l, K0, K1); + uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); #endif uasm_l_nopage_tlbl(&l, p); + build_restore_work_registers(&p); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_nop(&p); @@ -1905,17 +1996,18 @@ static void __cpuinit build_r4000_tlb_store_handler(void) u32 *p = handle_tlbs; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; + struct work_registers wr; memset(handle_tlbs, 0, sizeof(handle_tlbs)); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); - build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); - build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs); + wr = build_r4000_tlbchange_handler_head(&p, &l, &r); + build_pte_writable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbs); if (m4kc_tlbp_war()) build_tlb_probe_entry(&p); - build_make_write(&p, &r, K0, K1); - build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + build_make_write(&p, &r, wr.r1, wr.r2); + build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); #ifdef CONFIG_HUGETLB_PAGE /* @@ -1923,15 +2015,16 @@ static void __cpuinit build_r4000_tlb_store_handler(void) * build_r4000_tlbchange_handler_head spots a huge page. */ uasm_l_tlb_huge_update(&l, p); - iPTE_LW(&p, K0, K1); - build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs); + iPTE_LW(&p, wr.r1, wr.r2); + build_pte_writable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbs); build_tlb_probe_entry(&p); - uasm_i_ori(&p, K0, K0, + uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, K0, K1); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); #endif uasm_l_nopage_tlbs(&l, p); + build_restore_work_registers(&p); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); @@ -1950,18 +2043,19 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) u32 *p = handle_tlbm; struct uasm_label *l = labels; struct uasm_reloc *r = relocs; + struct work_registers wr; memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(labels, 0, sizeof(labels)); memset(relocs, 0, sizeof(relocs)); - build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); - build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm); + wr = build_r4000_tlbchange_handler_head(&p, &l, &r); + build_pte_modifiable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbm); if (m4kc_tlbp_war()) build_tlb_probe_entry(&p); /* Present and writable bits set, set accessed and dirty bits. */ - build_make_write(&p, &r, K0, K1); - build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + build_make_write(&p, &r, wr.r1, wr.r2); + build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); #ifdef CONFIG_HUGETLB_PAGE /* @@ -1969,15 +2063,16 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) * build_r4000_tlbchange_handler_head spots a huge page. */ uasm_l_tlb_huge_update(&l, p); - iPTE_LW(&p, K0, K1); - build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm); + iPTE_LW(&p, wr.r1, wr.r2); + build_pte_modifiable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbm); build_tlb_probe_entry(&p); - uasm_i_ori(&p, K0, K0, + uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, K0, K1); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); #endif uasm_l_nopage_tlbm(&l, p); + build_restore_work_registers(&p); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_nop(&p); @@ -2036,6 +2131,7 @@ void __cpuinit build_tlb_refill_handler(void) default: if (!run_once) { + scratch_reg = allocate_kscratch(); #ifdef CONFIG_MIPS_PGD_C0_CONTEXT build_r4000_setup_pgd(); #endif diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 31180c3..4b988b9 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -28,6 +28,7 @@ #include <asm/io.h> #include <asm/system.h> #include <asm/cacheflush.h> +#include <asm/smp-ops.h> #include <asm/traps.h> #include <asm/gcmpregs.h> @@ -358,15 +359,14 @@ void __init prom_init(void) #ifdef CONFIG_SERIAL_8250_CONSOLE console_config(); #endif -#ifdef CONFIG_MIPS_CMP /* Early detection of CMP support */ if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ)) - register_smp_ops(&cmp_smp_ops); - else -#endif -#ifdef CONFIG_MIPS_MT_SMP - register_smp_ops(&vsmp_smp_ops); -#endif + if (!register_cmp_smp_ops()) + return; + + if (!register_vsmp_smp_ops()) + return; + #ifdef CONFIG_MIPS_MT_SMTC register_smp_ops(&msmtc_smp_ops); #endif diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index 49a38b0..1efc8c3 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c @@ -152,7 +152,7 @@ int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, * runtime code can anyway deal with the null set */ printk(KERN_WARNING - "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); + "IRQ affinity leaves no legal CPU for IRQ %d\n", d->irq); /* Do any generic SMTC IRQ affinity setup */ smtc_set_irq_affinity(d->irq, tmask); diff --git a/arch/mips/netlogic/Platform b/arch/mips/netlogic/Platform new file mode 100644 index 0000000..f87c164 --- /dev/null +++ b/arch/mips/netlogic/Platform @@ -0,0 +1,11 @@ +# +# NETLOGIC includes +# +cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic +cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic + +# +# NETLOGIC XLR/XLS SoC, Simulator and boards +# +core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/ +load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000 diff --git a/arch/mips/netlogic/xlr/irq.c b/arch/mips/netlogic/xlr/irq.c index 1446d58e..521bb73 100644 --- a/arch/mips/netlogic/xlr/irq.c +++ b/arch/mips/netlogic/xlr/irq.c @@ -209,7 +209,7 @@ void __init init_xlr_irqs(void) irq_set_chip_and_handler(i, &xlr_pic, handle_level_irq); else irq_set_chip_and_handler(i, &nlm_cpu_intr, - handle_level_irq); + handle_percpu_irq); } #ifdef CONFIG_SMP irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr, diff --git a/arch/mips/netlogic/xlr/smp.c b/arch/mips/netlogic/xlr/smp.c index b495a7f..d842bce 100644 --- a/arch/mips/netlogic/xlr/smp.c +++ b/arch/mips/netlogic/xlr/smp.c @@ -87,17 +87,7 @@ void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) /* IRQ_IPI_SMP_RESCHEDULE handler */ void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) { - set_need_resched(); -} - -void nlm_common_ipi_handler(int irq, struct pt_regs *regs) -{ - if (irq == IRQ_IPI_SMP_FUNCTION) { - smp_call_function_interrupt(); - } else { - /* Announce that we are for reschduling */ - set_need_resched(); - } + scheduler_ipi(); } /* @@ -122,6 +112,7 @@ void nlm_smp_finish(void) #ifdef notyet nlm_common_msgring_cpu_init(); #endif + local_irq_enable(); } void nlm_cpus_done(void) diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c index 64246c9..71adac3 100644 --- a/arch/mips/nxp/pnx8550/common/setup.c +++ b/arch/mips/nxp/pnx8550/common/setup.c @@ -140,6 +140,4 @@ void __init plat_mem_setup(void) PNX8XXX_UART_LCR_8BIT; ip3106_baud(UART_BASE, pnx8550_console_port) = 5; } - - return; } diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c index b7f0fb0..99929cf 100644 --- a/arch/mips/pci/ops-nile4.c +++ b/arch/mips/pci/ops-nile4.c @@ -4,7 +4,6 @@ #include <asm/bootinfo.h> #include <asm/lasat/lasat.h> -#include <asm/gt64120.h> #include <asm/nile4.h> #define PCI_ACCESS_READ 0 diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index 2413ea6..0abfbe0 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c @@ -228,13 +228,11 @@ void __init prom_init(void) */ msp_serial_setup(); -#ifdef CONFIG_MIPS_MT_SMP - register_smp_ops(&vsmp_smp_ops); -#endif - + if (register_vsmp_smp_ops()) { #ifdef CONFIG_MIPS_MT_SMTC - register_smp_ops(&msp_smtc_smp_ops); + register_smp_ops(&msp_smtc_smp_ops); #endif + } #ifdef CONFIG_PMCTWILED /* diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c index 43cb394..fccd6b0 100644 --- a/arch/mips/pnx8550/common/setup.c +++ b/arch/mips/pnx8550/common/setup.c @@ -139,6 +139,4 @@ void __init plat_mem_setup(void) PNX8XXX_UART_LCR_8BIT; ip3106_baud(UART_BASE, pnx8550_console_port) = 5; } - - return; } diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 041fc1a..a969eb82 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -251,28 +251,22 @@ static struct platform_device *rb532_devs[] = { static void __init parse_mac_addr(char *macstr) { - int i, j; - unsigned char result, value; + int i, h, l; for (i = 0; i < 6; i++) { - result = 0; - if (i != 5 && *(macstr + 2) != ':') return; - for (j = 0; j < 2; j++) { - if (isxdigit(*macstr) - && (value = - isdigit(*macstr) ? *macstr - - '0' : toupper(*macstr) - 'A' + 10) < 16) { - result = result * 16 + value; - macstr++; - } else - return; - } + h = hex_to_bin(*macstr++); + if (h == -1) + return; + + l = hex_to_bin(*macstr++); + if (l == -1) + return; macstr++; - korina_dev0_data.mac[i] = result; + korina_dev0_data.mac[i] = (h << 4) + l; } } diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c index bc4fa8d..005c29e 100644 --- a/arch/mips/sgi-ip27/ip27-nmi.c +++ b/arch/mips/sgi-ip27/ip27-nmi.c @@ -3,7 +3,7 @@ #include <linux/nodemask.h> #include <linux/spinlock.h> #include <linux/smp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/sn/types.h> #include <asm/sn/addrs.h> #include <asm/sn/nmi.h> diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index be4460a..76ee045 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -123,6 +123,13 @@ static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask, } #endif +static void disable_sb1250_irq(struct irq_data *d) +{ + unsigned int irq = d->irq; + + sb1250_mask_irq(sb1250_irq_owner[irq], irq); +} + static void enable_sb1250_irq(struct irq_data *d) { unsigned int irq = d->irq; @@ -180,6 +187,7 @@ static struct irq_chip sb1250_irq_type = { .name = "SB1250-IMR", .irq_mask_ack = ack_sb1250_irq, .irq_unmask = enable_sb1250_irq, + .irq_mask = disable_sb1250_irq, #ifdef CONFIG_SMP .irq_set_affinity = sb1250_set_affinity #endif diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h index 9d773a6..b9a8f84 100644 --- a/arch/mn10300/include/asm/atomic.h +++ b/arch/mn10300/include/asm/atomic.h @@ -260,16 +260,15 @@ static inline void atomic_dec(atomic_t *v) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) -#define atomic_add_unless(v, a, u) \ +#define __atomic_add_unless(v, a, u) \ ({ \ int c, old; \ c = atomic_read(v); \ while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ c = old; \ - c != (u); \ + c; \ }) -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /** * atomic_clear_mask - Atomically clear bits in memory @@ -344,8 +343,6 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *addr) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> - #endif /* __KERNEL__ */ #endif /* CONFIG_SMP */ #endif /* _ASM_ATOMIC_H */ diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index 0939462..596bb27 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h @@ -227,12 +227,7 @@ int ffs(int x) #include <asm-generic/bitops/find.h> #include <asm-generic/bitops/sched.h> #include <asm-generic/bitops/hweight.h> - -#define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit((nr), (addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit((nr), (addr)) - +#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/le.h> #endif /* __KERNEL__ */ diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h index c8f6c82..c67c2b5 100644 --- a/arch/mn10300/include/asm/mmu_context.h +++ b/arch/mn10300/include/asm/mmu_context.h @@ -22,7 +22,7 @@ #ifndef _ASM_MMU_CONTEXT_H #define _ASM_MMU_CONTEXT_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pgalloc.h> #include <asm/tlbflush.h> #include <asm-generic/mm_hooks.h> diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h index 4c1b5cc..f7b3c9a 100644 --- a/arch/mn10300/include/asm/processor.h +++ b/arch/mn10300/include/asm/processor.h @@ -127,7 +127,6 @@ static inline void start_thread(struct pt_regs *regs, { struct thread_info *ti = current_thread_info(); struct pt_regs *frame0; - set_fs(USER_DS); frame0 = thread_info_to_uregs(ti); frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h index b696181..55b79ef 100644 --- a/arch/mn10300/include/asm/ptrace.h +++ b/arch/mn10300/include/asm/ptrace.h @@ -89,7 +89,6 @@ struct pt_regs { #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) #define instruction_pointer(regs) ((regs)->pc) #define user_stack_pointer(regs) ((regs)->sp) -extern void show_regs(struct pt_regs *); #define arch_has_single_step() (1) diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h index 9342915..1ae580f 100644 --- a/arch/mn10300/include/asm/spinlock.h +++ b/arch/mn10300/include/asm/spinlock.h @@ -11,7 +11,7 @@ #ifndef _ASM_SPINLOCK_H #define _ASM_SPINLOCK_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/rwlock.h> #include <asm/page.h> diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h index 8ff3e5a..94b4c5e 100644 --- a/arch/mn10300/include/asm/system.h +++ b/arch/mn10300/include/asm/system.h @@ -19,7 +19,7 @@ #include <linux/kernel.h> #include <linux/irqflags.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #if !defined(CONFIG_LAZY_SAVE_FPU) struct fpu_state_struct; diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index ae435e1..3e3620d 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -589,7 +589,7 @@ ENTRY(sys_call_table) .long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* was nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c index c5e12bf..a45f0c7 100644 --- a/arch/mn10300/kernel/mn10300-watchdog.c +++ b/arch/mn10300/kernel/mn10300-watchdog.c @@ -19,7 +19,7 @@ #include <linux/nmi.h> #include <asm/processor.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/intctl-regs.h> #include <asm/rtc-regs.h> #include <asm/div64.h> diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c index bd3e5e7..9220a75a 100644 --- a/arch/mn10300/kernel/traps.c +++ b/arch/mn10300/kernel/traps.c @@ -30,7 +30,7 @@ #include <asm/system.h> #include <linux/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> #include <asm/pgalloc.h> #include <asm/cacheflush.h> diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c index eef989c..f9bb8cb 100644 --- a/arch/mn10300/mm/misalignment.c +++ b/arch/mn10300/mm/misalignment.c @@ -26,7 +26,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> #include <asm/pgalloc.h> #include <asm/cpu-regs.h> diff --git a/arch/mn10300/proc-mn2ws0050/proc-init.c b/arch/mn10300/proc-mn2ws0050/proc-init.c index c58249b..fe6e249 100644 --- a/arch/mn10300/proc-mn2ws0050/proc-init.c +++ b/arch/mn10300/proc-mn2ws0050/proc-init.c @@ -18,7 +18,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> #include <asm/pgalloc.h> #include <asm/busctl-regs.h> diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h index 052f877..60b4722 100644 --- a/arch/openrisc/include/asm/dma-mapping.h +++ b/arch/openrisc/include/asm/dma-mapping.h @@ -31,7 +31,6 @@ #define DMA_ERROR_CODE (~(dma_addr_t)0x0) -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) @@ -47,6 +46,12 @@ dma_addr_t or1k_map_page(struct device *dev, struct page *page, void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs); +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); void or1k_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir); @@ -98,6 +103,51 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, true); } +static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + int i, ents; + struct scatterlist *s; + + for_each_sg(sg, s, nents, i) + kmemcheck_mark_initialized(sg_virt(s), s->length); + BUG_ON(!valid_dma_direction(dir)); + ents = or1k_map_sg(dev, sg, nents, dir, NULL); + debug_dma_map_sg(dev, sg, nents, ents, dir); + + return ents; +} + +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + debug_dma_unmap_sg(dev, sg, nents, dir); + or1k_unmap_sg(dev, sg, nents, dir, NULL); +} + +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t addr; + + kmemcheck_mark_initialized(page_address(page) + offset, size); + BUG_ON(!valid_dma_direction(dir)); + addr = or1k_map_page(dev, page, offset, size, dir, NULL); + debug_dma_map_page(dev, page, offset, size, dir, addr, false); + + return addr; +} + +static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + or1k_unmap_page(dev, addr, size, dir, NULL); + debug_dma_unmap_page(dev, addr, size, dir, true); +} + static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) @@ -119,7 +169,12 @@ static inline void dma_sync_single_for_device(struct device *dev, static inline int dma_supported(struct device *dev, u64 dma_mask) { /* Support 32 bit DMA mask exclusively */ - return dma_mask == 0xffffffffULL; + return dma_mask == DMA_BIT_MASK(32); +} + +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; } static inline int dma_set_mask(struct device *dev, u64 dma_mask) diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/asm/sigcontext.h index 54a5c50..b79c2b1 100644 --- a/arch/openrisc/include/asm/sigcontext.h +++ b/arch/openrisc/include/asm/sigcontext.h @@ -23,16 +23,11 @@ /* This struct is saved by setup_frame in signal.c, to keep the current context while a signal handler is executed. It's restored by sys_sigreturn. - - To keep things simple, we use pt_regs here even though normally you just - specify the list of regs to save. Then we can use copy_from_user on the - entire regs instead of a bunch of get_user's as well... */ struct sigcontext { - struct pt_regs regs; /* needs to be first */ + struct user_regs_struct regs; /* needs to be first */ unsigned long oldmask; - unsigned long usp; /* usp before stacking this gunk on it */ }; #endif /* __ASM_OPENRISC_SIGCONTEXT_H */ diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index 968d3ee..f1c8ee2 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c @@ -154,6 +154,33 @@ void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, /* Nothing special to do here... */ } +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nents, i) { + s->dma_address = or1k_map_page(dev, sg_page(s), s->offset, + s->length, dir, NULL); + } + + return nents; +} + +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nents, i) { + or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL); + } +} + void or1k_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) @@ -187,5 +214,4 @@ static int __init dma_init(void) return 0; } - fs_initcall(dma_init); diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 5f759c7..95207ab 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -52,31 +52,25 @@ struct rt_sigframe { static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { unsigned int err = 0; - unsigned long old_usp; /* Alwys make any pending restarted system call return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - /* restore the regs from &sc->regs (same as sc, since regs is first) + /* + * Restore the regs from &sc->regs. * (sc is already checked for VERIFY_READ since the sigframe was * checked in sys_sigreturn previously) */ - - if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) + if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long))) + goto badframe; + if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long))) + goto badframe; + if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long))) goto badframe; /* make sure the SM-bit is cleared so user-mode cannot fool us */ regs->sr &= ~SPR_SR_SM; - /* restore the old USP as it was before we stacked the sc etc. - * (we cannot just pop the sigcontext since we aligned the sp and - * stuff after pushing it) - */ - - err |= __get_user(old_usp, &sc->usp); - - regs->sp = old_usp; - /* TODO: the other ports use regs->orig_XX to disable syscall checks * after this completes, but we don't use that mechanism. maybe we can * use it now ? @@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) { int err = 0; - unsigned long usp = regs->sp; - /* copy the regs. they are first in sc so we can use sc directly */ + /* copy the regs */ - err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); + err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long)); + err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long)); + err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long)); /* then some other stuff */ err |= __put_user(mask, &sc->oldmask); - err |= __put_user(usp, &sc->usp); - return err; } diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 65adc86..e077b0b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -15,6 +15,7 @@ config PARISC select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select IRQ_PER_CPU + select ARCH_HAVE_NMI_SAFE_CMPXCHG help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index f819559..4054b31 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -197,15 +197,15 @@ static __inline__ int atomic_read(const atomic_t *v) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -217,10 +217,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v)))) #define atomic_sub(i,v) ((void)(__atomic_add_return(-(i),(v)))) @@ -259,10 +258,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) -static __inline__ int +static __inline__ s64 __atomic64_add_return(s64 i, atomic64_t *v) { - int ret; + s64 ret; unsigned long flags; _atomic_spin_lock_irqsave(v, flags); @@ -317,7 +316,7 @@ atomic64_read(const atomic64_t *v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) { @@ -336,12 +335,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -#else /* CONFIG_64BIT */ - -#include <asm-generic/atomic64.h> - #endif /* !CONFIG_64BIT */ -#include <asm-generic/atomic-long.h> #endif /* _ASM_PARISC_ATOMIC_H_ */ diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h index 43c516f..8c9b631 100644 --- a/arch/parisc/include/asm/bitops.h +++ b/arch/parisc/include/asm/bitops.h @@ -8,7 +8,7 @@ #include <linux/compiler.h> #include <asm/types.h> /* for BITS_PER_LONG/SHIFT_PER_LONG */ #include <asm/byteorder.h> -#include <asm/atomic.h> +#include <linux/atomic.h> /* * HP-PARISC specific bit operations @@ -223,14 +223,7 @@ static __inline__ int fls(int x) #ifdef __KERNEL__ #include <asm-generic/bitops/le.h> - -/* '3' is bits per byte */ -#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3) - -#define ext2_set_bit_atomic(l,nr,addr) \ - test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) -#define ext2_clear_bit_atomic(l,nr,addr) \ - test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 67a33cc..2388bdb 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -5,11 +5,14 @@ #include <linux/futex.h> #include <linux/uaccess.h> +#include <asm/atomic.h> #include <asm/errno.h> static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { + unsigned long int flags; + u32 val; int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; @@ -18,21 +21,58 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) return -EFAULT; pagefault_disable(); + _atomic_spin_lock_irqsave(uaddr, flags); + switch (op) { case FUTEX_OP_SET: + /* *(int *)UADDR2 = OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) + ret = put_user(oparg, uaddr); + break; case FUTEX_OP_ADD: + /* *(int *)UADDR2 += OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval + oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_OR: + /* *(int *)UADDR2 |= OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval | oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_ANDN: + /* *(int *)UADDR2 &= ~OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval & ~oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_XOR: + /* *(int *)UADDR2 ^= OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval ^ oparg; + ret = put_user(val, uaddr); + } + break; default: ret = -ENOSYS; } + _atomic_spin_unlock_irqrestore(uaddr, flags); + pagefault_enable(); if (!ret) { @@ -54,7 +94,9 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { + int ret; u32 val; + unsigned long flags; /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is * our gateway page, and causes no end of trouble... @@ -65,12 +107,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; - if (get_user(val, uaddr)) - return -EFAULT; - if (val == oldval && put_user(newval, uaddr)) - return -EFAULT; + /* HPPA has no cmpxchg in hardware and therefore the + * best we can do here is use an array of locks. The + * lock selected is based on a hash of the userspace + * address. This should scale to a couple of CPUs. + */ + + _atomic_spin_lock_irqsave(uaddr, flags); + + ret = get_user(val, uaddr); + + if (!ret && val == oldval) + ret = put_user(newval, uaddr); + *uval = val; - return 0; + + _atomic_spin_unlock_irqrestore(uaddr, flags); + + return ret; } #endif /*__KERNEL__*/ diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h index 354b2ac..59be257 100644 --- a/arch/parisc/include/asm/mmu_context.h +++ b/arch/parisc/include/asm/mmu_context.h @@ -3,7 +3,7 @@ #include <linux/mm.h> #include <linux/sched.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm-generic/mm_hooks.h> diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h index 7f09533..250ae35 100644 --- a/arch/parisc/include/asm/ptrace.h +++ b/arch/parisc/include/asm/ptrace.h @@ -56,7 +56,6 @@ struct pt_regs { #define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) #define user_stack_pointer(regs) ((regs)->gr[30]) unsigned long profile_pc(struct pt_regs *); -extern void show_regs(struct pt_regs *); #endif /* __KERNEL__ */ diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 3392de3..d61de64 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -821,8 +821,9 @@ #define __NR_open_by_handle_at (__NR_Linux + 326) #define __NR_syncfs (__NR_Linux + 327) #define __NR_setns (__NR_Linux + 328) +#define __NR_sendmmsg (__NR_Linux + 329) -#define __NR_Linux_syscalls (__NR_setns + 1) +#define __NR_Linux_syscalls (__NR_sendmmsg + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index df65366..a7bb757 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -31,7 +31,7 @@ #include <linux/string.h> EXPORT_SYMBOL(memset); -#include <asm/atomic.h> +#include <linux/atomic.h> EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); EXPORT_SYMBOL(__cmpxchg_u32); diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 828305f..32d5884 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -33,7 +33,7 @@ #include <linux/ftrace.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/current.h> #include <asm/delay.h> #include <asm/tlbflush.h> diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 34a4f5a..3735abd 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -259,7 +259,7 @@ ENTRY_SAME(ni_syscall) /* query_module */ ENTRY_SAME(poll) /* structs contain pointers and an in_addr... */ - ENTRY_COMP(nfsservctl) + ENTRY_SAME(ni_syscall) /* was nfsservctl */ ENTRY_SAME(setresgid) /* 170 */ ENTRY_SAME(getresgid) ENTRY_SAME(prctl) @@ -427,6 +427,7 @@ ENTRY_COMP(open_by_handle_at) ENTRY_SAME(syncfs) ENTRY_SAME(setns) + ENTRY_COMP(sendmmsg) /* Nothing yet */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 8b58bf0..f19e660 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -33,7 +33,7 @@ #include <asm/irq.h> #include <asm/traps.h> #include <asm/unaligned.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> #include <asm/pdc.h> #include <asm/pdc_chassis.h> diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 353963d..a8bffd8 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/spinlock.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #ifdef CONFIG_SMP arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 374c475..6926b61 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -136,6 +136,7 @@ config PPC select HAVE_SYSCALL_TRACEPOINTS select HAVE_BPF_JIT if (PPC64 && NET) select HAVE_ARCH_JUMP_LABEL + select ARCH_HAVE_NMI_SAFE_CMPXCHG config EARLY_PRINTK bool diff --git a/arch/powerpc/boot/dts/p1023rds.dts b/arch/powerpc/boot/dts/p1023rds.dts index bfa96aa..d9b7767 100644 --- a/arch/powerpc/boot/dts/p1023rds.dts +++ b/arch/powerpc/boot/dts/p1023rds.dts @@ -387,7 +387,7 @@ #size-cells = <1>; compatible = "cfi-flash"; reg = <0x0 0x0 0x02000000>; - bank-width = <1>; + bank-width = <2>; device-width = <1>; partition@0 { label = "ramdisk"; diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig index 980ff8f..3ff5a81 100644 --- a/arch/powerpc/configs/85xx/p1023rds_defconfig +++ b/arch/powerpc/configs/85xx/p1023rds_defconfig @@ -171,3 +171,4 @@ CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_FSL_CAAM=y diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index 10562a5..4311d02 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -185,3 +185,4 @@ CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_FSL_CAAM=y diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index d322835..c92c204 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -100,5 +100,8 @@ CONFIG_DEBUG_INFO=y CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_VIRQ_DEBUG=y CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_TALITOS=y +CONFIG_CRYPTO_DEV_FSL_CAAM=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index fcd85d2..a3467bf 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -139,6 +139,7 @@ CONFIG_SND=y CONFIG_SND_INTEL8X0=y # CONFIG_SND_PPC is not set # CONFIG_SND_USB is not set +CONFIG_SND_SOC=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 908c941..9693f6e 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -140,6 +140,7 @@ CONFIG_SND=y CONFIG_SND_INTEL8X0=y # CONFIG_SND_PPC is not set # CONFIG_SND_USB is not set +CONFIG_SND_SOC=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index b8f152e..e2a4c26 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -181,21 +181,21 @@ static __inline__ int atomic_dec_return(atomic_t *v) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int t; __asm__ __volatile__ ( PPC_RELEASE_BARRIER -"1: lwarx %0,0,%1 # atomic_add_unless\n\ +"1: lwarx %0,0,%1 # __atomic_add_unless\n\ cmpw 0,%0,%3 \n\ beq- 2f \n\ add %0,%2,%0 \n" @@ -209,10 +209,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) : "r" (&v->counter), "r" (a), "r" (u) : "cc", "memory"); - return t != u; + return t; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) @@ -444,7 +443,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) { @@ -452,7 +451,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) __asm__ __volatile__ ( PPC_RELEASE_BARRIER -"1: ldarx %0,0,%1 # atomic_add_unless\n\ +"1: ldarx %0,0,%1 # __atomic_add_unless\n\ cmpd 0,%0,%3 \n\ beq- 2f \n\ add %0,%2,%0 \n" @@ -470,11 +469,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -#else /* __powerpc64__ */ -#include <asm-generic/atomic64.h> - #endif /* __powerpc64__ */ -#include <asm-generic/atomic-long.h> #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_ATOMIC_H_ */ diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index f18c6d9..e137afc 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -327,10 +327,7 @@ unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset); /* Bitmap functions for the ext2 filesystem */ -#define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit_le((nr), (unsigned long*)addr) -#define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit_le((nr), (unsigned long*)addr) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/sched.h> diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h index 2cc41c7..63f2a22 100644 --- a/arch/powerpc/include/asm/emulated_ops.h +++ b/arch/powerpc/include/asm/emulated_ops.h @@ -18,7 +18,7 @@ #ifndef _ASM_POWERPC_EMULATED_OPS_H #define _ASM_POWERPC_EMULATED_OPS_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/perf_event.h> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index c57a28e..c0e1bc3 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -14,7 +14,7 @@ #include <linux/radix-tree.h> #include <asm/types.h> -#include <asm/atomic.h> +#include <linux/atomic.h> /* Define a way to iterate across irqs. */ diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h index 1f780b9..938986e 100644 --- a/arch/powerpc/include/asm/jump_label.h +++ b/arch/powerpc/include/asm/jump_label.h @@ -22,7 +22,6 @@ static __always_inline bool arch_static_branch(struct jump_label_key *key) asm goto("1:\n\t" "nop\n\t" ".pushsection __jump_table, \"aw\"\n\t" - ".align 4\n\t" JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" ".popsection \n\t" : : "i" (key) : : l_yes); @@ -41,7 +40,6 @@ struct jump_entry { jump_label_t code; jump_label_t target; jump_label_t key; - jump_label_t pad; }; #endif /* _ASM_POWERPC_JUMP_LABEL_H */ diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index 6857af5..bffd062 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -3,17 +3,7 @@ #include <asm/page.h> -/* - * If CONFIG_RELOCATABLE is enabled we can place the kdump kernel anywhere. - * To keep enough space in the RMO for the first stage kernel on 64bit, we - * place it at 64MB. If CONFIG_RELOCATABLE is not enabled we must place - * the second stage at 32MB. - */ -#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC64) -#define KDUMP_KERNELBASE 0x4000000 -#else #define KDUMP_KERNELBASE 0x2000000 -#endif /* How many bytes to reserve at zero for kdump. The reserve limit should * be greater or equal to the trampoline's end address. diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h index c2410af..b8da913 100644 --- a/arch/powerpc/include/asm/local.h +++ b/arch/powerpc/include/asm/local.h @@ -2,7 +2,7 @@ #define _ARCH_POWERPC_LOCAL_H #include <linux/percpu.h> -#include <asm/atomic.h> +#include <linux/atomic.h> typedef struct { diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 90bd3ed..56b879a 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -10,58 +10,10 @@ #include <linux/pci.h> #include <linux/list.h> #include <linux/ioport.h> +#include <asm-generic/pci-bridge.h> struct device_node; -enum { - /* Force re-assigning all resources (ignore firmware - * setup completely) - */ - PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001, - - /* Re-assign all bus numbers */ - PPC_PCI_REASSIGN_ALL_BUS = 0x00000002, - - /* Do not try to assign, just use existing setup */ - PPC_PCI_PROBE_ONLY = 0x00000004, - - /* Don't bother with ISA alignment unless the bridge has - * ISA forwarding enabled - */ - PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, - - /* Enable domain numbers in /proc */ - PPC_PCI_ENABLE_PROC_DOMAINS = 0x00000010, - /* ... except for domain 0 */ - PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020, -}; -#ifdef CONFIG_PCI -extern unsigned int ppc_pci_flags; - -static inline void ppc_pci_set_flags(int flags) -{ - ppc_pci_flags = flags; -} - -static inline void ppc_pci_add_flags(int flags) -{ - ppc_pci_flags |= flags; -} - -static inline int ppc_pci_has_flag(int flag) -{ - return (ppc_pci_flags & flag); -} -#else -static inline void ppc_pci_set_flags(int flags) { } -static inline void ppc_pci_add_flags(int flags) { } -static inline int ppc_pci_has_flag(int flag) -{ - return 0; -} -#endif - - /* * Structure of a PCI controller (host bridge) */ diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 1f52268..49c3de5 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -44,7 +44,7 @@ struct pci_dev; * bus numbers (don't do that on ppc64 yet !) */ #define pcibios_assign_all_busses() \ - (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS)) + (pci_has_flag(PCI_REASSIGN_ALL_BUS)) static inline void pcibios_set_master(struct pci_dev *dev) { diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index b823536..b5c9190 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -18,7 +18,7 @@ */ #include <linux/types.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #define HAVE_ARCH_DEVTREE_FIXUPS diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index e8aaf6f..559da19 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1003,7 +1003,6 @@ #define PV_970 0x0039 #define PV_POWER5 0x003A #define PV_POWER5p 0x003B -#define PV_POWER7 0x003F #define PV_970FX 0x003C #define PV_POWER6 0x003E #define PV_POWER7 0x003F @@ -1024,13 +1023,16 @@ #define mtmsrd(v) __mtmsrd((v), 0) #define mtmsr(v) mtmsrd(v) #else -#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v) : "memory") +#define mtmsr(v) asm volatile("mtmsr %0" : \ + : "r" ((unsigned long)(v)) \ + : "memory") #endif #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ : "=r" (rval)); rval;}) -#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)\ +#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ + : "r" ((unsigned long)(v)) \ : "memory") #ifdef __powerpc64__ diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index f6736b7..fa0d27a 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -171,7 +171,7 @@ SYSCALL_SPU(setresuid) SYSCALL_SPU(getresuid) SYSCALL(ni_syscall) SYSCALL_SPU(poll) -COMPAT_SYS(nfsservctl) +SYSCALL(ni_syscall) SYSCALL_SPU(setresgid) SYSCALL_SPU(getresgid) COMPAT_SYS_SPU(prctl) diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h index 2dc595d..e30a13d 100644 --- a/arch/powerpc/include/asm/system.h +++ b/arch/powerpc/include/asm/system.h @@ -120,7 +120,6 @@ extern void do_dabr(struct pt_regs *regs, unsigned long address, unsigned long error_code); #endif extern void print_backtrace(unsigned long *); -extern void show_regs(struct pt_regs * regs); extern void flush_instruction_cache(void); extern void hard_reset_now(void); extern void poweroff_now(void); diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 9fb9332..fa44ff5 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -2051,7 +2051,8 @@ static struct cpu_spec __initdata cpu_specs[] = { static struct cpu_spec the_cpu_spec; -static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s) +static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, + struct cpu_spec *s) { struct cpu_spec *t = &the_cpu_spec; struct cpu_spec old; @@ -2114,6 +2115,8 @@ static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s) t->cpu_setup(offset, t); } #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ + + return t; } struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) @@ -2124,10 +2127,8 @@ struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) s = PTRRELOC(s); for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) { - if ((pvr & s->pvr_mask) == s->pvr_value) { - setup_cpu_spec(offset, s); - return s; - } + if ((pvr & s->pvr_mask) == s->pvr_value) + return setup_cpu_spec(offset, s); } BUG(); diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index 1577434..b25f632 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c @@ -117,6 +117,7 @@ void ioport_unmap(void __iomem *addr) EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); +#ifdef CONFIG_PCI void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) { resource_size_t start = pci_resource_start(dev, bar); @@ -146,3 +147,4 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); +#endif /* CONFIG_PCI */ diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index 6658a15..9ce1672 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -136,12 +136,16 @@ void __init reserve_crashkernel(void) crashk_res.start = KDUMP_KERNELBASE; #else if (!crashk_res.start) { +#ifdef CONFIG_PPC64 /* - * unspecified address, choose a region of specified size - * can overlap with initrd (ignoring corruption when retained) - * ppc64 requires kernel and some stacks to be in first segemnt + * On 64bit we split the RMO in half but cap it at half of + * a small SLB (128MB) since the crash kernel needs to place + * itself and some stacks to be in the first segment. */ + crashk_res.start = min(0x80000000ULL, (ppc64_rma_size / 2)); +#else crashk_res.start = KDUMP_KERNELBASE; +#endif } crash_base = PAGE_ALIGN(crashk_res.start); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 2458218..59dbf6a 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -26,7 +26,7 @@ #include <asm/topology.h> #include <asm/pci-bridge.h> #include <asm/ppc-pci.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #ifdef CONFIG_PPC_OF_PLATFORM_PCI diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 0187829..32656f1 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -50,7 +50,7 @@ static int global_phb_number; /* Global phb counter */ resource_size_t isa_mem_base; /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ -unsigned int ppc_pci_flags = 0; +unsigned int pci_flags = 0; static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; @@ -842,9 +842,9 @@ int pci_proc_domain(struct pci_bus *bus) { struct pci_controller *hose = pci_bus_to_host(bus); - if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) + if (!pci_has_flag(PCI_ENABLE_PROC_DOMAINS)) return 0; - if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) + if (pci_has_flag(PCI_COMPAT_DOMAIN_0)) return hose->global_number != 0; return 1; } @@ -920,13 +920,13 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) struct resource *res = dev->resource + i; if (!res->flags) continue; - /* On platforms that have PPC_PCI_PROBE_ONLY set, we don't + /* On platforms that have PCI_PROBE_ONLY set, we don't * consider 0 as an unassigned BAR value. It's technically * a valid value, but linux doesn't like it... so when we can * re-assign things, we do so, but if we can't, we keep it * around and hope for the best... */ - if (res->start == 0 && !(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { + if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) { pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", pci_name(dev), i, (unsigned long long)res->start, @@ -973,7 +973,7 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, int i; /* We don't do anything if PCI_PROBE_ONLY is set */ - if (ppc_pci_flags & PPC_PCI_PROBE_ONLY) + if (pci_has_flag(PCI_PROBE_ONLY)) return 0; /* Job is a bit different between memory and IO */ @@ -1143,7 +1143,7 @@ void __devinit pci_fixup_cardbus(struct pci_bus *bus) static int skip_isa_ioresource_align(struct pci_dev *dev) { - if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && + if (pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN) && !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) return 1; return 0; @@ -1271,7 +1271,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) * and as such ensure proper re-allocation * later. */ - if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC) + if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) goto clear_resource; pr = pci_find_parent_resource(bus->self, res); if (pr == res) { @@ -1456,7 +1456,7 @@ void __init pcibios_resource_survey(void) list_for_each_entry(b, &pci_root_buses, node) pcibios_allocate_bus_resources(b); - if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) { + if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { pcibios_allocate_resources(0); pcibios_allocate_resources(1); } @@ -1465,7 +1465,7 @@ void __init pcibios_resource_survey(void) * the low IO area and the VGA memory area if they intersect the * bus available resources to avoid allocating things on top of them */ - if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { list_for_each_entry(b, &pci_root_buses, node) pcibios_reserve_legacy_regions(b); } @@ -1473,7 +1473,7 @@ void __init pcibios_resource_survey(void) /* Now, if the platform didn't decide to blindly trust the firmware, * we proceed to assigning things that were left unassigned */ - if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { pr_debug("PCI: Assigning unassigned resources...\n"); pci_assign_unassigned_resources(); } diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index e2f24ba..bb15451 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -230,7 +230,7 @@ static int __init pcibios_init(void) printk(KERN_INFO "PCI: Probing PCI hardware\n"); - if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS) + if (pci_has_flag(PCI_REASSIGN_ALL_BUS)) pci_assign_all_buses = 1; /* Scan all of the recorded PCI controllers. */ diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index fc6452b..ab34046 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -55,12 +55,12 @@ static int __init pcibios_init(void) ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; if (pci_probe_only) - ppc_pci_flags |= PPC_PCI_PROBE_ONLY; + pci_add_flags(PCI_PROBE_ONLY); /* On ppc64, we always enable PCI domains and we keep domain 0 * backward compatible in /proc for video cards */ - ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0; + pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0); /* Scan all of the recorded PCI controllers. */ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c index d05ae42..564c1d8 100644 --- a/arch/powerpc/kernel/perf_callchain.c +++ b/arch/powerpc/kernel/perf_callchain.c @@ -154,8 +154,12 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) ((unsigned long)ptr & 7)) return -EFAULT; - if (!__get_user_inatomic(*ret, ptr)) + pagefault_disable(); + if (!__get_user_inatomic(*ret, ptr)) { + pagefault_enable(); return 0; + } + pagefault_enable(); return read_user_stack_slow(ptr, ret, 8); } @@ -166,8 +170,12 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) ((unsigned long)ptr & 3)) return -EFAULT; - if (!__get_user_inatomic(*ret, ptr)) + pagefault_disable(); + if (!__get_user_inatomic(*ret, ptr)) { + pagefault_enable(); return 0; + } + pagefault_enable(); return read_user_stack_slow(ptr, ret, 4); } @@ -294,11 +302,17 @@ static inline int current_is_64bit(void) */ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) { + int rc; + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || ((unsigned long)ptr & 3)) return -EFAULT; - return __get_user_inatomic(*ret, ptr); + pagefault_disable(); + rc = __get_user_inatomic(*ret, ptr); + pagefault_enable(); + + return rc; } static inline void perf_callchain_user_64(struct perf_callchain_entry *entry, diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 7d28f54..f5ae872 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -18,7 +18,7 @@ #include <asm/cacheflush.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/checksum.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index c016033..a909f4e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) } if (addr == 0) return 0; - RELOC(alloc_bottom) = addr; + RELOC(alloc_bottom) = addr + size; prom_debug(" -> %x\n", addr); prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); @@ -1830,11 +1830,13 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, if (room > DEVTREE_CHUNK_SIZE) room = DEVTREE_CHUNK_SIZE; if (room < PAGE_SIZE) - prom_panic("No memory for flatten_device_tree (no room)"); + prom_panic("No memory for flatten_device_tree " + "(no room)\n"); chunk = alloc_up(room, 0); if (chunk == 0) - prom_panic("No memory for flatten_device_tree (claim failed)"); - *mem_end = RELOC(alloc_top); + prom_panic("No memory for flatten_device_tree " + "(claim failed)\n"); + *mem_end = chunk + room; } ret = (void *)*mem_start; @@ -2042,7 +2044,7 @@ static void __init flatten_device_tree(void) /* * Check how much room we have between alloc top & bottom (+/- a - * few pages), crop to 4Mb, as this is our "chuck" size + * few pages), crop to 1MB, as this is our "chunk" size */ room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000; if (room > DEVTREE_CHUNK_SIZE) @@ -2053,7 +2055,7 @@ static void __init flatten_device_tree(void) mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); if (mem_start == 0) prom_panic("Can't allocate initial device-tree chunk\n"); - mem_end = RELOC(alloc_top); + mem_end = mem_start + room; /* Get root of tree */ root = call_prom("peer", 1, 1, (phandle)0); diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 0e0ea94..d5ca823 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -39,7 +39,7 @@ #include <asm/udbg.h> #include <asm/syscalls.h> #include <asm/smp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/mmu.h> #include <asm/topology.h> diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 54e66da..6cd8f01 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -291,7 +291,7 @@ void __init find_and_init_phbs(void) prop = of_get_property(of_chosen, "linux,pci-assign-all-buses", NULL); if (prop && *prop) - ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; + pci_add_flags(PCI_REASSIGN_ALL_BUS); #endif /* CONFIG_PPC32 */ } } diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 67f6c3b..481ef06 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -27,7 +27,7 @@ #include <asm/rtas.h> #include <asm/prom.h> #include <asm/nvram.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/machdep.h> diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index 03e45c4..640de83 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -11,7 +11,7 @@ #include <linux/unistd.h> #include <linux/init.h> #include <linux/slab.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> #include <asm/time.h> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index f932f8a..7bf2187 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -33,7 +33,7 @@ #include <linux/topology.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 6dd3358..de29501 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1251,7 +1251,7 @@ BEGIN_FTR_SECTION reg = 0 .rept 32 li r6,reg*16+VCPU_VSRS - stxvd2x reg,r6,r3 + STXVD2X(reg,r6,r3) reg = reg + 1 .endr FTR_SECTION_ELSE @@ -1313,7 +1313,7 @@ BEGIN_FTR_SECTION reg = 0 .rept 32 li r7,reg*16+VCPU_VSRS - lxvd2x reg,r7,r4 + LXVD2X(reg,r7,r4) reg = reg + 1 .endr FTR_SECTION_ELSE diff --git a/arch/powerpc/platforms/40x/ep405.c b/arch/powerpc/platforms/40x/ep405.c index 4058fd1..b0389bb 100644 --- a/arch/powerpc/platforms/40x/ep405.c +++ b/arch/powerpc/platforms/40x/ep405.c @@ -100,7 +100,7 @@ static void __init ep405_setup_arch(void) /* Find & init the BCSR CPLD */ ep405_init_bcsr(); - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); } static int __init ep405_probe(void) diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c index 2521d93..e8dd5c5 100644 --- a/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c @@ -61,7 +61,7 @@ static const char *board[] __initdata = { static int __init ppc40x_probe(void) { if (of_flat_dt_match(of_get_flat_dt_root(), board)) { - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } diff --git a/arch/powerpc/platforms/40x/walnut.c b/arch/powerpc/platforms/40x/walnut.c index 335df91..8b691df 100644 --- a/arch/powerpc/platforms/40x/walnut.c +++ b/arch/powerpc/platforms/40x/walnut.c @@ -51,7 +51,7 @@ static int __init walnut_probe(void) if (!of_flat_dt_is_compatible(root, "ibm,walnut")) return 0; - ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } diff --git a/arch/powerpc/platforms/44x/canyonlands.c b/arch/powerpc/platforms/44x/canyonlands.c index afc5e8e..e300dd4 100644 --- a/arch/powerpc/platforms/44x/canyonlands.c +++ b/arch/powerpc/platforms/44x/canyonlands.c @@ -55,7 +55,7 @@ static int __init ppc460ex_probe(void) { unsigned long root = of_get_flat_dt_root(); if (of_flat_dt_is_compatible(root, "amcc,canyonlands")) { - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } return 0; diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c index 88b9117..6a4232b 100644 --- a/arch/powerpc/platforms/44x/ebony.c +++ b/arch/powerpc/platforms/44x/ebony.c @@ -54,7 +54,7 @@ static int __init ebony_probe(void) if (!of_flat_dt_is_compatible(root, "ibm,ebony")) return 0; - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c index c81c19c..8d22027 100644 --- a/arch/powerpc/platforms/44x/ppc44x_simple.c +++ b/arch/powerpc/platforms/44x/ppc44x_simple.c @@ -72,7 +72,7 @@ static int __init ppc44x_probe(void) for (i = 0; i < ARRAY_SIZE(board); i++) { if (of_flat_dt_is_compatible(root, board[i])) { - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } } diff --git a/arch/powerpc/platforms/44x/sam440ep.c b/arch/powerpc/platforms/44x/sam440ep.c index a78e8eb..9e09b83 100644 --- a/arch/powerpc/platforms/44x/sam440ep.c +++ b/arch/powerpc/platforms/44x/sam440ep.c @@ -51,7 +51,7 @@ static int __init sam440ep_probe(void) if (!of_flat_dt_is_compatible(root, "acube,sam440ep")) return 0; - ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC); + pci_set_flags(PCI_REASSIGN_ALL_RSRC); return 1; } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 5f5e693..bfb11e0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -371,7 +371,7 @@ mpc52xx_add_bridge(struct device_node *node) pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); if (of_address_to_resource(node, 0, &rsrc) != 0) { printk(KERN_ERR "Can't get %s resources\n", node->full_name); diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c index 9761a59..d111b02 100644 --- a/arch/powerpc/platforms/82xx/pq2.c +++ b/arch/powerpc/platforms/82xx/pq2.c @@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np) if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) goto err; - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(np); if (!hose) diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index f8fa2fc..c55129f 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -28,7 +28,7 @@ #include <linux/of_device.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 93e60f1..32a5289 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -27,7 +27,7 @@ #include <linux/of_device.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 81e44fa..6b45969 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -26,7 +26,7 @@ #include <linux/of_platform.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index c1b1dc5..041c517 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -26,7 +26,7 @@ #include <linux/of_platform.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 81c052b..934cc8c4 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -34,7 +34,7 @@ #include <linux/of_device.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index 49023db..af41d8c 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c @@ -28,7 +28,7 @@ #include <linux/of_platform.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 6299a2a..2bf9978 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -31,7 +31,7 @@ #include <asm/system.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 747d1ee..973b3f4 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -36,7 +36,7 @@ #include <linux/memblock.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index ecdd8c0..d07dcb7 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -34,7 +34,7 @@ #include <asm/system.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/time.h> #include <asm/io.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index d0af7fb..b9ba861 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -24,7 +24,7 @@ source "arch/powerpc/platforms/wsp/Kconfig" config KVM_GUEST bool "KVM Guest support" - default y + default n ---help--- This option enables various optimizations for running under the KVM hypervisor. Overhead for the kernel when not running inside KVM should diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c index d809836..7f92096 100644 --- a/arch/powerpc/platforms/cell/cpufreq_spudemand.c +++ b/arch/powerpc/platforms/cell/cpufreq_spudemand.c @@ -24,7 +24,7 @@ #include <linux/sched.h> #include <linux/timer.h> #include <linux/workqueue.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/machdep.h> #include <asm/spu.h> diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index dbb641e..f2e1dfe 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c @@ -28,7 +28,7 @@ #include <linux/cpu.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 0c87bcd..bf4d41d 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -24,7 +24,7 @@ #include <linux/mm.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/spu.h> #include <asm/spu_csa.h> #include "spufs.h" diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 3f65443..83285c5 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -199,7 +199,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d printk ("RTAS supporting Pegasos OF not found, please upgrade" " your firmware\n"); } - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); /* keep the reference to the root node */ } diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index a800122..feab30b 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c @@ -18,7 +18,7 @@ #include <linux/spinlock.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c index 2df48c2..8bda9be 100644 --- a/arch/powerpc/platforms/iseries/smp.c +++ b/arch/powerpc/platforms/iseries/smp.c @@ -29,7 +29,7 @@ #include <linux/cpu.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index d679964..c2f3e86 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -12,7 +12,7 @@ #include <linux/backlight.h> #include <linux/adb.h> #include <linux/pmu.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/prom.h> #include <asm/backlight.h> diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 41a80a4..5cc8385 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -732,7 +732,7 @@ static void __init setup_bandit(struct pci_controller *hose, static int __init setup_uninorth(struct pci_controller *hose, struct resource *addr) { - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); has_uninorth = 1; hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); @@ -998,7 +998,7 @@ void __init pmac_pci_init(void) struct device_node *np, *root; struct device_node *ht = NULL; - ppc_pci_set_flags(PPC_PCI_CAN_SKIP_ISA_ALIGN); + pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); root = of_find_node_by_path("/"); if (root == NULL) { @@ -1057,7 +1057,7 @@ void __init pmac_pci_init(void) * some offset between bus number and domains for now when we * assign all busses should help for now */ - if (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS)) + if (pci_has_flag(PCI_REASSIGN_ALL_BUS)) pcibios_assign_bus_offset = 0x10; #endif } diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index d15fca3..9a521dc 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -35,7 +35,7 @@ #include <linux/compiler.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/code-patching.h> #include <asm/irq.h> #include <asm/page.h> diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index e919007..0e86563 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; - unregister_dtl(hwcpu, __pa(dtl->buf)); + unregister_dtl(hwcpu); } static u64 dtl_current_index(struct dtl *dtl) diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 46b55cf..ada6e07 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -31,7 +31,7 @@ #include <linux/spinlock.h> #include <linux/of.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/eeh.h> #include <asm/eeh_event.h> #include <asm/io.h> diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index 8ed0d2d..fc5ae76 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -25,7 +25,7 @@ #include <linux/rbtree.h> #include <linux/slab.h> #include <linux/spinlock.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pci-bridge.h> #include <asm/ppc-pci.h> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index bc02885..83a3ca2 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -135,7 +135,7 @@ static void pseries_mach_cpu_die(void) get_lppaca()->idle = 0; if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { - unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + unregister_slb_shadow(hwcpu); /* * Call to start_secondary_resume() will not return. @@ -150,7 +150,7 @@ static void pseries_mach_cpu_die(void) WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE); set_cpu_current_state(cpu, CPU_STATE_OFFLINE); - unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + unregister_slb_shadow(hwcpu); rtas_stop_self(); /* Should never get here... */ diff --git a/arch/powerpc/platforms/pseries/io_event_irq.c b/arch/powerpc/platforms/pseries/io_event_irq.c index c829e60..2c4dd1f 100644 --- a/arch/powerpc/platforms/pseries/io_event_irq.c +++ b/arch/powerpc/platforms/pseries/io_event_irq.c @@ -212,17 +212,15 @@ static int __init ioei_init(void) struct device_node *np; ioei_check_exception_token = rtas_token("check-exception"); - if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) { - pr_warning("IO Event IRQ not supported on this system !\n"); + if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) return -ENODEV; - } + np = of_find_node_by_path("/event-sources/ibm,io-events"); if (np) { request_event_sources_irqs(np, ioei_interrupt, "IO_EVENT"); + pr_info("IBM I/O event interrupts enabled\n"); of_node_put(np); } else { - pr_err("io_event_irq: No ibm,io-events on system! " - "IO Event interrupt disabled.\n"); return -ENODEV; } return 0; diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c index 54cf3a4a..7d94bdc 100644 --- a/arch/powerpc/platforms/pseries/kexec.c +++ b/arch/powerpc/platforms/pseries/kexec.c @@ -25,20 +25,30 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) { /* Don't risk a hypervisor call if we're crashing */ if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { - unsigned long addr; + int ret; + int cpu = smp_processor_id(); + int hwcpu = hard_smp_processor_id(); - addr = __pa(get_slb_shadow()); - if (unregister_slb_shadow(hard_smp_processor_id(), addr)) - printk("SLB shadow buffer deregistration of " - "cpu %u (hw_cpu_id %d) failed\n", - smp_processor_id(), - hard_smp_processor_id()); + if (get_lppaca()->dtl_enable_mask) { + ret = unregister_dtl(hwcpu); + if (ret) { + pr_err("WARNING: DTL deregistration for cpu " + "%d (hw %d) failed with %d\n", + cpu, hwcpu, ret); + } + } + + ret = unregister_slb_shadow(hwcpu); + if (ret) { + pr_err("WARNING: SLB shadow buffer deregistration " + "for cpu %d (hw %d) failed with %d\n", + cpu, hwcpu, ret); + } - addr = __pa(get_lppaca()); - if (unregister_vpa(hard_smp_processor_id(), addr)) { - printk("VPA deregistration of cpu %u (hw_cpu_id %d) " - "failed\n", smp_processor_id(), - hard_smp_processor_id()); + ret = unregister_vpa(hwcpu); + if (ret) { + pr_err("WARNING: VPA deregistration for cpu %d " + "(hw %d) failed with %d\n", cpu, hwcpu, ret); } } } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index f7205d3..c9a29da 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -67,9 +67,8 @@ void vpa_init(int cpu) ret = register_vpa(hwcpu, addr); if (ret) { - printk(KERN_ERR "WARNING: vpa_init: VPA registration for " - "cpu %d (hw %d) of area %lx returns %ld\n", - cpu, hwcpu, addr, ret); + pr_err("WARNING: VPA registration for cpu %d (hw %d) of area " + "%lx failed with %ld\n", cpu, hwcpu, addr, ret); return; } /* @@ -80,10 +79,9 @@ void vpa_init(int cpu) if (firmware_has_feature(FW_FEATURE_SPLPAR)) { ret = register_slb_shadow(hwcpu, addr); if (ret) - printk(KERN_ERR - "WARNING: vpa_init: SLB shadow buffer " - "registration for cpu %d (hw %d) of area %lx " - "returns %ld\n", cpu, hwcpu, addr, ret); + pr_err("WARNING: SLB shadow buffer registration for " + "cpu %d (hw %d) of area %lx failed with %ld\n", + cpu, hwcpu, addr, ret); } /* @@ -100,8 +98,9 @@ void vpa_init(int cpu) dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; ret = register_dtl(hwcpu, __pa(dtl)); if (ret) - pr_warn("DTL registration failed for cpu %d (%ld)\n", - cpu, ret); + pr_err("WARNING: DTL registration of cpu %d (hw %d) " + "failed with %ld\n", smp_processor_id(), + hwcpu, ret); lppaca_of(cpu).dtl_enable_mask = 2; } } @@ -204,7 +203,7 @@ static void pSeries_lpar_hptab_clear(void) unsigned long ptel; } ptes[4]; long lpar_rc; - int i, j; + unsigned long i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 4bf2120..41c24c1 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -53,9 +53,9 @@ static inline long vpa_call(unsigned long flags, unsigned long cpu, return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); } -static inline long unregister_vpa(unsigned long cpu, unsigned long vpa) +static inline long unregister_vpa(unsigned long cpu) { - return vpa_call(0x5, cpu, vpa); + return vpa_call(0x5, cpu, 0); } static inline long register_vpa(unsigned long cpu, unsigned long vpa) @@ -63,9 +63,9 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa) return vpa_call(0x1, cpu, vpa); } -static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa) +static inline long unregister_slb_shadow(unsigned long cpu) { - return vpa_call(0x7, cpu, vpa); + return vpa_call(0x7, cpu, 0); } static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) @@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) return vpa_call(0x3, cpu, vpa); } -static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) +static inline long unregister_dtl(unsigned long cpu) { - return vpa_call(0x6, cpu, vpa); + return vpa_call(0x6, cpu, 0); } static inline long register_dtl(unsigned long cpu, unsigned long vpa) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index d00e529..0969fd9 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -324,8 +324,9 @@ static int alloc_dispatch_logs(void) dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; ret = register_dtl(hard_smp_processor_id(), __pa(dtl)); if (ret) - pr_warn("DTL registration failed for boot cpu %d (%d)\n", - smp_processor_id(), ret); + pr_err("WARNING: DTL registration of cpu %d (hw %d) failed " + "with %d\n", smp_processor_id(), + hard_smp_processor_id(), ret); get_paca()->lppaca_ptr->dtl_enable_mask = 2; return 0; diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 1672db2..4e44c4d 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -27,7 +27,7 @@ #include <linux/cpu.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 3bba8bd..4ce547e 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -351,7 +351,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(dev); if (!hose) return -ENOMEM; @@ -640,7 +640,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev) " bus 0\n", dev->full_name); } - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(dev); if (!hose) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 2de8551..c65f75a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -54,6 +54,7 @@ #define ODSR_CLEAR 0x1c00 #define LTLEECSR_ENABLE_ALL 0xFFC000FC #define ESCSR_CLEAR 0x07120204 +#define IECSR_CLEAR 0x80000000 #define RIO_PORT1_EDCSR 0x0640 #define RIO_PORT2_EDCSR 0x0680 @@ -1089,11 +1090,11 @@ static void port_error_handler(struct rio_mport *port, int offset) if (offset == 0) { out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0); - out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0); + out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), IECSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR); } else { out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0); - out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0); + out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), IECSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR); } } diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 265313e..2d66275 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -32,7 +32,7 @@ #include <linux/fs_uart_pd.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/time.h> diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c index cf27df6..08abe91 100644 --- a/arch/powerpc/sysdev/grackle.c +++ b/arch/powerpc/sysdev/grackle.c @@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose) { setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); if (of_machine_is_compatible("PowerMac1,1")) - ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS); + pci_add_flags(PCI_REASSIGN_ALL_BUS); if (of_machine_is_compatible("AAPL,PowerBook1998")) grackle_set_loop_snoop(hose, 1); #if 0 /* Disabled for now, HW problems ??? */ diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 2ec4f3b..dbfe96b 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -655,8 +655,6 @@ struct ppc4xx_pciex_hwops static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; -#ifdef CONFIG_44x - static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port, unsigned int sdr_offset, unsigned int mask, @@ -688,6 +686,7 @@ static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port) return 0; } + static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) { printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); @@ -718,6 +717,8 @@ static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); } +#ifdef CONFIG_44x + /* Check various reset bits of the 440SPe PCIe core */ static int __init ppc440spe_pciex_check_reset(struct device_node *np) { @@ -1977,7 +1978,7 @@ static int __init ppc4xx_pci_find_bridges(void) { struct device_node *np; - ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0; + pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0); #ifdef CONFIG_PPC4xx_PCI_EXPRESS for_each_compatible_node(np, NULL, "ibm,plb-pciex") diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index ee05680..9f51f97 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -23,7 +23,7 @@ #include <asm/tsi108.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/prom.h> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c03fef7..ed5cb5a 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -81,6 +81,7 @@ config S390 select INIT_ALL_POSSIBLE select HAVE_IRQ_WORK select HAVE_PERF_EVENTS + select ARCH_HAVE_NMI_SAFE_CMPXCHG select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA @@ -273,11 +274,11 @@ config MARCH_Z10 on older machines. config MARCH_Z196 - bool "IBM zEnterprise 196" + bool "IBM zEnterprise 114 and 196" help - Select this to enable optimizations for IBM zEnterprise 196 - (2817 series). The kernel will be slightly faster but will not work - on older machines. + Select this to enable optimizations for IBM zEnterprise 114 and 196 + (2818 and 2817 series). The kernel will be slightly faster but will + not work on older machines. endchoice diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index d9db138..8517d2a 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -93,7 +93,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) return old; } -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -105,10 +105,9 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != u; + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #undef __CS_LOOP @@ -332,6 +331,4 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v) #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() -#include <asm-generic/atomic-long.h> - #endif /* __ARCH_S390_ATOMIC__ */ diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 667c6e9..e5beb49 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -832,10 +832,7 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit_le(nr, addr) -#define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit_le(nr, addr) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 5e95d95..97cc440 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -167,5 +167,6 @@ enum diag308_rc { }; extern int diag308(unsigned long subcode, void *addr); +extern void diag308_reset(void); #endif /* _ASM_S390_IPL_H */ diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index f26280d..e85c911 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -18,6 +18,7 @@ void system_call(void); void pgm_check_handler(void); void mcck_int_handler(void); void io_int_handler(void); +void psw_restart_int_handler(void); #ifdef CONFIG_32BIT @@ -150,7 +151,10 @@ struct _lowcore { */ __u32 ipib; /* 0x0e00 */ __u32 ipib_checksum; /* 0x0e04 */ - __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */ + + /* 64 bit save area */ + __u64 save_area_64; /* 0x0e08 */ + __u8 pad_0x0e10[0x0f00-0x0e10]; /* 0x0e10 */ /* Extended facility list */ __u64 stfle_fac_list[32]; /* 0x0f00 */ @@ -286,7 +290,10 @@ struct _lowcore { */ __u64 ipib; /* 0x0e00 */ __u32 ipib_checksum; /* 0x0e08 */ - __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */ + + /* 64 bit save area */ + __u64 save_area_64; /* 0x0e0c */ + __u8 pad_0x0e14[0x0f00-0x0e14]; /* 0x0e14 */ /* Extended facility list */ __u64 stfle_fac_list[32]; /* 0x0f00 */ diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 55dfcc8..a4b6229 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -119,14 +119,12 @@ struct stack_frame { * Do necessary setup to start up a new thread. */ #define start_thread(regs, new_psw, new_stackp) do { \ - set_fs(USER_DS); \ regs->psw.mask = psw_user_bits; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ } while (0) #define start_thread31(regs, new_psw, new_stackp) do { \ - set_fs(USER_DS); \ regs->psw.mask = psw_user32_bits; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 9ad628a..62fd80c 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -539,7 +539,6 @@ struct user_regs_struct * These are defined as per linux/ptrace.h, which see. */ #define arch_has_single_step() (1) -extern void show_regs(struct pt_regs * regs); #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index d382629..6582f69 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -113,6 +113,7 @@ extern void pfault_fini(void); extern void cmma_init(void); extern int memcpy_real(void *, void *, size_t); +extern void copy_to_absolute_zero(void *dest, void *src, size_t count); #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 05d8f38..532fd43 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -27,12 +27,9 @@ int main(void) BLANK(); DEFINE(__TASK_pid, offsetof(struct task_struct, pid)); BLANK(); - DEFINE(__THREAD_per_cause, - offsetof(struct task_struct, thread.per_event.cause)); - DEFINE(__THREAD_per_address, - offsetof(struct task_struct, thread.per_event.address)); - DEFINE(__THREAD_per_paid, - offsetof(struct task_struct, thread.per_event.paid)); + DEFINE(__THREAD_per_cause, offsetof(struct task_struct, thread.per_event.cause)); + DEFINE(__THREAD_per_address, offsetof(struct task_struct, thread.per_event.address)); + DEFINE(__THREAD_per_paid, offsetof(struct task_struct, thread.per_event.paid)); BLANK(); DEFINE(__TI_task, offsetof(struct thread_info, task)); DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); @@ -142,6 +139,7 @@ int main(void) DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area)); DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area)); DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area)); + DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64)); #ifdef CONFIG_32BIT DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr)); #else /* CONFIG_32BIT */ diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 209938c..2554356 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -76,6 +76,42 @@ s390_base_pgm_handler_fn: .quad 0 .previous +# +# Calls diag 308 subcode 1 and continues execution +# +# The following conditions must be ensured before calling this function: +# * Prefix register = 0 +# * Lowcore protection is disabled +# +ENTRY(diag308_reset) + larl %r4,.Lctlregs # Save control registers + stctg %c0,%c15,0(%r4) + larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 + lghi %r3,0 + lg %r4,0(%r4) # Save PSW + sturg %r4,%r3 # Use sturg, because of large pages + lghi %r1,1 + diag %r1,%r1,0x308 +.Lrestart_part2: + lhi %r0,0 # Load r0 with zero + lhi %r1,2 # Use mode 2 = ESAME (dump) + sigp %r1,%r0,0x12 # Switch to ESAME mode + sam64 # Switch to 64 bit addressing mode + larl %r4,.Lctlregs # Restore control registers + lctlg %c0,%c15,0(%r4) + br %r14 +.align 16 +.Lrestart_psw: + .long 0x00080000,0x80000000 + .Lrestart_part2 + + .section .bss +.align 8 +.Lctlregs: + .rept 16 + .quad 0 + .endr + .previous + #else /* CONFIG_64BIT */ ENTRY(s390_base_mcck_handler) diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index eee9998..a9a285b 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -380,20 +380,13 @@ asmlinkage long sys32_sigreturn(void) goto badframe; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - + set_current_blocked(&set); if (restore_sigregs32(regs, &frame->sregs)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; - return regs->gprs[2]; - badframe: force_sig(SIGSEGV, current); return 0; @@ -413,31 +406,22 @@ asmlinkage long sys32_rt_sigreturn(void) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - + set_current_blocked(&set); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; - err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); st.ss_sp = compat_ptr(ss_sp); err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); if (err) goto badframe; - set_fs (KERNEL_DS); do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]); set_fs (old_fs); - return regs->gprs[2]; - badframe: force_sig(SIGSEGV, current); return 0; @@ -605,10 +589,10 @@ give_sigsegv: * OK, we're invoking a handler */ -int -handle_signal32(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +int handle_signal32(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + sigset_t blocked; int ret; /* Set up the stack frame */ @@ -616,15 +600,12 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka, ret = setup_rt_frame32(sig, ka, info, oldset, regs); else ret = setup_frame32(sig, ka, oldset, regs); - - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - return ret; + if (ret) + return ret; + sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(&blocked, sig); + set_current_blocked(&blocked); + return 0; } diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 08ab9aa..7526db6 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -665,12 +665,6 @@ ENTRY(sys32_poll_wrapper) lgfr %r4,%r4 # long jg sys_poll # branch to system call -ENTRY(compat_sys_nfsservctl_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # struct compat_nfsctl_arg* - llgtr %r4,%r4 # union compat_nfsctl_res* - jg compat_sys_nfsservctl # branch to system call - ENTRY(sys32_setresgid16_wrapper) llgfr %r2,%r2 # __kernel_old_gid_emu31_t llgfr %r3,%r3 # __kernel_old_gid_emu31_t diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 1ca3d1d..45df6d4 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -27,7 +27,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mathemu.h> #include <asm/cpcmd.h> #include <asm/lowcore.h> diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 068f846..f297456 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void) static __init void rescue_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD + unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20); /* - * Move the initrd right behind the bss section in case it starts - * within the bss section. So we don't overwrite it when the bss - * section gets cleared. + * Just like in case of IPL from VM reader we make sure there is a + * gap of 4MB between end of kernel and start of initrd. + * That way we can also be sure that saving an NSS will succeed, + * which however only requires different segments. */ if (!INITRD_START || !INITRD_SIZE) return; - if (INITRD_START >= (unsigned long) __bss_stop) + if (INITRD_START >= min_initrd_addr) return; - memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE); - INITRD_START = (unsigned long) __bss_stop; + memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE); + INITRD_START = min_initrd_addr; #endif } diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 3eab7cf..02ec8fe 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -849,6 +849,34 @@ restart_crash: restart_go: #endif +# +# PSW restart interrupt handler +# +ENTRY(psw_restart_int_handler) + st %r15,__LC_SAVE_AREA_64(%r0) # save r15 + basr %r15,0 +0: l %r15,.Lrestart_stack-0b(%r15) # load restart stack + l %r15,0(%r15) + ahi %r15,-SP_SIZE # make room for pt_regs + stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack + mvc SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack + mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 + basr %r14,0 +1: l %r14,.Ldo_restart-1b(%r14) + basr %r14,%r14 + + basr %r14,0 # load disabled wait PSW if +2: lpsw restart_psw_crash-2b(%r14) # do_restart returns + .align 4 +.Ldo_restart: + .long do_restart +.Lrestart_stack: + .long restart_stack + .align 8 +restart_psw_crash: + .long 0x000a0000,0x00000000 + restart_psw_crash + .section .kprobes.text, "ax" #ifdef CONFIG_CHECK_STACK diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 7a0fd42..5f729d6 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -865,6 +865,26 @@ restart_crash: restart_go: #endif +# +# PSW restart interrupt handler +# +ENTRY(psw_restart_int_handler) + stg %r15,__LC_SAVE_AREA_64(%r0) # save r15 + larl %r15,restart_stack # load restart stack + lg %r15,0(%r15) + aghi %r15,-SP_SIZE # make room for pt_regs + stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack + mvc SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack + mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 + brasl %r14,do_restart + + larl %r14,restart_psw_crash # load disabled wait PSW if + lpswe 0(%r14) # do_restart returns + .align 8 +restart_psw_crash: + .quad 0x0002000080000000,0x0000000000000000 + restart_psw_crash + .section .kprobes.text, "ax" #ifdef CONFIG_CHECK_STACK diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index a689070..48c7102 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -45,11 +45,13 @@ * - halt * - power off * - reipl + * - restart */ #define ON_PANIC_STR "on_panic" #define ON_HALT_STR "on_halt" #define ON_POFF_STR "on_poff" #define ON_REIPL_STR "on_reboot" +#define ON_RESTART_STR "on_restart" struct shutdown_action; struct shutdown_trigger { @@ -1218,7 +1220,7 @@ static int __init reipl_fcp_init(void) /* sysfs: create fcp kset for mixing attr group and bin attrs */ reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, &reipl_kset->kobj); - if (!reipl_kset) { + if (!reipl_fcp_kset) { free_page((unsigned long) reipl_block_fcp); return -ENOMEM; } @@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128]; static char vmcmd_on_panic[128]; static char vmcmd_on_halt[128]; static char vmcmd_on_poff[128]; +static char vmcmd_on_restart[128]; DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); +DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart); static struct attribute *vmcmd_attrs[] = { &sys_vmcmd_on_reboot_attr.attr, &sys_vmcmd_on_panic_attr.attr, &sys_vmcmd_on_halt_attr.attr, &sys_vmcmd_on_poff_attr.attr, + &sys_vmcmd_on_restart_attr.attr, NULL, }; @@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_trigger *trigger) cmd = vmcmd_on_halt; else if (strcmp(trigger->name, ON_POFF_STR) == 0) cmd = vmcmd_on_poff; + else if (strcmp(trigger->name, ON_RESTART_STR) == 0) + cmd = vmcmd_on_restart; else return; @@ -1611,7 +1618,8 @@ static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR, static void stop_run(struct shutdown_trigger *trigger) { - if (strcmp(trigger->name, ON_PANIC_STR) == 0) + if (strcmp(trigger->name, ON_PANIC_STR) == 0 || + strcmp(trigger->name, ON_RESTART_STR) == 0) disabled_wait((unsigned long) __builtin_return_address(0)); while (sigp(smp_processor_id(), sigp_stop) == sigp_busy) cpu_relax(); @@ -1707,6 +1715,34 @@ static void do_panic(void) stop_run(&on_panic_trigger); } +/* on restart */ + +static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR, + &stop_action}; + +static ssize_t on_restart_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return sprintf(page, "%s\n", on_restart_trigger.action->name); +} + +static ssize_t on_restart_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return set_trigger(buf, &on_restart_trigger, len); +} + +static struct kobj_attribute on_restart_attr = + __ATTR(on_restart, 0644, on_restart_show, on_restart_store); + +void do_restart(void) +{ + smp_send_stop(); + on_restart_trigger.action->fn(&on_restart_trigger); + stop_run(&on_restart_trigger); +} + /* on halt */ static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; @@ -1783,7 +1819,9 @@ static void __init shutdown_triggers_init(void) if (sysfs_create_file(&shutdown_actions_kset->kobj, &on_poff_attr.attr)) goto fail; - + if (sysfs_create_file(&shutdown_actions_kset->kobj, + &on_restart_attr.attr)) + goto fail; return; fail: panic("shutdown_triggers_init failed\n"); @@ -1959,6 +1997,12 @@ static void do_reset_calls(void) { struct reset_call *reset; +#ifdef CONFIG_64BIT + if (diag308_set_works) { + diag308_reset(); + return; + } +#endif list_for_each_entry(reset, &rcall, list) reset->fn(); } diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index 78eb7cf..e690975 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -1,5 +1,5 @@ /* - * Copyright IBM Corp 2000,2009 + * Copyright IBM Corp 2000,2011 * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>, * Denis Joseph Barrow, */ @@ -8,6 +8,64 @@ #include <asm/asm-offsets.h> # +# store_status +# +# Prerequisites to run this function: +# - Prefix register is set to zero +# - Original prefix register is stored in "dump_prefix_page" +# - Lowcore protection is off +# +ENTRY(store_status) + /* Save register one and load save area base */ + stg %r1,__LC_SAVE_AREA_64(%r0) + lghi %r1,SAVE_AREA_BASE + /* General purpose registers */ + stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + lg %r2,__LC_SAVE_AREA_64(%r0) + stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) + /* Control registers */ + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + /* Access registers */ + stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + /* Floating point registers */ + std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) + /* Floating point control register */ + stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1) + /* CPU timer */ + stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1) + /* Saved prefix register */ + larl %r2,dump_prefix_page + mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2) + /* Clock comparator - seven bytes */ + larl %r2,.Lclkcmp + stckc 0(%r2) + mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2) + /* Program status word */ + epsw %r2,%r3 + st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1) + st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) + larl %r2,store_status + stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) + br %r14 +.align 8 +.Lclkcmp: .quad 0x0000000000000000 + +# # do_reipl_asm # Parameter: r2 = schid of reipl device # @@ -15,22 +73,7 @@ ENTRY(do_reipl_asm) basr %r13,0 .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) -.Lpg1: # do store status of all registers - - stg %r1,.Lregsave-.Lpg0(%r13) - lghi %r1,0x1000 - stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1) - lg %r0,.Lregsave-.Lpg0(%r13) - stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1) - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1) - stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1) - lg %r10,.Ldump_pfx-.Lpg0(%r13) - mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10) - stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1) - stckc .Lclkcmp-.Lpg0(%r13) - mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13) - stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1) - stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1) +.Lpg1: brasl %r14,store_status lctlg %c6,%c6,.Lall-.Lpg0(%r13) lgr %r1,%r2 @@ -67,10 +110,7 @@ ENTRY(do_reipl_asm) st %r14,.Ldispsw+12-.Lpg0(%r13) lpswe .Ldispsw-.Lpg0(%r13) .align 8 -.Lclkcmp: .quad 0x0000000000000000 .Lall: .quad 0x00000000ff000000 -.Ldump_pfx: .quad dump_prefix_page -.Lregsave: .quad 0x0000000000000000 .align 16 /* * These addresses have to be 31 bit otherwise diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 0c35dee1..7b371c3 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -346,7 +346,7 @@ setup_lowcore(void) lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; lc->restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) restart_int_handler; + PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; if (user_mode != HOME_SPACE_MODE) lc->restart_psw.mask |= PSW_ASC_HOME; lc->external_new_psw.mask = psw_kernel_bits; @@ -529,6 +529,27 @@ static void __init setup_memory_end(void) memory_end = memory_size; } +void *restart_stack __attribute__((__section__(".data"))); + +/* + * Setup new PSW and allocate stack for PSW restart interrupt + */ +static void __init setup_restart_psw(void) +{ + psw_t psw; + + restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0); + restart_stack += ASYNC_SIZE; + + /* + * Setup restart PSW for absolute zero lowcore. This is necesary + * if PSW restart is done on an offline CPU that has lowcore zero + */ + psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; + psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; + copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw)); +} + static void __init setup_memory(void) { @@ -731,6 +752,7 @@ static void __init setup_hwcaps(void) strcpy(elf_platform, "z10"); break; case 0x2817: + case 0x2818: strcpy(elf_platform, "z196"); break; } @@ -792,6 +814,7 @@ setup_arch(char **cmdline_p) setup_addressing_mode(); setup_memory(); setup_resources(); + setup_restart_psw(); setup_lowcore(); cpu_init(); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index abbb3c3..9a40e1c 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -57,17 +57,15 @@ typedef struct */ SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) { - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + sigset_t blocked; + current->saved_sigmask = current->blocked; + mask &= _BLOCKABLE; + siginitset(&blocked, mask); + set_current_blocked(&blocked); set_current_state(TASK_INTERRUPTIBLE); schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - + set_restore_sigmask(); return -ERESTARTNOHAND; } @@ -172,18 +170,11 @@ SYSCALL_DEFINE0(sigreturn) goto badframe; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE)) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - + set_current_blocked(&set); if (restore_sigregs(regs, &frame->sregs)) goto badframe; - return regs->gprs[2]; - badframe: force_sig(SIGSEGV, current); return 0; @@ -199,21 +190,14 @@ SYSCALL_DEFINE0(rt_sigreturn) goto badframe; if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - + set_current_blocked(&set); if (restore_sigregs(regs, &frame->uc.uc_mcontext)) goto badframe; - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]) == -EFAULT) goto badframe; return regs->gprs[2]; - badframe: force_sig(SIGSEGV, current); return 0; @@ -385,14 +369,11 @@ give_sigsegv: return -EFAULT; } -/* - * OK, we're invoking a handler - */ - -static int -handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +static int handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, + struct pt_regs *regs) { + sigset_t blocked; int ret; /* Set up the stack frame */ @@ -400,17 +381,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); - - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - - return ret; + if (ret) + return ret; + sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(&blocked, sig); + set_current_blocked(&blocked); + return 0; } /* diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a6d85c0..6ab16ac 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -452,23 +452,27 @@ out: */ int __cpuinit start_secondary(void *cpuvoid) { - /* Setup the cpu */ cpu_init(); preempt_disable(); - /* Enable TOD clock interrupts on the secondary cpu. */ init_cpu_timer(); - /* Enable cpu timer interrupts on the secondary cpu. */ init_cpu_vtimer(); - /* Enable pfault pseudo page faults on this cpu. */ pfault_init(); - /* call cpu notifiers */ notify_cpu_starting(smp_processor_id()); - /* Mark this cpu as online */ ipi_call_lock(); set_cpu_online(smp_processor_id(), true); ipi_call_unlock(); - /* Switch on interrupts */ + __ctl_clear_bit(0, 28); /* Disable lowcore protection */ + S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; + S390_lowcore.restart_psw.addr = + PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; + __ctl_set_bit(0, 28); /* Enable lowcore protection */ + /* + * Wait until the cpu which brought this one up marked it + * active before enabling interrupts. + */ + while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask)) + cpu_relax(); local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); @@ -507,7 +511,11 @@ static int __cpuinit smp_alloc_lowcore(int cpu) memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); lowcore->async_stack = async_stack + ASYNC_SIZE; lowcore->panic_stack = panic_stack + PAGE_SIZE; - + lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; + lowcore->restart_psw.addr = + PSW_ADDR_AMODE | (unsigned long) restart_int_handler; + if (user_mode != HOME_SPACE_MODE) + lowcore->restart_psw.mask |= PSW_ASC_HOME; #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { unsigned long save_area; diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 6ee39ef..73eb08c 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -177,7 +177,7 @@ SYSCALL(sys_getresuid16,sys_ni_syscall,sys32_getresuid16_wrapper) /* 165 old get NI_SYSCALL /* for vm86 */ NI_SYSCALL /* old sys_query_module */ SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) -SYSCALL(sys_nfsservctl,sys_nfsservctl,compat_sys_nfsservctl_wrapper) +NI_SYSCALL /* old nfsservctl */ SYSCALL(sys_setresgid16,sys_ni_syscall,sys32_setresgid16_wrapper) /* 170 old setresgid16 syscall */ SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index e9372c7..ffabcd9 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -36,7 +36,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mathemu.h> #include <asm/cpcmd.h> #include <asm/lowcore.h> diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 51e5cd9..5dbbaa6 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, size_t count) arch_local_irq_restore(flags); return rc; } + +/* + * Copy memory to absolute zero + */ +void copy_to_absolute_zero(void *dest, void *src, size_t count) +{ + unsigned long cr0; + + BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore)); + preempt_disable(); + __ctl_store(cr0, 0, 0); + __ctl_clear_bit(0, 28); /* disable lowcore protection */ + memcpy_real(dest + store_prefix(), src, count); + __ctl_load(cr0, 0, 0); + preempt_enable(); +} diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 2adb239..4d1f2bc 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -528,6 +528,7 @@ static inline void page_table_free_pgste(unsigned long *table) static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, unsigned long vmaddr) { + return NULL; } static inline void page_table_free_pgste(unsigned long *table) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 748ff19..ff9177c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -11,6 +11,7 @@ config SUPERH select HAVE_DMA_ATTRS select HAVE_IRQ_WORK select HAVE_PERF_EVENTS + select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) select PERF_USE_VMALLOC select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 diff --git a/arch/sh/Makefile b/arch/sh/Makefile index e3d8170..99385d0 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -173,6 +173,7 @@ core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ cpuincdir-$(CONFIG_CPU_SH2A) += cpu-sh2a cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2 cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3 +cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5 cpuincdir-y += cpu-common # Must be last diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c index 8e2a270..2823619 100644 --- a/arch/sh/boards/board-apsh4a3a.c +++ b/arch/sh/boards/board-apsh4a3a.c @@ -116,7 +116,7 @@ static int apsh4a3a_clk_init(void) int ret; clk = clk_get(NULL, "extal"); - if (!clk || IS_ERR(clk)) + if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_set_rate(clk, 33333000); clk_put(clk); diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c index e2bd218..b4d6292a 100644 --- a/arch/sh/boards/board-apsh4ad0a.c +++ b/arch/sh/boards/board-apsh4ad0a.c @@ -94,7 +94,7 @@ static int apsh4ad0a_clk_init(void) int ret; clk = clk_get(NULL, "extal"); - if (!clk || IS_ERR(clk)) + if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_set_rate(clk, 33333000); clk_put(clk); diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index ee65ff0..d879848 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -299,7 +299,7 @@ static int sh7785lcr_clk_init(void) int ret; clk = clk_get(NULL, "extal"); - if (!clk || IS_ERR(clk)) + if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_set_rate(clk, 33333333); clk_put(clk); diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index d81c609..24e3316 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -190,7 +190,7 @@ static int urquell_clk_init(void) return -EINVAL; clk = clk_get(NULL, "extal"); - if (!clk || IS_ERR(clk)) + if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_set_rate(clk, 33333333); clk_put(clk); diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 1dc924b..d362657 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -332,8 +332,8 @@ static int camera_set_capture(struct soc_camera_platform_info *info, return ret; } -static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev); -static void ap325rxa_camera_del(struct soc_camera_link *icl); +static int ap325rxa_camera_add(struct soc_camera_device *icd); +static void ap325rxa_camera_del(struct soc_camera_device *icd); static struct soc_camera_platform_info camera_info = { .format_name = "UYVY", @@ -366,24 +366,23 @@ static void ap325rxa_camera_release(struct device *dev) soc_camera_platform_release(&camera_device); } -static int ap325rxa_camera_add(struct soc_camera_link *icl, - struct device *dev) +static int ap325rxa_camera_add(struct soc_camera_device *icd) { - int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link, + int ret = soc_camera_platform_add(icd, &camera_device, &camera_link, ap325rxa_camera_release, 0); if (ret < 0) return ret; ret = camera_probe(); if (ret < 0) - soc_camera_platform_del(icl, camera_device, &camera_link); + soc_camera_platform_del(icd, camera_device, &camera_link); return ret; } -static void ap325rxa_camera_del(struct soc_camera_link *icl) +static void ap325rxa_camera_del(struct soc_camera_device *icd) { - soc_camera_platform_del(icl, camera_device, &camera_link); + soc_camera_platform_del(icd, camera_device, &camera_link); } #endif /* CONFIG_I2C */ diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index 87618c9..74b8db1 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -335,8 +335,6 @@ static struct clk *r7780rp_clocks[] = { &ivdr_clk, }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("ivdr_clk", &ivdr_clk), diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 1521aa7..486d1ac 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -194,7 +194,7 @@ static int sdk7786_clk_init(void) return -EINVAL; clk = clk_get(NULL, "extal"); - if (!clk || IS_ERR(clk)) + if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_set_rate(clk, 33333333); clk_put(clk); diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index b68b61d..edc2fb7 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -5,7 +5,7 @@ #include <cpu/irq.h> #include "pci-sh5.h" -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 942ef4f..edeea89 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -64,7 +64,7 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The interrupt routing semantics here are quite trivial. diff --git a/arch/sh/drivers/pci/fixups-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c index 95c6e2d..ecb1d10 100644 --- a/arch/sh/drivers/pci/fixups-landisk.c +++ b/arch/sh/drivers/pci/fixups-landisk.c @@ -19,7 +19,7 @@ #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { /* * slot0: pin1-4 = irq5,6,7,8 diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 08b2d86..f9370dce 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -18,7 +18,7 @@ static char irq_tab[] __initdata = { 65, 66, 67, 68, }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return irq_tab[slot]; } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index e248516..eaddb56 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -31,7 +31,7 @@ static char lboxre2_irq_tab[] __initdata = { IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { if (mach_is_lboxre2()) return lboxre2_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 0930f98..0b84725 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -27,7 +27,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index fd3e6b0..2ec146c 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -6,7 +6,7 @@ #include <linux/io.h> #include "pci-sh4.h" -int __init pcibios_map_platform_irq(struct pci_dev *, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) { switch (slot) { case 0: return 13; diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 2e8a18b..1615e59 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -3,7 +3,7 @@ #include <linux/types.h> #include <linux/pci.h> -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 5a39ecc..4a093c6 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -18,7 +18,7 @@ #include <linux/pci.h> #include "pci-sh4.h" -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index 3a79fa8..bd1addb 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { TITAN_IRQ_USB, }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = titan_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 4418f90..4df27c4f 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -466,7 +466,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) return 0; } -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return 71; } diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h index c798312..63a27db 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -30,7 +30,6 @@ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic_inc(v) atomic_add(1, (v)) #define atomic_dec(v) atomic_sub(1, (v)) @@ -39,15 +38,15 @@ #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -60,7 +59,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) c = old; } - return c != (u); + return c; } #define smp_mb__before_atomic_dec() smp_mb() @@ -68,7 +67,4 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() -#include <asm-generic/atomic-long.h> -#include <asm-generic/atomic64.h> - #endif /* __ASM_SH_ATOMIC_H */ diff --git a/arch/sh/include/asm/hw_irq.h b/arch/sh/include/asm/hw_irq.h index 603cdde..693d441 100644 --- a/arch/sh/include/asm/hw_irq.h +++ b/arch/sh/include/asm/hw_irq.h @@ -3,7 +3,7 @@ #include <linux/init.h> #include <linux/sh_intc.h> -#include <asm/atomic.h> +#include <linux/atomic.h> extern atomic_t irq_err_count; diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f0efe97f..cb21e23 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -112,7 +112,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #endif /* Board-specific fixup routines. */ -int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin); extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 88bd6be..2d3679b 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -45,8 +45,6 @@ #define GET_FP(regs) ((regs)->regs[14]) #define GET_USP(regs) ((regs)->regs[15]) -extern void show_regs(struct pt_regs *); - #define arch_has_single_step() (1) /* @@ -125,7 +123,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, struct perf_event; struct perf_sample_data; -extern void ptrace_triggered(struct perf_event *bp, int nmi, +extern void ptrace_triggered(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs); #define task_pt_regs(task) \ diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 9070d94..78b0d0f4 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -8,7 +8,7 @@ #ifdef CONFIG_SMP #include <linux/spinlock.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/current.h> #include <asm/percpu.h> diff --git a/arch/sh/include/cpu-sh3/cpu/serial.h b/arch/sh/include/cpu-sh3/cpu/serial.h new file mode 100644 index 0000000..7766329 --- /dev/null +++ b/arch/sh/include/cpu-sh3/cpu/serial.h @@ -0,0 +1,10 @@ +#ifndef __CPU_SH3_SERIAL_H +#define __CPU_SH3_SERIAL_H + +#include <linux/serial_sci.h> + +extern struct plat_sci_port_ops sh770x_sci_port_ops; +extern struct plat_sci_port_ops sh7710_sci_port_ops; +extern struct plat_sci_port_ops sh7720_sci_port_ops; + +#endif /* __CPU_SH3_SERIAL_H */ diff --git a/arch/sh/include/cpu-sh4a/cpu/serial.h b/arch/sh/include/cpu-sh4a/cpu/serial.h new file mode 100644 index 0000000..ff1bc27 --- /dev/null +++ b/arch/sh/include/cpu-sh4a/cpu/serial.h @@ -0,0 +1,7 @@ +#ifndef __CPU_SH4A_SERIAL_H +#define __CPU_SH4A_SERIAL_H + +/* arch/sh/kernel/cpu/sh4a/serial-sh7722.c */ +extern struct plat_sci_port_ops sh7722_sci_port_ops; + +#endif /* __CPU_SH4A_SERIAL_H */ diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 8f63a26..f59b1f3 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -35,8 +35,6 @@ static struct clk *onchip_clocks[] = { &cpu_clk, }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("master_clk", &master_clk), diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index ecab274..6f13f33 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -7,15 +7,15 @@ obj-y := ex.o probe.o entry.o setup-sh3.o obj-$(CONFIG_HIBERNATION) += swsusp.o # CPU subtype setup -obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o -obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o -obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o -obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o -obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o -obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o -obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o -obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o -obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o +obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o serial-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o serial-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o serial-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o serial-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o serial-sh770x.o +obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o serial-sh7710.o +obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o serial-sh7710.o +obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o serial-sh7720.o +obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o serial-sh7720.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o diff --git a/arch/sh/kernel/cpu/sh3/serial-sh770x.c b/arch/sh/kernel/cpu/sh3/serial-sh770x.c new file mode 100644 index 0000000..4f7242c --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/serial-sh770x.c @@ -0,0 +1,33 @@ +#include <linux/serial_sci.h> +#include <linux/serial_core.h> +#include <linux/io.h> +#include <cpu/serial.h> + +#define SCPCR 0xA4000116 +#define SCPDR 0xA4000136 + +static void sh770x_sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + unsigned short data; + + /* We need to set SCPCR to enable RTS/CTS */ + data = __raw_readw(SCPCR); + /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ + __raw_writew(data & 0x0fcf, SCPCR); + + if (!(cflag & CRTSCTS)) { + /* We need to set SCPCR to enable RTS/CTS */ + data = __raw_readw(SCPCR); + /* Clear out SCP7MD1,0, SCP4MD1,0, + Set SCP6MD1,0 = {01} (output) */ + __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); + + data = __raw_readb(SCPDR); + /* Set /RTS2 (bit6) = 0 */ + __raw_writeb(data & 0xbf, SCPDR); + } +} + +struct plat_sci_port_ops sh770x_sci_port_ops = { + .init_pins = sh770x_sci_init_pins, +}; diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7710.c b/arch/sh/kernel/cpu/sh3/serial-sh7710.c new file mode 100644 index 0000000..42190ef --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/serial-sh7710.c @@ -0,0 +1,20 @@ +#include <linux/serial_sci.h> +#include <linux/serial_core.h> +#include <linux/io.h> +#include <cpu/serial.h> + +#define PACR 0xa4050100 +#define PBCR 0xa4050102 + +static void sh7710_sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + if (port->mapbase == 0xA4400000) { + __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); + __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); + } else if (port->mapbase == 0xA4410000) + __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); +} + +struct plat_sci_port_ops sh7710_sci_port_ops = { + .init_pins = sh7710_sci_init_pins, +}; diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7720.c b/arch/sh/kernel/cpu/sh3/serial-sh7720.c new file mode 100644 index 0000000..8832c52 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/serial-sh7720.c @@ -0,0 +1,37 @@ +#include <linux/serial_sci.h> +#include <linux/serial_core.h> +#include <linux/io.h> +#include <cpu/serial.h> +#include <asm/gpio.h> + +static void sh7720_sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + unsigned short data; + + if (cflag & CRTSCTS) { + /* enable RTS/CTS */ + if (port->mapbase == 0xa4430000) { /* SCIF0 */ + /* Clear PTCR bit 9-2; enable all scif pins but sck */ + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xfc03), PORT_PTCR); + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ + /* Clear PVCR bit 9-2 */ + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xfc03), PORT_PVCR); + } + } else { + if (port->mapbase == 0xa4430000) { /* SCIF0 */ + /* Clear PTCR bit 5-2; enable only tx and rx */ + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xffc3), PORT_PTCR); + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ + /* Clear PVCR bit 5-2 */ + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xffc3), PORT_PVCR); + } + } +} + +struct plat_sci_port_ops sh7720_sci_port_ops = { + .init_pins = sh7720_sci_init_pins, +}; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index cd2e702..2309618 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -15,6 +15,7 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <asm/rtc.h> +#include <cpu/serial.h> enum { UNUSED = 0, @@ -75,6 +76,8 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 56, 56, 56 }, + .ops = &sh770x_sci_port_ops, + .regtype = SCIx_SH7705_SCIF_REGTYPE, }; static struct platform_device scif0_device = { @@ -92,6 +95,8 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 52, 52, 52 }, + .ops = &sh770x_sci_port_ops, + .regtype = SCIx_SH7705_SCIF_REGTYPE, }; static struct platform_device scif1_device = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 4551ad6..3f3d5fe 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -19,6 +19,7 @@ #include <linux/serial.h> #include <linux/serial_sci.h> #include <linux/sh_timer.h> +#include <cpu/serial.h> enum { UNUSED = 0, @@ -108,11 +109,14 @@ static struct platform_device rtc_device = { static struct plat_sci_port scif0_platform_data = { .mapbase = 0xfffffe80, + .port_reg = 0xa4000136, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCI, .irqs = { 23, 23, 23, 0 }, + .ops = &sh770x_sci_port_ops, + .regshift = 1, }; static struct platform_device scif0_device = { @@ -132,6 +136,8 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 56, 56, 56, 56 }, + .ops = &sh770x_sci_port_ops, + .regtype = SCIx_SH3_SCIF_REGTYPE, }; static struct platform_device scif1_device = { @@ -146,11 +152,14 @@ static struct platform_device scif1_device = { defined(CONFIG_CPU_SUBTYPE_SH7709) static struct plat_sci_port scif2_platform_data = { .mapbase = 0xa4000140, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_IRDA, .irqs = { 52, 52, 52, 52 }, + .ops = &sh770x_sci_port_ops, + .regshift = 1, }; static struct platform_device scif2_device = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 365b94a6..9492034 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -20,6 +20,7 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <asm/rtc.h> +#include <cpu/serial.h> static struct resource rtc_resources[] = { [0] = { @@ -55,6 +56,8 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, + .ops = &sh7720_sci_port_ops, + .regtype = SCIx_SH7705_SCIF_REGTYPE, }; static struct platform_device scif0_device = { @@ -72,6 +75,8 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, + .ops = &sh7720_sci_port_ops, + .regtype = SCIx_SH7705_SCIF_REGTYPE, }; static struct platform_device scif1_device = { diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 3f6f8e9..f4e262a 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -147,8 +147,6 @@ static struct clk *sh4202_onchip_clocks[] = { &sh4202_shoc_clk, }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("emi_clk", &sh4202_emi_clk), diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index e53b4b3..98cc0c7 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -1,5 +1,5 @@ /* - * SH7750/SH7751 Setup + * SH7091/SH7750/SH7750S/SH7750R/SH7751/SH7751R Setup * * Copyright (C) 2006 Paul Mundt * Copyright (C) 2006 Jamie Lenehan @@ -38,11 +38,13 @@ static struct platform_device rtc_device = { static struct plat_sci_port sci_platform_data = { .mapbase = 0xffe00000, + .port_reg = 0xffe0001C, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCI, .irqs = { 23, 23, 23, 0 }, + .regshift = 2, }; static struct platform_device sci_device = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 78bbf23..c0b4c77 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -133,6 +133,7 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -150,6 +151,7 @@ static struct plat_sci_port scif1_platform_data = { .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .irqs = { 72, 73, 75, 74 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { @@ -167,6 +169,7 @@ static struct plat_sci_port scif2_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 76, 77, 79, 78 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif2_device = { @@ -184,6 +187,7 @@ static struct plat_sci_port scif3_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCI, .irqs = { 80, 81, 82, 0 }, + .regshift = 2, }; static struct platform_device scif3_device = { diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index cc122b1..c57fb28 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o -obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o +obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o serial-sh7722.o obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 93c6460..70e45bd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -194,8 +194,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("rclk", &r_clk), @@ -233,32 +231,17 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]), CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), - { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP007], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP006], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP005], - }, { - /* SCIF3 */ - .dev_id = "sh-sci.3", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP004], - }, + + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP004]), + CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]), CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]), CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]), - CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]), - CLKDEV_CON_ID("i2c1", &mstp_clks[MSTP108]), + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]), + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP108]), CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]), CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]), CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index 049dc062..3c31650 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -192,8 +192,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("rclk", &r_clk), @@ -231,25 +229,14 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]), CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]), CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]), - { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP007], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP006], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP005], - }, + + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]), + CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]), CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]), - CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]), + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]), CLKDEV_CON_ID("icb0", &mstp_clks[MSTP227]), CLKDEV_CON_ID("meram0", &mstp_clks[MSTP226]), CLKDEV_CON_ID("dacy1", &mstp_clks[MSTP224]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 9d23a36..c9a4808 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -175,8 +175,6 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_P], 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("rclk", &r_clk), @@ -201,42 +199,20 @@ static struct clk_lookup lookups[] = { /* MSTP clocks */ CLKDEV_CON_ID("uram0", &mstp_clks[HWBLK_URAM]), CLKDEV_CON_ID("xymem0", &mstp_clks[HWBLK_XYMEM]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU], - }, { - /* TMU2 */ - .dev_id = "sh_tmu.2", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU]), + CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]), - { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF0], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF1], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF2], - }, - CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]), + + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]), + + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]), CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI]), CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 55493cd..3cc3827 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -200,8 +200,6 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("rclk", &r_clk), @@ -305,7 +303,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]), CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]), CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]), - CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]), + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]), CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]), CLKDEV_CON_ID("adc0", &mstp_clks[HWBLK_ADC]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index d08fa95..8668f55 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -252,8 +252,6 @@ static struct clk mstp_clks[HWBLK_NR] = { SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("rclk", &r_clk), @@ -289,77 +287,31 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]), CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]), CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU0], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU0], - }, { - /* TMU2 */ - .dev_id = "sh_tmu.2", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU0], - }, { - /* TMU3 */ - .dev_id = "sh_tmu.3", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU1], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU0]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU0]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]), + CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]), CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]), CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]), - { - /* TMU4 */ - .dev_id = "sh_tmu.4", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU1], - }, { - /* TMU5 */ - .dev_id = "sh_tmu.5", - .con_id = "tmu_fck", - .clk = &mstp_clks[HWBLK_TMU1], - }, { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF0], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF1], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF2], - }, { - /* SCIF3 */ - .dev_id = "sh-sci.3", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF3], - }, { - /* SCIF4 */ - .dev_id = "sh-sci.4", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF4], - }, { - /* SCIF5 */ - .dev_id = "sh-sci.5", - .con_id = "sci_fck", - .clk = &mstp_clks[HWBLK_SCIF5], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]), + CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]), CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]), CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]), CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]), - CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC0]), - CLKDEV_CON_ID("i2c1", &mstp_clks[HWBLK_IIC1]), + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC0]), + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[HWBLK_IIC1]), CLKDEV_CON_ID("mmc0", &mstp_clks[HWBLK_MMC]), CLKDEV_CON_ID("eth0", &mstp_clks[HWBLK_ETHER]), CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index eedddad..3b097b0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -101,8 +101,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("extal", &extal_clk), @@ -116,33 +114,13 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]), CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP113], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP114], - }, - { - /* SCIF4 (But, ID is 2) */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP112], - }, { - /* SCIF3 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP111], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP110], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP113]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP114]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP112]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]), + CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]), CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 599630f..2d4c7fd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -91,8 +91,6 @@ static struct clk *sh7763_onchip_clocks[] = { &sh7763_shyway_clk, }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("shyway_clk", &sh7763_shyway_clk), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 8894926..3b53348 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -97,8 +97,6 @@ static struct clk *sh7780_onchip_clocks[] = { &sh7780_shyway_clk, }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("shyway_clk", &sh7780_shyway_clk), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 2d96024..e5b420c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -116,8 +116,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP100] = SH_CLK_MSTP32(NULL, MSTPCR1, 0, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("extal", &extal_clk), @@ -134,74 +132,27 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - { - /* SCIF5 */ - .dev_id = "sh-sci.5", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP029], - }, { - /* SCIF4 */ - .dev_id = "sh-sci.4", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP028], - }, { - /* SCIF3 */ - .dev_id = "sh-sci.3", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP027], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP026], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP025], - }, { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP024], - }, + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]), CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]), CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]), CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]), CLKDEV_CON_ID("mmcif_fck", &mstp_clks[MSTP013]), CLKDEV_CON_ID("flctl_fck", &mstp_clks[MSTP012]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU2 */ - .dev_id = "sh_tmu.2", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU3 */ - .dev_id = "sh_tmu.3", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU4 */ - .dev_id = "sh_tmu.4", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU5 */ - .dev_id = "sh_tmu.5", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[MSTP009]), + CLKDEV_CON_ID("siof_fck", &mstp_clks[MSTP003]), CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]), CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 42e403b..f6c0c3d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -125,8 +125,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP102] = SH_CLK_MSTP32(NULL, MSTPCR1, 2, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("extal", &extal_clk), @@ -141,37 +139,13 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - { - /* SCIF5 */ - .dev_id = "sh-sci.5", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP029], - }, { - /* SCIF4 */ - .dev_id = "sh-sci.4", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP028], - }, { - /* SCIF3 */ - .dev_id = "sh-sci.3", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP027], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP026], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP025], - }, { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP024], - }, + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]), CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]), CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]), @@ -180,67 +154,20 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]), CLKDEV_CON_ID("i2c1_fck", &mstp_clks[MSTP015]), CLKDEV_CON_ID("i2c0_fck", &mstp_clks[MSTP014]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU2 */ - .dev_id = "sh_tmu.2", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU3 */ - .dev_id = "sh_tmu.3", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU4 */ - .dev_id = "sh_tmu.4", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU5 */ - .dev_id = "sh_tmu.5", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU6 */ - .dev_id = "sh_tmu.6", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP010], - }, { - /* TMU7 */ - .dev_id = "sh_tmu.7", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP010], - }, { - /* TMU8 */ - .dev_id = "sh_tmu.8", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP010], - }, { - /* TMU9 */ - .dev_id = "sh_tmu.9", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP011], - }, { - /* TMU10 */ - .dev_id = "sh_tmu.10", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP011], - }, { - /* TMU11 */ - .dev_id = "sh_tmu.11", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP011], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.6", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.7", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.8", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.9", &mstp_clks[MSTP011]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.10", &mstp_clks[MSTP011]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.11", &mstp_clks[MSTP011]), + CLKDEV_CON_ID("sdif1_fck", &mstp_clks[MSTP005]), CLKDEV_CON_ID("sdif0_fck", &mstp_clks[MSTP004]), CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]), diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 1afdb93..bf2d00b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -100,8 +100,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0), }; -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } - static struct clk_lookup lookups[] = { /* main clocks */ CLKDEV_CON_ID("extal", &extal_clk), @@ -116,62 +114,23 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - { - /* SCIF3 */ - .dev_id = "sh-sci.3", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP027], - }, { - /* SCIF2 */ - .dev_id = "sh-sci.2", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP026], - }, { - /* SCIF1 */ - .dev_id = "sh-sci.1", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP025], - }, { - /* SCIF0 */ - .dev_id = "sh-sci.0", - .con_id = "sci_fck", - .clk = &mstp_clks[MSTP024], - }, + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]), + CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]), CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]), CLKDEV_CON_ID("fe1_fck", &mstp_clks[MSTP001]), CLKDEV_CON_ID("fe0_fck", &mstp_clks[MSTP000]), - { - /* TMU0 */ - .dev_id = "sh_tmu.0", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU1 */ - .dev_id = "sh_tmu.1", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU2 */ - .dev_id = "sh_tmu.2", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP008], - }, { - /* TMU3 */ - .dev_id = "sh_tmu.3", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU4 */ - .dev_id = "sh_tmu.4", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, { - /* TMU5 */ - .dev_id = "sh_tmu.5", - .con_id = "tmu_fck", - .clk = &mstp_clks[MSTP009], - }, + + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[MSTP008]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[MSTP009]), + CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]), CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]), CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]), diff --git a/arch/sh/kernel/cpu/sh4a/serial-sh7722.c b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c new file mode 100644 index 0000000..59bc3a7 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c @@ -0,0 +1,23 @@ +#include <linux/serial_sci.h> +#include <linux/serial_core.h> +#include <linux/io.h> + +#define PSCR 0xA405011E + +static void sh7722_sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + unsigned short data; + + if (port->mapbase == 0xffe00000) { + data = __raw_readw(PSCR); + data &= ~0x03cf; + if (!(cflag & CRTSCTS)) + data |= 0x0340; + + __raw_writew(data, PSCR); + } +} + +struct plat_sci_port_ops sh7722_sci_port_ops = { + .init_pins = sh7722_sci_init_pins, +}; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 82616af..8777386 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -20,6 +20,7 @@ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, + .port_reg = 0xa405013e, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 5813d80..278a0e5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -22,6 +22,7 @@ #include <cpu/dma-register.h> #include <cpu/sh7722.h> +#include <cpu/serial.h> static const struct sh_dmae_slave_config sh7722_dmae_slaves[] = { { @@ -185,6 +186,8 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, + .ops = &sh7722_sci_port_ops, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif0_device = { @@ -202,6 +205,8 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, + .ops = &sh7722_sci_port_ops, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif1_device = { @@ -219,6 +224,8 @@ static struct plat_sci_port scif2_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, + .ops = &sh7722_sci_port_ops, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif2_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 0723822..3c2810d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -23,11 +23,13 @@ /* Serial */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, + .port_reg = 0xa4050160, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif0_device = { @@ -40,11 +42,13 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .mapbase = 0xffe10000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif1_device = { @@ -57,11 +61,13 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .mapbase = 0xffe20000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif2_device = { @@ -75,6 +81,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, + .port_reg = SCIx_NOT_SUPPORTED, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, @@ -91,6 +98,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .mapbase = 0xa4e40000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_3, @@ -108,6 +116,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .mapbase = 0xa4e50000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_3, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 134a397..a37dd72 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -296,11 +296,13 @@ static struct platform_device dma1_device = { /* Serial */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif0_device = { @@ -313,11 +315,13 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .mapbase = 0xffe10000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif1_device = { @@ -330,11 +334,13 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .mapbase = 0xffe20000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, + .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, }; static struct platform_device scif2_device = { @@ -347,6 +353,7 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .mapbase = 0xa4e30000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE, .scbrr_algo_id = SCBRR_ALGO_3, @@ -364,6 +371,7 @@ static struct platform_device scif3_device = { static struct plat_sci_port scif4_platform_data = { .mapbase = 0xa4e40000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE, .scbrr_algo_id = SCBRR_ALGO_3, @@ -381,6 +389,7 @@ static struct platform_device scif4_device = { static struct plat_sci_port scif5_platform_data = { .mapbase = 0xa4e50000, + .port_reg = SCIx_NOT_SUPPORTED, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE, .scbrr_algo_id = SCBRR_ALGO_3, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index e915dea..0555929 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -15,6 +15,7 @@ #include <linux/serial_sci.h> #include <linux/io.h> #include <linux/mm.h> +#include <linux/dma-mapping.h> #include <linux/sh_timer.h> #include <linux/sh_dma.h> diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 593eca6..0011351 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -23,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -40,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { @@ -57,6 +59,7 @@ static struct plat_sci_port scif2_platform_data = { .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 104, 104, 104, 104 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif2_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 08add7f..3d4d207 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -14,7 +14,6 @@ #include <linux/serial_sci.h> #include <linux/sh_dma.h> #include <linux/sh_timer.h> - #include <cpu/dma-register.h> static struct plat_sci_port scif0_platform_data = { @@ -24,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -41,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 18d8fc1..b29e634 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -15,9 +15,7 @@ #include <linux/mm.h> #include <linux/sh_dma.h> #include <linux/sh_timer.h> - #include <asm/mmzone.h> - #include <cpu/dma-register.h> static struct plat_sci_port scif0_platform_data = { @@ -27,6 +25,7 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -44,6 +43,7 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { @@ -61,6 +61,7 @@ static struct plat_sci_port scif2_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 60, 60, 60, 60 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif2_device = { @@ -78,6 +79,7 @@ static struct plat_sci_port scif3_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif3_device = { @@ -95,6 +97,7 @@ static struct plat_sci_port scif4_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif4_device = { @@ -112,6 +115,7 @@ static struct plat_sci_port scif5_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif5_device = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index beba32b..dd5e709 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -1,7 +1,7 @@ /* * SH7786 Setup * - * Copyright (C) 2009 - 2010 Renesas Solutions Corp. + * Copyright (C) 2009 - 2011 Renesas Solutions Corp. * Kuninori Morimoto <morimoto.kuninori@renesas.com> * Paul Mundt <paul.mundt@renesas.com> * @@ -33,6 +33,7 @@ static struct plat_sci_port scif0_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -53,6 +54,7 @@ static struct plat_sci_port scif1_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { @@ -70,6 +72,7 @@ static struct plat_sci_port scif2_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 50, 50, 50, 50 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif2_device = { @@ -87,6 +90,7 @@ static struct plat_sci_port scif3_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 51, 51, 51, 51 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif3_device = { @@ -104,6 +108,7 @@ static struct plat_sci_port scif4_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 52, 52, 52, 52 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif4_device = { @@ -121,6 +126,7 @@ static struct plat_sci_port scif5_platform_data = { .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 53, 53, 53, 53 }, + .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif5_device = { diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 425d604..db4ecd7 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -16,12 +16,13 @@ #include <linux/thread_info.h> #include <linux/irqflags.h> #include <linux/smp.h> +#include <linux/cpuidle.h> #include <asm/pgalloc.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/smp.h> -void (*pm_idle)(void) = NULL; +void (*pm_idle)(void); static int hlt_counter; @@ -100,7 +101,8 @@ void cpu_idle(void) local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); - pm_idle(); + if (cpuidle_idle_call()) + pm_idle(); /* * Sanity check to ensure that pm_idle() returns * with IRQs enabled diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 6207561..3147a9a 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -21,7 +21,7 @@ #include <linux/cpu.h> #include <linux/interrupt.h> #include <linux/sched.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/processor.h> #include <asm/system.h> #include <asm/mmu_context.h> diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 39b051d..293e39c 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -185,7 +185,7 @@ ENTRY(sys_call_table) .long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* old "query_module" */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* was nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 089c4d8..ceb34b9 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S @@ -189,7 +189,7 @@ sys_call_table: .long sys_ni_syscall /* vm86 */ .long sys_ni_syscall /* old "query_module" */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* was nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index d9006f8..7bbef95 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -316,6 +316,35 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs, break; } break; + + case 9: /* mov.w @(disp,PC),Rn */ + srcu = (unsigned char __user *)regs->pc; + srcu += 4; + srcu += (instruction & 0x00FF) << 1; + dst = (unsigned char *)rn; + *(unsigned long *)dst = 0; + +#if !defined(__LITTLE_ENDIAN__) + dst += 2; +#endif + + if (ma->from(dst, srcu, 2)) + goto fetch_fault; + sign_extend(2, dst); + ret = 0; + break; + + case 0xd: /* mov.l @(disp,PC),Rn */ + srcu = (unsigned char __user *)(regs->pc & ~0x3); + srcu += 4; + srcu += (instruction & 0x00FF) << 2; + dst = (unsigned char *)rn; + *(unsigned long *)dst = 0; + + if (ma->from(dst, srcu, 4)) + goto fetch_fault; + ret = 0; + break; } return ret; @@ -466,6 +495,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, case 0x0500: /* mov.w @(disp,Rm),R0 */ goto simple; case 0x0B00: /* bf lab - no delayslot*/ + ret = 0; break; case 0x0F00: /* bf/s lab */ ret = handle_delayslot(regs, instruction, ma); @@ -479,6 +509,7 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, } break; case 0x0900: /* bt lab - no delayslot */ + ret = 0; break; case 0x0D00: /* bt/s lab */ ret = handle_delayslot(regs, instruction, ma); @@ -494,6 +525,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, } break; + case 0x9000: /* mov.w @(disp,Rm),Rn */ + goto simple; + case 0xA000: /* bra label */ ret = handle_delayslot(regs, instruction, ma); if (ret==0) @@ -507,6 +541,9 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, regs->pc += SH_PC_12BIT_OFFSET(instruction); } break; + + case 0xD000: /* mov.l @(disp,Rm),Rn */ + goto simple; } return ret; diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 67110be..cd3a404 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -28,7 +28,7 @@ #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/processor.h> #include <asm/pgtable.h> #include <asm/fpu.h> diff --git a/arch/sh/kernel/unwinder.c b/arch/sh/kernel/unwinder.c index 468889d..521b543 100644 --- a/arch/sh/kernel/unwinder.c +++ b/arch/sh/kernel/unwinder.c @@ -13,7 +13,7 @@ #include <linux/spinlock.h> #include <linux/module.h> #include <asm/unwinder.h> -#include <asm/atomic.h> +#include <linux/atomic.h> /* * This is the most basic stack unwinder an architecture can diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 1074ddd..1a6f20d 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -54,6 +54,8 @@ config SPARC64 select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select IRQ_PREFLOW_FASTEOI + select ARCH_HAVE_NMI_SAFE_CMPXCHG + select HAVE_C_RECORDMCOUNT config ARCH_DEFCONFIG string diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 3c93f08..2c2e388 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -16,3 +16,8 @@ header-y += traps.h header-y += uctx.h header-y += utrap.h header-y += watchdog.h + +generic-y += div64.h +generic-y += local64.h +generic-y += irq_regs.h +generic-y += local.h diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index 7ae128b..5c3c8b6 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -22,7 +22,7 @@ extern int __atomic_add_return(int, atomic_t *); extern int atomic_cmpxchg(atomic_t *, int, int); #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -extern int atomic_add_unless(atomic_t *, int, int); +extern int __atomic_add_unless(atomic_t *, int, int); extern void atomic_set(atomic_t *, int); #define atomic_read(v) (*(volatile int *)&(v)->counter) @@ -52,7 +52,6 @@ extern void atomic_set(atomic_t *, int); #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* This is the old 24-bit implementation. It's still used internally * by some sparc-specific code, notably the semaphore implementation. @@ -161,5 +160,4 @@ static inline int __atomic24_sub(int i, atomic24_t *v) #endif /* !(__KERNEL__) */ -#include <asm-generic/atomic-long.h> #endif /* !(__ARCH_SPARC_ATOMIC__) */ diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index bdb2ff8..9f421df 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -70,7 +70,7 @@ extern long atomic64_sub_ret(long, atomic64_t *); #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -82,10 +82,9 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #define atomic64_cmpxchg(v, o, n) \ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) @@ -114,5 +113,4 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif /* !(__ARCH_SPARC64_ATOMIC__) */ diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h index 38e9aa1..29011cc 100644 --- a/arch/sparc/include/asm/bitops_64.h +++ b/arch/sparc/include/asm/bitops_64.h @@ -26,61 +26,28 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() -#include <asm-generic/bitops/ffz.h> -#include <asm-generic/bitops/__ffs.h> #include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/__fls.h> #include <asm-generic/bitops/fls64.h> #ifdef __KERNEL__ +extern int ffs(int x); +extern unsigned long __ffs(unsigned long); + +#include <asm-generic/bitops/ffz.h> #include <asm-generic/bitops/sched.h> -#include <asm-generic/bitops/ffs.h> /* * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -#ifdef ULTRA_HAS_POPULATION_COUNT - -static inline unsigned int __arch_hweight64(unsigned long w) -{ - unsigned int res; - - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); - return res; -} - -static inline unsigned int __arch_hweight32(unsigned int w) -{ - unsigned int res; - - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); - return res; -} +extern unsigned long __arch_hweight64(__u64 w); +extern unsigned int __arch_hweight32(unsigned int w); +extern unsigned int __arch_hweight16(unsigned int w); +extern unsigned int __arch_hweight8(unsigned int w); -static inline unsigned int __arch_hweight16(unsigned int w) -{ - unsigned int res; - - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); - return res; -} - -static inline unsigned int __arch_hweight8(unsigned int w) -{ - unsigned int res; - - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); - return res; -} - -#else - -#include <asm-generic/bitops/arch_hweight.h> - -#endif #include <asm-generic/bitops/const_hweight.h> #include <asm-generic/bitops/lock.h> #endif /* __KERNEL__ */ @@ -91,10 +58,7 @@ static inline unsigned int __arch_hweight8(unsigned int w) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(lock,nr,addr) \ - test_and_set_bit((nr) ^ 0x38,(unsigned long *)(addr)) -#define ext2_clear_bit_atomic(lock,nr,addr) \ - test_and_clear_bit((nr) ^ 0x38,(unsigned long *)(addr)) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/div64.h b/arch/sparc/include/asm/div64.h deleted file mode 100644 index 6cd978c..0000000 --- a/arch/sparc/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/div64.h> diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h index cfa9cd2..7df8b7f 100644 --- a/arch/sparc/include/asm/elf_64.h +++ b/arch/sparc/include/asm/elf_64.h @@ -59,15 +59,33 @@ #define R_SPARC_6 45 /* Bits present in AT_HWCAP, primarily for Sparc32. */ - -#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ -#define HWCAP_SPARC_STBAR 2 -#define HWCAP_SPARC_SWAP 4 -#define HWCAP_SPARC_MULDIV 8 -#define HWCAP_SPARC_V9 16 -#define HWCAP_SPARC_ULTRA3 32 -#define HWCAP_SPARC_BLKINIT 64 -#define HWCAP_SPARC_N2 128 +#define HWCAP_SPARC_FLUSH 0x00000001 +#define HWCAP_SPARC_STBAR 0x00000002 +#define HWCAP_SPARC_SWAP 0x00000004 +#define HWCAP_SPARC_MULDIV 0x00000008 +#define HWCAP_SPARC_V9 0x00000010 +#define HWCAP_SPARC_ULTRA3 0x00000020 +#define HWCAP_SPARC_BLKINIT 0x00000040 +#define HWCAP_SPARC_N2 0x00000080 + +/* Solaris compatible AT_HWCAP bits. */ +#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ +#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ +#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ +#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ +#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ +#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ +#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ +#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ +#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ +#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ +#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ +#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ +#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ +#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ +#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ +#define AV_SPARC_ASI_CACHE_SPARING \ + 0x00800000 /* cache sparing ASIs available */ #define CORE_DUMP_USE_REGSET @@ -162,31 +180,8 @@ typedef struct { #define ELF_ET_DYN_BASE 0x0000010000000000UL #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -/* On Ultra, we support all of the v8 capabilities. */ -static inline unsigned int sparc64_elf_hwcap(void) -{ - unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | - HWCAP_SPARC_V9); - - if (tlb_type == cheetah || tlb_type == cheetah_plus) - cap |= HWCAP_SPARC_ULTRA3; - else if (tlb_type == hypervisor) { - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA2) - cap |= HWCAP_SPARC_BLKINIT; - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) - cap |= HWCAP_SPARC_N2; - } - - return cap; -} - -#define ELF_HWCAP sparc64_elf_hwcap() +extern unsigned long sparc64_elf_hwcap; +#define ELF_HWCAP sparc64_elf_hwcap /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 7568640..015a761 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request, #define HV_FAST_FIRE_GET_PERFREG 0x120 #define HV_FAST_FIRE_SET_PERFREG 0x121 +#define HV_FAST_REBOOT_DATA_SET 0x172 + +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_reboot_data_set(unsigned long ra, + unsigned long len); +#endif + /* Function numbers for HV_CORE_TRAP. */ #define HV_CORE_SET_VER 0x00 #define HV_CORE_PUTCHAR 0x01 @@ -2940,16 +2947,23 @@ extern unsigned long sun4v_ncs_request(unsigned long request, #define HV_GRP_CORE 0x0001 #define HV_GRP_INTR 0x0002 #define HV_GRP_SOFT_STATE 0x0003 +#define HV_GRP_TM 0x0080 #define HV_GRP_PCI 0x0100 #define HV_GRP_LDOM 0x0101 #define HV_GRP_SVC_CHAN 0x0102 #define HV_GRP_NCS 0x0103 #define HV_GRP_RNG 0x0104 +#define HV_GRP_PBOOT 0x0105 +#define HV_GRP_TPM 0x0107 +#define HV_GRP_SDIO 0x0108 +#define HV_GRP_SDIO_ERR 0x0109 +#define HV_GRP_REBOOT_DATA 0x0110 #define HV_GRP_NIAG_PERF 0x0200 #define HV_GRP_FIRE_PERF 0x0201 #define HV_GRP_N2_CPU 0x0202 #define HV_GRP_NIU 0x0204 #define HV_GRP_VF_CPU 0x0205 +#define HV_GRP_KT_CPU 0x0209 #define HV_GRP_DIAG 0x0300 #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/irq_regs.h b/arch/sparc/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b..0000000 --- a/arch/sparc/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/sparc/include/asm/leon_pci.h b/arch/sparc/include/asm/leon_pci.h index 42b4b31..f48527e 100644 --- a/arch/sparc/include/asm/leon_pci.h +++ b/arch/sparc/include/asm/leon_pci.h @@ -12,7 +12,7 @@ struct leon_pci_info { struct pci_ops *ops; struct resource io_space; struct resource mem_space; - int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); + int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); }; extern void leon_pci_init(struct platform_device *ofdev, diff --git a/arch/sparc/include/asm/local.h b/arch/sparc/include/asm/local.h deleted file mode 100644 index bc80815..0000000 --- a/arch/sparc/include/asm/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SPARC_LOCAL_H -#define _SPARC_LOCAL_H - -#include <asm-generic/local.h> - -#endif diff --git a/arch/sparc/include/asm/local64.h b/arch/sparc/include/asm/local64.h deleted file mode 100644 index 36c93b5..0000000 --- a/arch/sparc/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index 56bbaad..edd3d3cde 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -21,7 +21,7 @@ #include <linux/of_pdt.h> #include <linux/proc_fs.h> #include <linux/mutex.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index b928b31..a0e1bcf 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h @@ -213,7 +213,6 @@ extern unsigned long profile_pc(struct pt_regs *); #else #define profile_pc(regs) instruction_pointer(regs) #endif -extern void show_regs(struct pt_regs *); #endif /* (__KERNEL__) */ #else /* __ASSEMBLY__ */ @@ -257,7 +256,6 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->pc) #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) unsigned long profile_pc(struct pt_regs *); -extern void show_regs(struct pt_regs *); #endif /* (__KERNEL__) */ #else /* (!__ASSEMBLY__) */ diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h index a1607d18..69914d7 100644 --- a/arch/sparc/include/asm/sigcontext.h +++ b/arch/sparc/include/asm/sigcontext.h @@ -45,6 +45,19 @@ typedef struct { int si_mask; } __siginfo32_t; +#define __SIGC_MAXWIN 7 + +typedef struct { + unsigned long locals[8]; + unsigned long ins[8]; +} __siginfo_reg_window; + +typedef struct { + int wsaved; + __siginfo_reg_window reg_window[__SIGC_MAXWIN]; + unsigned long rwbuf_stkptrs[__SIGC_MAXWIN]; +} __siginfo_rwin_t; + #ifdef CONFIG_SPARC64 typedef struct { unsigned int si_float_regs [64]; @@ -73,6 +86,7 @@ struct sigcontext { unsigned long ss_size; } sigc_stack; unsigned long sigc_mask; + __siginfo_rwin_t * sigc_rwin_save; }; #else diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index 093f108..01c51c7 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h @@ -22,7 +22,7 @@ #include <asm/ptrace.h> #include <asm/asi.h> -#include <asm/atomic.h> +#include <linux/atomic.h> /* * Private routines/data diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index 20bca89..29862a9 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -27,7 +27,7 @@ */ #include <linux/bitops.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/percpu.h> DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 5f5b8bf..bcc98fc 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -131,6 +131,15 @@ static inline void arch_write_lock(arch_rwlock_t *rw) *(volatile __u32 *)&lp->lock = ~0U; } +static void inline arch_write_unlock(arch_rwlock_t *lock) +{ + __asm__ __volatile__( +" st %%g0, [%0]" + : /* no outputs */ + : "r" (lock) + : "memory"); +} + static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned int val; @@ -175,8 +184,6 @@ static inline int __arch_read_trylock(arch_rwlock_t *rw) res; \ }) -#define arch_write_unlock(rw) do { (rw)->lock = 0; } while(0) - #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_read_lock_flags(rw, flags) arch_read_lock(rw) #define arch_write_lock_flags(rw, flags) arch_write_lock(rw) diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 073936a..9689176 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -210,14 +210,8 @@ static int inline arch_write_trylock(arch_rwlock_t *lock) return result; } -#define arch_read_lock(p) arch_read_lock(p) #define arch_read_lock_flags(p, f) arch_read_lock(p) -#define arch_read_trylock(p) arch_read_trylock(p) -#define arch_read_unlock(p) arch_read_unlock(p) -#define arch_write_lock(p) arch_write_lock(p) #define arch_write_lock_flags(p, f) arch_write_lock(p) -#define arch_write_unlock(p) arch_write_unlock(p) -#define arch_write_trylock(p) arch_write_trylock(p) #define arch_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) #define arch_write_can_lock(rw) (!(rw)->lock) diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index f0d0c40c4..55a17c6 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h @@ -42,6 +42,7 @@ #define SUN4V_CHIP_INVALID 0x00 #define SUN4V_CHIP_NIAGARA1 0x01 #define SUN4V_CHIP_NIAGARA2 0x02 +#define SUN4V_CHIP_NIAGARA3 0x03 #define SUN4V_CHIP_UNKNOWN 0xff #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 83c571d..1a8afd1 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; sub TSB, 0x8, TSB; \ TSB_STORE(TSB, TAG); -#define KTSB_LOAD_QUAD(TSB, REG) \ - ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; - -#define KTSB_STORE(ADDR, VAL) \ - stxa VAL, [ADDR] ASI_N; - -#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ -99: lduwa [TSB] ASI_N, REG1; \ - sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ - andcc REG1, REG2, %g0; \ - bne,pn %icc, 99b; \ - nop; \ - casa [TSB] ASI_N, REG1, REG2;\ - cmp REG1, REG2; \ - bne,pn %icc, 99b; \ - nop; \ - -#define KTSB_WRITE(TSB, TTE, TAG) \ - add TSB, 0x8, TSB; \ - stxa TTE, [TSB] ASI_N; \ - sub TSB, 0x8, TSB; \ - stxa TAG, [TSB] ASI_N; - /* Do a kernel page table walk. Leaves physical PTE pointer in * REG1. Jumps to FAIL_LABEL on early page table walk termination. * VADDR will not be clobbered, but REG2 will. @@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; (KERNEL_TSB_SIZE_BYTES / 16) #define KERNEL_TSB4M_NENTRIES 4096 +#define KTSB_PHYS_SHIFT 15 + /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries * and the found TTE will be left in REG1. REG3 and REG4 must @@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * VADDR and TAG will be preserved and not clobbered by this macro. */ #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ - sethi %hi(swapper_tsb), REG1; \ +661: sethi %hi(swapper_tsb), REG1; \ or REG1, %lo(swapper_tsb), REG1; \ + .section .swapper_tsb_phys_patch, "ax"; \ + .word 661b; \ + .previous; \ +661: nop; \ + .section .tsb_ldquad_phys_patch, "ax"; \ + .word 661b; \ + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ + .previous; \ srlx VADDR, PAGE_SHIFT, REG2; \ and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - KTSB_LOAD_QUAD(REG2, REG3); \ + TSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; @@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * we can make use of that for the index computation. */ #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ - sethi %hi(swapper_4m_tsb), REG1; \ +661: sethi %hi(swapper_4m_tsb), REG1; \ or REG1, %lo(swapper_4m_tsb), REG1; \ + .section .swapper_4m_tsb_phys_patch, "ax"; \ + .word 661b; \ + .previous; \ +661: nop; \ + .section .tsb_ldquad_phys_patch, "ax"; \ + .word 661b; \ + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ + .previous; \ and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - KTSB_LOAD_QUAD(REG2, REG3); \ + TSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h index bee4bf4..9ed6ff6 100644 --- a/arch/sparc/include/asm/xor_64.h +++ b/arch/sparc/include/asm/xor_64.h @@ -65,6 +65,7 @@ static struct xor_block_template xor_block_niagara = { #define XOR_SELECT_TEMPLATE(FASTEST) \ ((tlb_type == hypervisor && \ (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ - sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \ + sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \ &xor_block_niagara : \ &xor_block_VIS) diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index b90b4a1..cb85458 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-y += process_$(BITS).o obj-y += signal_$(BITS).o +obj-y += sigutil_$(BITS).o obj-$(CONFIG_SPARC32) += ioport.o obj-y += setup_$(BITS).o obj-y += idprom.o diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 138dbbc..9810fd8 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -396,6 +396,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) , cpu_data(0).clock_tick #endif ); + cpucap_info(m); #ifdef CONFIG_SMP smp_bogo(m); #endif @@ -474,11 +475,18 @@ static void __init sun4v_cpu_probe(void) sparc_pmu_type = "niagara2"; break; + case SUN4V_CHIP_NIAGARA3: + sparc_cpu_type = "UltraSparc T3 (Niagara3)"; + sparc_fpu_type = "UltraSparc T3 integrated FPU"; + sparc_pmu_type = "niagara3"; + break; + default: printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", prom_cpu_compatible); sparc_cpu_type = "Unknown SUN4V CPU"; sparc_fpu_type = "Unknown SUN4V FPU"; + sparc_pmu_type = "Unknown SUN4V PMU"; break; } } diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index d91fd78..4197e8d 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -324,6 +324,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) switch (sun4v_chip_type) { case SUN4V_CHIP_NIAGARA1: case SUN4V_CHIP_NIAGARA2: + case SUN4V_CHIP_NIAGARA3: rover_inc_table = niagara_iterate_method; break; default: diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index dd1342c..7429b47 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -15,12 +15,15 @@ #include <linux/reboot.h> #include <linux/cpu.h> +#include <asm/hypervisor.h> #include <asm/ldc.h> #include <asm/vio.h> #include <asm/mdesc.h> #include <asm/head.h> #include <asm/irq.h> +#include "kernel.h" + #define DRV_MODULE_NAME "ds" #define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.0" @@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) } } +static char full_boot_str[256] __attribute__((aligned(32))); +static int reboot_data_supported; + void ldom_reboot(const char *boot_command) { /* Don't bother with any of this if the boot_command * is empty. */ if (boot_command && strlen(boot_command)) { - char full_boot_str[256]; + unsigned long len; strcpy(full_boot_str, "boot "); strcpy(full_boot_str + strlen("boot "), boot_command); + len = strlen(full_boot_str); - ldom_set_var("reboot-command", full_boot_str); + if (reboot_data_supported) { + unsigned long ra = kimage_addr_to_ra(full_boot_str); + unsigned long hv_ret; + + hv_ret = sun4v_reboot_data_set(ra, len); + if (hv_ret != HV_EOK) + pr_err("SUN4V: Unable to set reboot data " + "hv_ret=%lu\n", hv_ret); + } else { + ldom_set_var("reboot-command", full_boot_str); + } } sun4v_mach_sir(); } @@ -1237,6 +1254,16 @@ static struct vio_driver ds_driver = { static int __init ds_init(void) { + unsigned long hv_ret, major, minor; + + if (tlb_type == hypervisor) { + hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); + if (hv_ret == HV_EOK) { + pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", + major, minor); + reboot_data_supported = 1; + } + } kthread_run(ds_thread, NULL, "kldomd"); return vio_register_driver(&ds_driver); diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index d1f1361..e27f8ea 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -42,6 +42,20 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, extern void fpload(unsigned long *fpregs, unsigned long *fsr); #else /* CONFIG_SPARC32 */ +struct popc_3insn_patch_entry { + unsigned int addr; + unsigned int insns[3]; +}; +extern struct popc_3insn_patch_entry __popc_3insn_patch, + __popc_3insn_patch_end; + +struct popc_6insn_patch_entry { + unsigned int addr; + unsigned int insns[6]; +}; +extern struct popc_6insn_patch_entry __popc_6insn_patch, + __popc_6insn_patch_end; + extern void __init per_cpu_patch(void); extern void __init sun4v_patch(void); extern void __init boot_cpu_id_too_large(int cpu); diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index aa594c7..0eac1b2 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -132,6 +132,8 @@ prom_sun4v_name: .asciz "sun4v" prom_niagara_prefix: .asciz "SUNW,UltraSPARC-T" +prom_sparc_prefix: + .asciz "SPARC-T" .align 4 prom_root_compatible: .skip 64 @@ -382,6 +384,22 @@ sun4v_chip_type: 90: ldub [%g7], %g2 ldub [%g1], %g4 cmp %g2, %g4 + bne,pn %icc, 89f + add %g7, 1, %g7 + subcc %g3, 1, %g3 + bne,pt %xcc, 90b + add %g1, 1, %g1 + ba,pt %xcc, 91f + nop + +89: sethi %hi(prom_cpu_compatible), %g1 + or %g1, %lo(prom_cpu_compatible), %g1 + sethi %hi(prom_sparc_prefix), %g7 + or %g7, %lo(prom_sparc_prefix), %g7 + mov 7, %g3 +90: ldub [%g7], %g2 + ldub [%g1], %g4 + cmp %g2, %g4 bne,pn %icc, 4f add %g7, 1, %g7 subcc %g3, 1, %g3 @@ -390,6 +408,15 @@ sun4v_chip_type: sethi %hi(prom_cpu_compatible), %g1 or %g1, %lo(prom_cpu_compatible), %g1 + ldub [%g1 + 7], %g2 + cmp %g2, '3' + be,pt %xcc, 5f + mov SUN4V_CHIP_NIAGARA3, %g4 + ba,pt %xcc, 4f + nop + +91: sethi %hi(prom_cpu_compatible), %g1 + or %g1, %lo(prom_cpu_compatible), %g1 ldub [%g1 + 17], %g2 cmp %g2, '1' be,pt %xcc, 5f @@ -397,6 +424,7 @@ sun4v_chip_type: cmp %g2, '2' be,pt %xcc, 5f mov SUN4V_CHIP_NIAGARA2, %g4 + 4: mov SUN4V_CHIP_UNKNOWN, %g4 5: sethi %hi(sun4v_chip_type), %g2 @@ -514,6 +542,9 @@ niagara_tlb_fixup: cmp %g1, SUN4V_CHIP_NIAGARA2 be,pt %xcc, niagara2_patch nop + cmp %g1, SUN4V_CHIP_NIAGARA3 + be,pt %xcc, niagara2_patch + nop call generic_patch_copyops nop @@ -528,7 +559,7 @@ niagara2_patch: nop call niagara_patch_bzero nop - call niagara2_patch_pageops + call niagara_patch_pageops nop ba,a,pt %xcc, 80f diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 7c60afb..c2d055d 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -28,16 +28,23 @@ static struct api_info api_table[] = { { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, { .group = HV_GRP_INTR, }, { .group = HV_GRP_SOFT_STATE, }, + { .group = HV_GRP_TM, }, { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, { .group = HV_GRP_LDOM, }, { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, { .group = HV_GRP_RNG, }, + { .group = HV_GRP_PBOOT, }, + { .group = HV_GRP_TPM, }, + { .group = HV_GRP_SDIO, }, + { .group = HV_GRP_SDIO_ERR, }, + { .group = HV_GRP_REBOOT_DATA, }, { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, { .group = HV_GRP_FIRE_PERF, }, { .group = HV_GRP_N2_CPU, }, { .group = HV_GRP_NIU, }, { .group = HV_GRP_VF_CPU, }, + { .group = HV_GRP_KT_CPU, }, { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, }; diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index 8a5f35f..58d60de 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf) retl nop ENDPROC(sun4v_niagara2_setperf) + +ENTRY(sun4v_reboot_data_set) + mov HV_FAST_REBOOT_DATA_SET, %o5 + ta HV_FAST_TRAP + retl + nop +ENDPROC(sun4v_reboot_data_set) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 6ffccd6..d0479e2 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -65,9 +65,6 @@ static inline void dma_make_coherent(unsigned long pa, unsigned long len) } #endif -static struct resource *_sparc_find_resource(struct resource *r, - unsigned long); - static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, unsigned long size, char *name); @@ -143,7 +140,11 @@ void iounmap(volatile void __iomem *virtual) unsigned long vaddr = (unsigned long) virtual & PAGE_MASK; struct resource *res; - if ((res = _sparc_find_resource(&sparc_iomap, vaddr)) == NULL) { + /* + * XXX Too slow. Can have 8192 DVMA pages on sun4m in the worst case. + * This probably warrants some sort of hashing. + */ + if ((res = lookup_resource(&sparc_iomap, vaddr)) == NULL) { printk("free_io/iounmap: cannot free %lx\n", vaddr); return; } @@ -319,7 +320,7 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p, struct resource *res; struct page *pgv; - if ((res = _sparc_find_resource(&_sparc_dvma, + if ((res = lookup_resource(&_sparc_dvma, (unsigned long)p)) == NULL) { printk("sbus_free_consistent: cannot free %p\n", p); return; @@ -492,7 +493,7 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p, { struct resource *res; - if ((res = _sparc_find_resource(&_sparc_dvma, + if ((res = lookup_resource(&_sparc_dvma, (unsigned long)p)) == NULL) { printk("pci_free_consistent: cannot free %p\n", p); return; @@ -715,25 +716,6 @@ static const struct file_operations sparc_io_proc_fops = { }; #endif /* CONFIG_PROC_FS */ -/* - * This is a version of find_resource and it belongs to kernel/resource.c. - * Until we have agreement with Linus and Martin, it lingers here. - * - * XXX Too slow. Can have 8192 DVMA pages on sun4m in the worst case. - * This probably warrants some sort of hashing. - */ -static struct resource *_sparc_find_resource(struct resource *root, - unsigned long hit) -{ - struct resource *tmp; - - for (tmp = root->child; tmp != 0; tmp = tmp->sibling) { - if (tmp->start <= hit && tmp->end >= hit) - return tmp; - } - return NULL; -} - static void register_proc_sparc_ioport(void) { #ifdef CONFIG_PROC_FS diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 100b9c2..4285112 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -88,7 +88,7 @@ BTFIXUPDEF_CALL(void, set_irq_udt, int) #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ -#define SUN4D_IPI_IRQ 14 +#define SUN4D_IPI_IRQ 13 extern void sun4d_ipi_interrupt(void); diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 4e78862..0dd8422 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -26,7 +26,7 @@ #include <asm/ptrace.h> #include <asm/processor.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/irq.h> #include <asm/io.h> diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 6f6544c..fd6c36b 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -4,12 +4,27 @@ #include <linux/interrupt.h> #include <asm/traps.h> +#include <asm/head.h> +#include <asm/io.h> /* cpu.c */ extern const char *sparc_pmu_type; extern unsigned int fsr_storage; extern int ncpus_probed; +#ifdef CONFIG_SPARC64 +/* setup_64.c */ +struct seq_file; +extern void cpucap_info(struct seq_file *); + +static inline unsigned long kimage_addr_to_ra(const char *p) +{ + unsigned long val = (unsigned long) p; + + return kern_base + (val - KERNBASE); +} +#endif + #ifdef CONFIG_SPARC32 /* cpu.c */ extern void cpu_probe(void); diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 1d36147..79f3103 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S @@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: kvmap_itlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) - KTSB_LOCK_TAG(%g1, %g2, %g7) + TSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_itlb_longpath - KTSB_STORE(%g1, %g7) + TSB_STORE(%g1, %g7) - KTSB_WRITE(%g1, %g5, %g6) + TSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ @@ -102,9 +102,9 @@ kvmap_itlb_longpath: kvmap_itlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) - KTSB_LOCK_TAG(%g1, %g2, %g7) + TSB_LOCK_TAG(%g1, %g2, %g7) - KTSB_WRITE(%g1, %g5, %g6) + TSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_itlb_load nop @@ -112,17 +112,17 @@ kvmap_itlb_obp: kvmap_dtlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) - KTSB_LOCK_TAG(%g1, %g2, %g7) + TSB_LOCK_TAG(%g1, %g2, %g7) - KTSB_WRITE(%g1, %g5, %g6) + TSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop .align 32 kvmap_dtlb_tsb4m_load: - KTSB_LOCK_TAG(%g1, %g2, %g7) - KTSB_WRITE(%g1, %g5, %g6) + TSB_LOCK_TAG(%g1, %g2, %g7) + TSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop @@ -222,16 +222,16 @@ kvmap_linear_patch: kvmap_dtlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) - KTSB_LOCK_TAG(%g1, %g2, %g7) + TSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_dtlb_longpath - KTSB_STORE(%g1, %g7) + TSB_STORE(%g1, %g7) - KTSB_WRITE(%g1, %g5, %g6) + TSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 44dc093..fad1bd0 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -215,7 +215,7 @@ struct grpci2_priv { DEFINE_SPINLOCK(grpci2_dev_lock); struct grpci2_priv *grpci2priv; -int grpci2_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +int grpci2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct grpci2_priv *priv = dev->bus->sysdata; int irq_group; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index fe8fb44..1210fde 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -28,7 +28,7 @@ #include <asm/tlbflush.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq_regs.h> #include <asm/traps.h> diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 42f28c7..acaebb6 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -508,6 +508,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) } EXPORT_SYMBOL(mdesc_node_name); +static u64 max_cpus = 64; + static void __init report_platform_properties(void) { struct mdesc_handle *hp = mdesc_grab(); @@ -543,8 +545,10 @@ static void __init report_platform_properties(void) if (v) printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); v = mdesc_get_property(hp, pn, "max-cpus", NULL); - if (v) - printk("PLATFORM: max-cpus [%llu]\n", *v); + if (v) { + max_cpus = *v; + printk("PLATFORM: max-cpus [%llu]\n", max_cpus); + } #ifdef CONFIG_SMP { @@ -715,7 +719,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) } static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, - unsigned char def) + unsigned long def, unsigned long max) { u64 val; @@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, if (!val || val >= 64) goto use_default; + if (val > max) + val = max; + *mask = ((1U << val) * 64U) - 1U; return; @@ -736,19 +743,28 @@ use_default: static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, struct trap_per_cpu *tb) { + static int printed; const u64 *val; val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); + get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); + get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); - get_one_mondo_bits(val, &tb->resum_qmask, 6); + get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); - get_one_mondo_bits(val, &tb->nonresum_qmask, 2); + get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); + if (!printed++) { + pr_info("SUN4V: Mondo queue sizes " + "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", + tb->cpu_mondo_qmask + 1, + tb->dev_mondo_qmask + 1, + tb->resum_qmask + 1, + tb->nonresum_qmask + 1); + } } static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index a19f041..1aaf8c1 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -352,8 +352,8 @@ int __init pcic_probe(void) strcpy(pbm->prom_name, namebuf); { - extern volatile int t_nmi[1]; - extern int pcic_nmi_trap_patch[1]; + extern volatile int t_nmi[4]; + extern int pcic_nmi_trap_patch[4]; t_nmi[0] = pcic_nmi_trap_patch[0]; t_nmi[1] = pcic_nmi_trap_patch[1]; diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 8ac23e6..343b0f9 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c @@ -80,8 +80,11 @@ static void n2_pcr_write(u64 val) { unsigned long ret; - ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); - if (ret != HV_EOK) + if (val & PCR_N2_HTRACE) { + ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); + if (ret != HV_EOK) + write_pcr(val); + } else write_pcr(val); } @@ -106,6 +109,10 @@ static int __init register_perf_hsvc(void) perf_hsvc_group = HV_GRP_N2_CPU; break; + case SUN4V_CHIP_NIAGARA3: + perf_hsvc_group = HV_GRP_KT_CPU; + break; + default: return -ENODEV; } diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 62a0343..614da62 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -22,7 +22,7 @@ #include <asm/stacktrace.h> #include <asm/cpudata.h> #include <asm/uaccess.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/nmi.h> #include <asm/pcr.h> @@ -1343,7 +1343,8 @@ static bool __init supported_pmu(void) sparc_pmu = &niagara1_pmu; return true; } - if (!strcmp(sparc_pmu_type, "niagara2")) { + if (!strcmp(sparc_pmu_type, "niagara2") || + !strcmp(sparc_pmu_type, "niagara3")) { sparc_pmu = &niagara2_pmu; return true; } diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index c4dd099..3c5bb78 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -29,6 +29,7 @@ #include <linux/interrupt.h> #include <linux/cpu.h> #include <linux/initrd.h> +#include <linux/module.h> #include <asm/system.h> #include <asm/io.h> @@ -46,6 +47,8 @@ #include <asm/mmu.h> #include <asm/ns87303.h> #include <asm/btext.h> +#include <asm/elf.h> +#include <asm/mdesc.h> #ifdef CONFIG_IP_PNP #include <net/ipconfig.h> @@ -269,6 +272,40 @@ void __init sun4v_patch(void) sun4v_hvapi_init(); } +static void __init popc_patch(void) +{ + struct popc_3insn_patch_entry *p3; + struct popc_6insn_patch_entry *p6; + + p3 = &__popc_3insn_patch; + while (p3 < &__popc_3insn_patch_end) { + unsigned long i, addr = p3->addr; + + for (i = 0; i < 3; i++) { + *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; + wmb(); + __asm__ __volatile__("flush %0" + : : "r" (addr + (i * 4))); + } + + p3++; + } + + p6 = &__popc_6insn_patch; + while (p6 < &__popc_6insn_patch_end) { + unsigned long i, addr = p6->addr; + + for (i = 0; i < 6; i++) { + *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; + wmb(); + __asm__ __volatile__("flush %0" + : : "r" (addr + (i * 4))); + } + + p6++; + } +} + #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -278,6 +315,160 @@ void __init boot_cpu_id_too_large(int cpu) } #endif +/* On Ultra, we support all of the v8 capabilities. */ +unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | + HWCAP_SPARC_V9); +EXPORT_SYMBOL(sparc64_elf_hwcap); + +static const char *hwcaps[] = { + "flush", "stbar", "swap", "muldiv", "v9", + "ultra3", "blkinit", "n2", + + /* These strings are as they appear in the machine description + * 'hwcap-list' property for cpu nodes. + */ + "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", + "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", + "ima", "cspare", +}; + +void cpucap_info(struct seq_file *m) +{ + unsigned long caps = sparc64_elf_hwcap; + int i, printed = 0; + + seq_puts(m, "cpucaps\t\t: "); + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { + unsigned long bit = 1UL << i; + if (caps & bit) { + seq_printf(m, "%s%s", + printed ? "," : "", hwcaps[i]); + printed++; + } + } + seq_putc(m, '\n'); +} + +static void __init report_hwcaps(unsigned long caps) +{ + int i, printed = 0; + + printk(KERN_INFO "CPU CAPS: ["); + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { + unsigned long bit = 1UL << i; + if (caps & bit) { + printk(KERN_CONT "%s%s", + printed ? "," : "", hwcaps[i]); + if (++printed == 8) { + printk(KERN_CONT "]\n"); + printk(KERN_INFO "CPU CAPS: ["); + printed = 0; + } + } + } + printk(KERN_CONT "]\n"); +} + +static unsigned long __init mdesc_cpu_hwcap_list(void) +{ + struct mdesc_handle *hp; + unsigned long caps = 0; + const char *prop; + int len; + u64 pn; + + hp = mdesc_grab(); + if (!hp) + return 0; + + pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); + if (pn == MDESC_NODE_NULL) + goto out; + + prop = mdesc_get_property(hp, pn, "hwcap-list", &len); + if (!prop) + goto out; + + while (len) { + int i, plen; + + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { + unsigned long bit = 1UL << i; + + if (!strcmp(prop, hwcaps[i])) { + caps |= bit; + break; + } + } + + plen = strlen(prop) + 1; + prop += plen; + len -= plen; + } + +out: + mdesc_release(hp); + return caps; +} + +/* This yields a mask that user programs can use to figure out what + * instruction set this cpu supports. + */ +static void __init init_sparc64_elf_hwcap(void) +{ + unsigned long cap = sparc64_elf_hwcap; + unsigned long mdesc_caps; + + if (tlb_type == cheetah || tlb_type == cheetah_plus) + cap |= HWCAP_SPARC_ULTRA3; + else if (tlb_type == hypervisor) { + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= HWCAP_SPARC_BLKINIT; + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= HWCAP_SPARC_N2; + } + + cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); + + mdesc_caps = mdesc_cpu_hwcap_list(); + if (!mdesc_caps) { + if (tlb_type == spitfire) + cap |= AV_SPARC_VIS; + if (tlb_type == cheetah || tlb_type == cheetah_plus) + cap |= AV_SPARC_VIS | AV_SPARC_VIS2; + if (tlb_type == cheetah_plus) { + unsigned long impl, ver; + + __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); + impl = ((ver >> 32) & 0xffff); + if (impl == PANTHER_IMPL) + cap |= AV_SPARC_POPC; + } + if (tlb_type == hypervisor) { + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) + cap |= AV_SPARC_ASI_BLK_INIT; + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | + AV_SPARC_ASI_BLK_INIT | + AV_SPARC_POPC); + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | + AV_SPARC_FMAF); + } + } + sparc64_elf_hwcap = cap | mdesc_caps; + + report_hwcaps(sparc64_elf_hwcap); + + if (sparc64_elf_hwcap & AV_SPARC_POPC) + popc_patch(); +} + void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ @@ -337,6 +528,7 @@ void __init setup_arch(char **cmdline_p) init_cur_cpu_trap(current_thread_info()); paging_init(); + init_sparc64_elf_hwcap(); } extern int stop_a_enabled; diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 75fad42..1ba95af 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -29,6 +29,8 @@ #include <asm/visasm.h> #include <asm/compat_signal.h> +#include "sigutil.h" + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) /* This magic should be in g_upper[0] for all upper parts @@ -44,14 +46,14 @@ typedef struct { struct signal_frame32 { struct sparc_stackf32 ss; __siginfo32_t info; - /* __siginfo_fpu32_t * */ u32 fpu_save; + /* __siginfo_fpu_t * */ u32 fpu_save; unsigned int insns[2]; unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; - __siginfo_fpu_t fpu_state; -}; + /* __siginfo_rwin_t * */u32 rwin_save; +} __attribute__((aligned(8))); typedef struct compat_siginfo{ int si_signo; @@ -110,18 +112,14 @@ struct rt_signal_frame32 { compat_siginfo_t info; struct pt_regs32 regs; compat_sigset_t mask; - /* __siginfo_fpu32_t * */ u32 fpu_save; + /* __siginfo_fpu_t * */ u32 fpu_save; unsigned int insns[2]; stack_t32 stack; unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; - __siginfo_fpu_t fpu_state; -}; - -/* Align macros */ -#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15))) -#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15))) + /* __siginfo_rwin_t * */u32 rwin_save; +} __attribute__((aligned(8))); int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { @@ -192,30 +190,13 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) return 0; } -static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err; - - err = __get_user(fprs, &fpu->si_fprs); - fprs_write(0); - regs->tstate &= ~TSTATE_PEF; - if (fprs & FPRS_DL) - err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32)); - err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); - current_thread_info()->fpsaved[0] |= fprs; - return err; -} - void do_sigreturn32(struct pt_regs *regs) { struct signal_frame32 __user *sf; + compat_uptr_t fpu_save; + compat_uptr_t rwin_save; unsigned int psr; - unsigned pc, npc, fpu_save; + unsigned pc, npc; sigset_t set; unsigned seta[_COMPAT_NSIG_WORDS]; int err, i; @@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (fpu_save) - err |= restore_fpu_state32(regs, &sf->fpu_state); + if (!err && fpu_save) + err |= restore_fpu_state(regs, compat_ptr(fpu_save)); + err |= __get_user(rwin_save, &sf->rwin_save); + if (!err && rwin_save) { + if (restore_rwin_state(compat_ptr(rwin_save))) + goto segv; + } err |= __get_user(seta[0], &sf->info.si_mask); err |= copy_from_user(seta+1, &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); @@ -300,7 +286,9 @@ segv: asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) { struct rt_signal_frame32 __user *sf; - unsigned int psr, pc, npc, fpu_save, u_ss_sp; + unsigned int psr, pc, npc, u_ss_sp; + compat_uptr_t fpu_save; + compat_uptr_t rwin_save; mm_segment_t old_fs; sigset_t set; compat_sigset_t seta; @@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (fpu_save) - err |= restore_fpu_state32(regs, &sf->fpu_state); + if (!err && fpu_save) + err |= restore_fpu_state(regs, compat_ptr(fpu_save)); err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); err |= __get_user(u_ss_sp, &sf->stack.ss_sp); st.ss_sp = compat_ptr(u_ss_sp); @@ -376,6 +364,12 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); set_fs(old_fs); + err |= __get_user(rwin_save, &sf->rwin_save); + if (!err && rwin_save) { + if (restore_rwin_state(compat_ptr(rwin_save))) + goto segv; + } + switch (_NSIG_WORDS) { case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); @@ -433,26 +427,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns return (void __user *) sp; } -static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err = 0; - - fprs = current_thread_info()->fpsaved[0]; - if (fprs & FPRS_DL) - err |= copy_to_user(&fpu->si_float_regs[0], fpregs, - (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, - (sizeof(unsigned int) * 32)); - err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); - err |= __put_user(fprs, &fpu->si_fprs); - - return err; -} - /* The I-cache flush instruction only works in the primary ASI, which * right now is the nucleus, aka. kernel space. * @@ -515,18 +489,23 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; + int i, err, wsaved; + void __user *tail; int sigframe_size; u32 psr; - int i, err; unsigned int seta[_COMPAT_NSIG_WORDS]; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - sigframe_size = SF_ALIGNEDSZ; - if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) - sigframe_size -= sizeof(__siginfo_fpu_t); + wsaved = get_thread_wsaved(); + + sigframe_size = sizeof(*sf); + if (current_thread_info()->fpsaved[0] & FPRS_FEF) + sigframe_size += sizeof(__siginfo_fpu_t); + if (wsaved) + sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -534,8 +513,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; - if (get_thread_wsaved() != 0) - goto sigill; + tail = (sf + 1); /* 2. Save the current process state */ if (test_thread_flag(TIF_32BIT)) { @@ -560,11 +538,22 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, &sf->v8plus.asi); if (psr & PSR_EF) { - err |= save_fpu_state32(regs, &sf->fpu_state); - err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); + __siginfo_fpu_t __user *fp = tail; + tail += sizeof(*fp); + err |= save_fpu_state(regs, fp); + err |= __put_user((u64)fp, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } + if (wsaved) { + __siginfo_rwin_t __user *rwp = tail; + tail += sizeof(*rwp); + err |= save_rwin_state(wsaved, rwp); + err |= __put_user((u64)rwp, &sf->rwin_save); + set_thread_wsaved(0); + } else { + err |= __put_user(0, &sf->rwin_save); + } switch (_NSIG_WORDS) { case 4: seta[7] = (oldset->sig[3] >> 32); @@ -580,10 +569,21 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf->extramask, seta + 1, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); - err |= copy_in_user((u32 __user *)sf, - (u32 __user *)(regs->u_regs[UREG_FP]), - sizeof(struct reg_window32)); - + if (!wsaved) { + err |= copy_in_user((u32 __user *)sf, + (u32 __user *)(regs->u_regs[UREG_FP]), + sizeof(struct reg_window32)); + } else { + struct reg_window *rp; + + rp = ¤t_thread_info()->reg_window[wsaved - 1]; + for (i = 0; i < 8; i++) + err |= __put_user(rp->locals[i], &sf->ss.locals[i]); + for (i = 0; i < 6; i++) + err |= __put_user(rp->ins[i], &sf->ss.ins[i]); + err |= __put_user(rp->ins[6], &sf->ss.fp); + err |= __put_user(rp->ins[7], &sf->ss.callers_pc); + } if (err) goto sigsegv; @@ -613,7 +613,6 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ if (err) goto sigsegv; - flush_signal_insns(address); } return 0; @@ -632,18 +631,23 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, siginfo_t *info) { struct rt_signal_frame32 __user *sf; + int i, err, wsaved; + void __user *tail; int sigframe_size; u32 psr; - int i, err; compat_sigset_t seta; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - sigframe_size = RT_ALIGNEDSZ; - if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) - sigframe_size -= sizeof(__siginfo_fpu_t); + wsaved = get_thread_wsaved(); + + sigframe_size = sizeof(*sf); + if (current_thread_info()->fpsaved[0] & FPRS_FEF) + sigframe_size += sizeof(__siginfo_fpu_t); + if (wsaved) + sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -651,8 +655,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; - if (get_thread_wsaved() != 0) - goto sigill; + tail = (sf + 1); /* 2. Save the current process state */ if (test_thread_flag(TIF_32BIT)) { @@ -677,11 +680,22 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, &sf->v8plus.asi); if (psr & PSR_EF) { - err |= save_fpu_state32(regs, &sf->fpu_state); - err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); + __siginfo_fpu_t __user *fp = tail; + tail += sizeof(*fp); + err |= save_fpu_state(regs, fp); + err |= __put_user((u64)fp, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } + if (wsaved) { + __siginfo_rwin_t __user *rwp = tail; + tail += sizeof(*rwp); + err |= save_rwin_state(wsaved, rwp); + err |= __put_user((u64)rwp, &sf->rwin_save); + set_thread_wsaved(0); + } else { + err |= __put_user(0, &sf->rwin_save); + } /* Update the siginfo structure. */ err |= copy_siginfo_to_user32(&sf->info, info); @@ -703,9 +717,21 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); - err |= copy_in_user((u32 __user *)sf, - (u32 __user *)(regs->u_regs[UREG_FP]), - sizeof(struct reg_window32)); + if (!wsaved) { + err |= copy_in_user((u32 __user *)sf, + (u32 __user *)(regs->u_regs[UREG_FP]), + sizeof(struct reg_window32)); + } else { + struct reg_window *rp; + + rp = ¤t_thread_info()->reg_window[wsaved - 1]; + for (i = 0; i < 8; i++) + err |= __put_user(rp->locals[i], &sf->ss.locals[i]); + for (i = 0; i < 6; i++) + err |= __put_user(rp->ins[i], &sf->ss.ins[i]); + err |= __put_user(rp->ins[6], &sf->ss.fp); + err |= __put_user(rp->ins[7], &sf->ss.callers_pc); + } if (err) goto sigsegv; diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 5e5c5fd..04ede8f 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -26,6 +26,8 @@ #include <asm/pgtable.h> #include <asm/cacheflush.h> /* flush_sig_insns */ +#include "sigutil.h" + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern void fpsave(unsigned long *fpregs, unsigned long *fsr, @@ -39,8 +41,8 @@ struct signal_frame { unsigned long insns[2] __attribute__ ((aligned (8))); unsigned int extramask[_NSIG_WORDS - 1]; unsigned int extra_size; /* Should be 0 */ - __siginfo_fpu_t fpu_state; -}; + __siginfo_rwin_t __user *rwin_save; +} __attribute__((aligned(8))); struct rt_signal_frame { struct sparc_stackf ss; @@ -51,8 +53,8 @@ struct rt_signal_frame { unsigned int insns[2]; stack_t stack; unsigned int extra_size; /* Should be 0 */ - __siginfo_fpu_t fpu_state; -}; + __siginfo_rwin_t __user *rwin_save; +} __attribute__((aligned(8))); /* Align macros */ #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7))) @@ -79,43 +81,13 @@ asmlinkage int sys_sigsuspend(old_sigset_t set) return _sigpause_common(set); } -static inline int -restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - int err; -#ifdef CONFIG_SMP - if (test_tsk_thread_flag(current, TIF_USEDFPU)) - regs->psr &= ~PSR_EF; -#else - if (current == last_task_used_math) { - last_task_used_math = NULL; - regs->psr &= ~PSR_EF; - } -#endif - set_used_math(); - clear_tsk_thread_flag(current, TIF_USEDFPU); - - if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) - return -EFAULT; - - err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], - (sizeof(unsigned long) * 32)); - err |= __get_user(current->thread.fsr, &fpu->si_fsr); - err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); - if (current->thread.fpqdepth != 0) - err |= __copy_from_user(¤t->thread.fpqueue[0], - &fpu->si_fpqueue[0], - ((sizeof(unsigned long) + - (sizeof(unsigned long *)))*16)); - return err; -} - asmlinkage void do_sigreturn(struct pt_regs *regs) { struct signal_frame __user *sf; unsigned long up_psr, pc, npc; sigset_t set; __siginfo_fpu_t __user *fpu_save; + __siginfo_rwin_t __user *rwin_save; int err; /* Always make any pending restarted system calls return -EINTR */ @@ -150,9 +122,11 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - if (fpu_save) err |= restore_fpu_state(regs, fpu_save); + err |= __get_user(rwin_save, &sf->rwin_save); + if (rwin_save) + err |= restore_rwin_state(rwin_save); /* This is pretty much atomic, no amount locking would prevent * the races which exist anyways. @@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) struct rt_signal_frame __user *sf; unsigned int psr, pc, npc; __siginfo_fpu_t __user *fpu_save; + __siginfo_rwin_t __user *rwin_save; mm_segment_t old_fs; sigset_t set; stack_t st; @@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) pt_regs_clear_syscall(regs); err |= __get_user(fpu_save, &sf->fpu_save); - - if (fpu_save) + if (!err && fpu_save) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); @@ -228,6 +202,12 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf); set_fs(old_fs); + err |= __get_user(rwin_save, &sf->rwin_save); + if (!err && rwin_save) { + if (restore_rwin_state(rwin_save)) + goto segv; + } + sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; @@ -280,53 +260,23 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) sp; } -static inline int -save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - int err = 0; -#ifdef CONFIG_SMP - if (test_tsk_thread_flag(current, TIF_USEDFPU)) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - regs->psr &= ~(PSR_EF); - clear_tsk_thread_flag(current, TIF_USEDFPU); - } -#else - if (current == last_task_used_math) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - last_task_used_math = NULL; - regs->psr &= ~(PSR_EF); - } -#endif - err |= __copy_to_user(&fpu->si_float_regs[0], - ¤t->thread.float_regs[0], - (sizeof(unsigned long) * 32)); - err |= __put_user(current->thread.fsr, &fpu->si_fsr); - err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); - if (current->thread.fpqdepth != 0) - err |= __copy_to_user(&fpu->si_fpqueue[0], - ¤t->thread.fpqueue[0], - ((sizeof(unsigned long) + - (sizeof(unsigned long *)))*16)); - clear_used_math(); - return err; -} - static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) { struct signal_frame __user *sf; - int sigframe_size, err; + int sigframe_size, err, wsaved; + void __user *tail; /* 1. Make sure everything is clean */ synchronize_user_stack(); - sigframe_size = SF_ALIGNEDSZ; - if (!used_math()) - sigframe_size -= sizeof(__siginfo_fpu_t); + wsaved = current_thread_info()->w_saved; + + sigframe_size = sizeof(*sf); + if (used_math()) + sigframe_size += sizeof(__siginfo_fpu_t); + if (wsaved) + sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); @@ -334,8 +284,7 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer(sf, sigframe_size)) goto sigill_and_return; - if (current_thread_info()->w_saved != 0) - goto sigill_and_return; + tail = sf + 1; /* 2. Save the current process state */ err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs)); @@ -343,17 +292,34 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0, &sf->extra_size); if (used_math()) { - err |= save_fpu_state(regs, &sf->fpu_state); - err |= __put_user(&sf->fpu_state, &sf->fpu_save); + __siginfo_fpu_t __user *fp = tail; + tail += sizeof(*fp); + err |= save_fpu_state(regs, fp); + err |= __put_user(fp, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } + if (wsaved) { + __siginfo_rwin_t __user *rwp = tail; + tail += sizeof(*rwp); + err |= save_rwin_state(wsaved, rwp); + err |= __put_user(rwp, &sf->rwin_save); + } else { + err |= __put_user(0, &sf->rwin_save); + } err |= __put_user(oldset->sig[0], &sf->info.si_mask); err |= __copy_to_user(sf->extramask, &oldset->sig[1], (_NSIG_WORDS - 1) * sizeof(unsigned int)); - err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], - sizeof(struct reg_window32)); + if (!wsaved) { + err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], + sizeof(struct reg_window32)); + } else { + struct reg_window32 *rp; + + rp = ¤t_thread_info()->reg_window[wsaved - 1]; + err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); + } if (err) goto sigsegv; @@ -399,21 +365,24 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; - int sigframe_size; + int sigframe_size, wsaved; + void __user *tail; unsigned int psr; int err; synchronize_user_stack(); - sigframe_size = RT_ALIGNEDSZ; - if (!used_math()) - sigframe_size -= sizeof(__siginfo_fpu_t); + wsaved = current_thread_info()->w_saved; + sigframe_size = sizeof(*sf); + if (used_math()) + sigframe_size += sizeof(__siginfo_fpu_t); + if (wsaved) + sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; - if (current_thread_info()->w_saved != 0) - goto sigill; + tail = sf + 1; err = __put_user(regs->pc, &sf->regs.pc); err |= __put_user(regs->npc, &sf->regs.npc); err |= __put_user(regs->y, &sf->regs.y); @@ -425,11 +394,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(0, &sf->extra_size); if (psr & PSR_EF) { - err |= save_fpu_state(regs, &sf->fpu_state); - err |= __put_user(&sf->fpu_state, &sf->fpu_save); + __siginfo_fpu_t *fp = tail; + tail += sizeof(*fp); + err |= save_fpu_state(regs, fp); + err |= __put_user(fp, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } + if (wsaved) { + __siginfo_rwin_t *rwp = tail; + tail += sizeof(*rwp); + err |= save_rwin_state(wsaved, rwp); + err |= __put_user(rwp, &sf->rwin_save); + } else { + err |= __put_user(0, &sf->rwin_save); + } err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); /* Setup sigaltstack */ @@ -437,8 +416,15 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); - err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], - sizeof(struct reg_window32)); + if (!wsaved) { + err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], + sizeof(struct reg_window32)); + } else { + struct reg_window32 *rp; + + rp = ¤t_thread_info()->reg_window[wsaved - 1]; + err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); + } err |= copy_siginfo_to_user(&sf->info, info); diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 006fe45..47509df 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -34,6 +34,7 @@ #include "entry.h" #include "systbls.h" +#include "sigutil.h" #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -236,7 +237,7 @@ struct rt_signal_frame { __siginfo_fpu_t __user *fpu_save; stack_t stack; sigset_t mask; - __siginfo_fpu_t fpu_state; + __siginfo_rwin_t *rwin_save; }; static long _sigpause_common(old_sigset_t set) @@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigset_t set) return _sigpause_common(set); } -static inline int -restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err; - - err = __get_user(fprs, &fpu->si_fprs); - fprs_write(0); - regs->tstate &= ~TSTATE_PEF; - if (fprs & FPRS_DL) - err |= copy_from_user(fpregs, &fpu->si_float_regs[0], - (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], - (sizeof(unsigned int) * 32)); - err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); - current_thread_info()->fpsaved[0] |= fprs; - return err; -} - void do_rt_sigreturn(struct pt_regs *regs) { struct rt_signal_frame __user *sf; unsigned long tpc, tnpc, tstate; __siginfo_fpu_t __user *fpu_save; + __siginfo_rwin_t __user *rwin_save; sigset_t set; int err; @@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)); err |= __get_user(fpu_save, &sf->fpu_save); - if (fpu_save) - err |= restore_fpu_state(regs, &sf->fpu_state); + if (!err && fpu_save) + err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); @@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *regs) if (err) goto segv; + err |= __get_user(rwin_save, &sf->rwin_save); + if (!err && rwin_save) { + if (restore_rwin_state(rwin_save)) + goto segv; + } + regs->tpc = tpc; regs->tnpc = tnpc; @@ -351,34 +337,13 @@ segv: } /* Checks if the fp is valid */ -static int invalid_frame_pointer(void __user *fp, int fplen) +static int invalid_frame_pointer(void __user *fp) { if (((unsigned long) fp) & 15) return 1; return 0; } -static inline int -save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ - unsigned long *fpregs = current_thread_info()->fpregs; - unsigned long fprs; - int err = 0; - - fprs = current_thread_info()->fpsaved[0]; - if (fprs & FPRS_DL) - err |= copy_to_user(&fpu->si_float_regs[0], fpregs, - (sizeof(unsigned int) * 32)); - if (fprs & FPRS_DU) - err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, - (sizeof(unsigned int) * 32)); - err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); - err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); - err |= __put_user(fprs, &fpu->si_fprs); - - return err; -} - static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; @@ -414,34 +379,48 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; - int sigframe_size, err; + int wsaved, err, sf_size; + void __user *tail; /* 1. Make sure everything is clean */ synchronize_user_stack(); save_and_clear_fpu(); - sigframe_size = sizeof(struct rt_signal_frame); - if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) - sigframe_size -= sizeof(__siginfo_fpu_t); + wsaved = get_thread_wsaved(); + sf_size = sizeof(struct rt_signal_frame); + if (current_thread_info()->fpsaved[0] & FPRS_FEF) + sf_size += sizeof(__siginfo_fpu_t); + if (wsaved) + sf_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) - get_sigframe(ka, regs, sigframe_size); - - if (invalid_frame_pointer (sf, sigframe_size)) - goto sigill; + get_sigframe(ka, regs, sf_size); - if (get_thread_wsaved() != 0) + if (invalid_frame_pointer (sf)) goto sigill; + tail = (sf + 1); + /* 2. Save the current process state */ err = copy_to_user(&sf->regs, regs, sizeof (*regs)); if (current_thread_info()->fpsaved[0] & FPRS_FEF) { - err |= save_fpu_state(regs, &sf->fpu_state); - err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); + __siginfo_fpu_t __user *fpu_save = tail; + tail += sizeof(__siginfo_fpu_t); + err |= save_fpu_state(regs, fpu_save); + err |= __put_user((u64)fpu_save, &sf->fpu_save); } else { err |= __put_user(0, &sf->fpu_save); } + if (wsaved) { + __siginfo_rwin_t __user *rwin_save = tail; + tail += sizeof(__siginfo_rwin_t); + err |= save_rwin_state(wsaved, rwin_save); + err |= __put_user((u64)rwin_save, &sf->rwin_save); + set_thread_wsaved(0); + } else { + err |= __put_user(0, &sf->rwin_save); + } /* Setup sigaltstack */ err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); @@ -450,10 +429,17 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); - err |= copy_in_user((u64 __user *)sf, - (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS), - sizeof(struct reg_window)); + if (!wsaved) { + err |= copy_in_user((u64 __user *)sf, + (u64 __user *)(regs->u_regs[UREG_FP] + + STACK_BIAS), + sizeof(struct reg_window)); + } else { + struct reg_window *rp; + rp = ¤t_thread_info()->reg_window[wsaved - 1]; + err |= copy_to_user(sf, rp, sizeof(struct reg_window)); + } if (info) err |= copy_siginfo_to_user(&sf->info, info); else { diff --git a/arch/sparc/kernel/sigutil.h b/arch/sparc/kernel/sigutil.h new file mode 100644 index 0000000..d223aa4 --- /dev/null +++ b/arch/sparc/kernel/sigutil.h @@ -0,0 +1,9 @@ +#ifndef _SIGUTIL_H +#define _SIGUTIL_H + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin); +int restore_rwin_state(__siginfo_rwin_t __user *rp); + +#endif /* _SIGUTIL_H */ diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c new file mode 100644 index 0000000..35c7897 --- /dev/null +++ b/arch/sparc/kernel/sigutil_32.c @@ -0,0 +1,120 @@ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/thread_info.h> +#include <linux/uaccess.h> +#include <linux/sched.h> + +#include <asm/sigcontext.h> +#include <asm/fpumacro.h> +#include <asm/ptrace.h> + +#include "sigutil.h" + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + int err = 0; +#ifdef CONFIG_SMP + if (test_tsk_thread_flag(current, TIF_USEDFPU)) { + put_psr(get_psr() | PSR_EF); + fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, + ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); + regs->psr &= ~(PSR_EF); + clear_tsk_thread_flag(current, TIF_USEDFPU); + } +#else + if (current == last_task_used_math) { + put_psr(get_psr() | PSR_EF); + fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, + ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); + last_task_used_math = NULL; + regs->psr &= ~(PSR_EF); + } +#endif + err |= __copy_to_user(&fpu->si_float_regs[0], + ¤t->thread.float_regs[0], + (sizeof(unsigned long) * 32)); + err |= __put_user(current->thread.fsr, &fpu->si_fsr); + err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); + if (current->thread.fpqdepth != 0) + err |= __copy_to_user(&fpu->si_fpqueue[0], + ¤t->thread.fpqueue[0], + ((sizeof(unsigned long) + + (sizeof(unsigned long *)))*16)); + clear_used_math(); + return err; +} + +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + int err; +#ifdef CONFIG_SMP + if (test_tsk_thread_flag(current, TIF_USEDFPU)) + regs->psr &= ~PSR_EF; +#else + if (current == last_task_used_math) { + last_task_used_math = NULL; + regs->psr &= ~PSR_EF; + } +#endif + set_used_math(); + clear_tsk_thread_flag(current, TIF_USEDFPU); + + if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) + return -EFAULT; + + err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], + (sizeof(unsigned long) * 32)); + err |= __get_user(current->thread.fsr, &fpu->si_fsr); + err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); + if (current->thread.fpqdepth != 0) + err |= __copy_from_user(¤t->thread.fpqueue[0], + &fpu->si_fpqueue[0], + ((sizeof(unsigned long) + + (sizeof(unsigned long *)))*16)); + return err; +} + +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) +{ + int i, err = __put_user(wsaved, &rwin->wsaved); + + for (i = 0; i < wsaved; i++) { + struct reg_window32 *rp; + unsigned long fp; + + rp = ¤t_thread_info()->reg_window[i]; + fp = current_thread_info()->rwbuf_stkptrs[i]; + err |= copy_to_user(&rwin->reg_window[i], rp, + sizeof(struct reg_window32)); + err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); + } + return err; +} + +int restore_rwin_state(__siginfo_rwin_t __user *rp) +{ + struct thread_info *t = current_thread_info(); + int i, wsaved, err; + + __get_user(wsaved, &rp->wsaved); + if (wsaved > NSWINS) + return -EFAULT; + + err = 0; + for (i = 0; i < wsaved; i++) { + err |= copy_from_user(&t->reg_window[i], + &rp->reg_window[i], + sizeof(struct reg_window32)); + err |= __get_user(t->rwbuf_stkptrs[i], + &rp->rwbuf_stkptrs[i]); + } + if (err) + return err; + + t->w_saved = wsaved; + synchronize_user_stack(); + if (t->w_saved) + return -EFAULT; + return 0; + +} diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c new file mode 100644 index 0000000..e7dc508 --- /dev/null +++ b/arch/sparc/kernel/sigutil_64.c @@ -0,0 +1,93 @@ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/thread_info.h> +#include <linux/uaccess.h> + +#include <asm/sigcontext.h> +#include <asm/fpumacro.h> +#include <asm/ptrace.h> + +#include "sigutil.h" + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err = 0; + + fprs = current_thread_info()->fpsaved[0]; + if (fprs & FPRS_DL) + err |= copy_to_user(&fpu->si_float_regs[0], fpregs, + (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, + (sizeof(unsigned int) * 32)); + err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); + err |= __put_user(fprs, &fpu->si_fprs); + + return err; +} + +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ + unsigned long *fpregs = current_thread_info()->fpregs; + unsigned long fprs; + int err; + + err = __get_user(fprs, &fpu->si_fprs); + fprs_write(0); + regs->tstate &= ~TSTATE_PEF; + if (fprs & FPRS_DL) + err |= copy_from_user(fpregs, &fpu->si_float_regs[0], + (sizeof(unsigned int) * 32)); + if (fprs & FPRS_DU) + err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], + (sizeof(unsigned int) * 32)); + err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); + current_thread_info()->fpsaved[0] |= fprs; + return err; +} + +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) +{ + int i, err = __put_user(wsaved, &rwin->wsaved); + + for (i = 0; i < wsaved; i++) { + struct reg_window *rp = ¤t_thread_info()->reg_window[i]; + unsigned long fp = current_thread_info()->rwbuf_stkptrs[i]; + + err |= copy_to_user(&rwin->reg_window[i], rp, + sizeof(struct reg_window)); + err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); + } + return err; +} + +int restore_rwin_state(__siginfo_rwin_t __user *rp) +{ + struct thread_info *t = current_thread_info(); + int i, wsaved, err; + + __get_user(wsaved, &rp->wsaved); + if (wsaved > NSWINS) + return -EFAULT; + + err = 0; + for (i = 0; i < wsaved; i++) { + err |= copy_from_user(&t->reg_window[i], + &rp->reg_window[i], + sizeof(struct reg_window)); + err |= __get_user(t->rwbuf_stkptrs[i], + &rp->rwbuf_stkptrs[i]); + } + if (err) + return err; + + set_thread_wsaved(wsaved); + synchronize_user_stack(); + if (get_thread_wsaved()) + return -EFAULT; + return 0; +} diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 21b1253..f671e7f 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -22,7 +22,7 @@ #include <linux/delay.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/page.h> diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 99cb172..4a442c3 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -28,7 +28,7 @@ #include <asm/head.h> #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/tlbflush.h> #include <asm/mmu_context.h> #include <asm/cpudata.h> diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 372ad59..83b47ab 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/bitops.h> #include <asm/system.h> #include <asm/cpudata.h> @@ -38,5 +39,15 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); EXPORT_SYMBOL(sun4v_niagara2_getperf); EXPORT_SYMBOL(sun4v_niagara2_setperf); +/* from hweight.S */ +EXPORT_SYMBOL(__arch_hweight8); +EXPORT_SYMBOL(__arch_hweight16); +EXPORT_SYMBOL(__arch_hweight32); +EXPORT_SYMBOL(__arch_hweight64); + +/* from ffs_ffz.S */ +EXPORT_SYMBOL(ffs); +EXPORT_SYMBOL(__ffs); + /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line); diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c index 8cdbe59..c59af54 100644 --- a/arch/sparc/kernel/sstate.c +++ b/arch/sparc/kernel/sstate.c @@ -14,14 +14,9 @@ #include <asm/head.h> #include <asm/io.h> -static int hv_supports_soft_state; - -static unsigned long kimage_addr_to_ra(const char *p) -{ - unsigned long val = (unsigned long) p; +#include "kernel.h" - return kern_base + (val - KERNBASE); -} +static int hv_supports_soft_state; static void do_set_sstate(unsigned long state, const char *msg) { diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 44e5faf..d97f3eb 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -81,7 +81,6 @@ SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4) SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5) SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1) SIGN1(sys32_mlockall, sys_mlockall, %o0) -SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0) SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1) SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6e492d5..09d8ec4 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -67,7 +67,7 @@ sys_call_table: /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index f566518..edbec45 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -68,7 +68,7 @@ sys_call_table32: .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep -/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl +/*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys_nis_syscall .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy @@ -145,7 +145,7 @@ sys_call_table: .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 35cff16..76e4ac1 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -22,6 +22,7 @@ #include <linux/bitops.h> #include <linux/perf_event.h> #include <linux/ratelimit.h> +#include <linux/bitops.h> #include <asm/fpumacro.h> enum direction { @@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) } } -static char popc_helper[] = { -0, 1, 1, 2, 1, 2, 2, 3, -1, 2, 2, 3, 2, 3, 3, 4, -}; - int handle_popc(u32 insn, struct pt_regs *regs) { - u64 value; - int ret, i, rd = ((insn >> 25) & 0x1f); int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; + int ret, rd = ((insn >> 25) & 0x1f); + u64 value; perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); if (insn & 0x2000) { @@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); value = fetch_reg(insn & 0x1f, regs); } - for (ret = 0, i = 0; i < 16; i++) { - ret += popc_helper[value & 0xf]; - value >>= 4; - } + ret = hweight64(value); if (rd < 16) { if (rd) regs->u_regs[rd] = ret; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index c022075..0e16056 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -107,7 +107,26 @@ SECTIONS *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } - + .swapper_tsb_phys_patch : { + __swapper_tsb_phys_patch = .; + *(.swapper_tsb_phys_patch) + __swapper_tsb_phys_patch_end = .; + } + .swapper_4m_tsb_phys_patch : { + __swapper_4m_tsb_phys_patch = .; + *(.swapper_4m_tsb_phys_patch) + __swapper_4m_tsb_phys_patch_end = .; + } + .popc_3insn_patch : { + __popc_3insn_patch = .; + *(.popc_3insn_patch) + __popc_3insn_patch_end = .; + } + .popc_6insn_patch : { + __popc_6insn_patch = .; + *(.popc_6insn_patch) + __popc_6insn_patch_end = .; + } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 7f01b8f..a3fc437 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o -lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o +lib-$(CONFIG_SPARC64) += NG2patch.o lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o obj-y += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S deleted file mode 100644 index 73b6b7c..0000000 --- a/arch/sparc/lib/NG2page.S +++ /dev/null @@ -1,61 +0,0 @@ -/* NG2page.S: Niagara-2 optimized clear and copy page. - * - * Copyright (C) 2007 (davem@davemloft.net) - */ - -#include <asm/asi.h> -#include <asm/page.h> -#include <asm/visasm.h> - - .text - .align 32 - - /* This is heavily simplified from the sun4u variants - * because Niagara-2 does not have any D-cache aliasing issues. - */ -NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ - prefetch [%o1 + 0x00], #one_read - prefetch [%o1 + 0x40], #one_read - VISEntryHalf - set PAGE_SIZE, %g7 - sub %o0, %o1, %g3 -1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P - subcc %g7, 64, %g7 - ldda [%o1] ASI_BLK_P, %f0 - stda %f0, [%o1 + %g3] ASI_BLK_P - add %o1, 64, %o1 - bne,pt %xcc, 1b - prefetch [%o1 + 0x40], #one_read - membar #Sync - VISExitHalf - retl - nop - -#define BRANCH_ALWAYS 0x10680000 -#define NOP 0x01000000 -#define NG_DO_PATCH(OLD, NEW) \ - sethi %hi(NEW), %g1; \ - or %g1, %lo(NEW), %g1; \ - sethi %hi(OLD), %g2; \ - or %g2, %lo(OLD), %g2; \ - sub %g1, %g2, %g1; \ - sethi %hi(BRANCH_ALWAYS), %g3; \ - sll %g1, 11, %g1; \ - srl %g1, 11 + 2, %g1; \ - or %g3, %lo(BRANCH_ALWAYS), %g3; \ - or %g3, %g1, %g3; \ - stw %g3, [%g2]; \ - sethi %hi(NOP), %g3; \ - or %g3, %lo(NOP), %g3; \ - stw %g3, [%g2 + 0x4]; \ - flush %g2; - - .globl niagara2_patch_pageops - .type niagara2_patch_pageops,#function -niagara2_patch_pageops: - NG_DO_PATCH(copy_user_page, NG2copy_user_page) - NG_DO_PATCH(_clear_page, NGclear_page) - NG_DO_PATCH(clear_user_page, NGclear_user_page) - retl - nop - .size niagara2_patch_pageops,.-niagara2_patch_pageops diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S index 428920d..b9e790b 100644 --- a/arch/sparc/lib/NGpage.S +++ b/arch/sparc/lib/NGpage.S @@ -16,55 +16,91 @@ */ NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ - prefetch [%o1 + 0x00], #one_read - mov 8, %g1 - mov 16, %g2 - mov 24, %g3 + save %sp, -192, %sp + rd %asi, %g3 + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi set PAGE_SIZE, %g7 + prefetch [%i1 + 0x00], #one_read + prefetch [%i1 + 0x40], #one_read -1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 - prefetch [%o1 + 0x40], #one_read - add %o1, 32, %o1 - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P - ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 - add %o1, 32, %o1 - add %o0, 32, %o0 - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P - subcc %g7, 64, %g7 +1: prefetch [%i1 + 0x80], #one_read + prefetch [%i1 + 0xc0], #one_read + ldda [%i1 + 0x00] %asi, %o2 + ldda [%i1 + 0x10] %asi, %o4 + ldda [%i1 + 0x20] %asi, %l2 + ldda [%i1 + 0x30] %asi, %l4 + stxa %o2, [%i0 + 0x00] %asi + stxa %o3, [%i0 + 0x08] %asi + stxa %o4, [%i0 + 0x10] %asi + stxa %o5, [%i0 + 0x18] %asi + stxa %l2, [%i0 + 0x20] %asi + stxa %l3, [%i0 + 0x28] %asi + stxa %l4, [%i0 + 0x30] %asi + stxa %l5, [%i0 + 0x38] %asi + ldda [%i1 + 0x40] %asi, %o2 + ldda [%i1 + 0x50] %asi, %o4 + ldda [%i1 + 0x60] %asi, %l2 + ldda [%i1 + 0x70] %asi, %l4 + stxa %o2, [%i0 + 0x40] %asi + stxa %o3, [%i0 + 0x48] %asi + stxa %o4, [%i0 + 0x50] %asi + stxa %o5, [%i0 + 0x58] %asi + stxa %l2, [%i0 + 0x60] %asi + stxa %l3, [%i0 + 0x68] %asi + stxa %l4, [%i0 + 0x70] %asi + stxa %l5, [%i0 + 0x78] %asi + add %i1, 128, %i1 + subcc %g7, 128, %g7 bne,pt %xcc, 1b - add %o0, 32, %o0 + add %i0, 128, %i0 + wr %g3, 0x0, %asi membar #Sync - retl - nop + ret + restore - .globl NGclear_page, NGclear_user_page + .align 32 NGclear_page: /* %o0=dest */ NGclear_user_page: /* %o0=dest, %o1=vaddr */ - mov 8, %g1 - mov 16, %g2 - mov 24, %g3 + rd %asi, %g3 + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi set PAGE_SIZE, %g7 -1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P - add %o0, 32, %o0 - stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P - subcc %g7, 64, %g7 +1: stxa %g0, [%o0 + 0x00] %asi + stxa %g0, [%o0 + 0x08] %asi + stxa %g0, [%o0 + 0x10] %asi + stxa %g0, [%o0 + 0x18] %asi + stxa %g0, [%o0 + 0x20] %asi + stxa %g0, [%o0 + 0x28] %asi + stxa %g0, [%o0 + 0x30] %asi + stxa %g0, [%o0 + 0x38] %asi + stxa %g0, [%o0 + 0x40] %asi + stxa %g0, [%o0 + 0x48] %asi + stxa %g0, [%o0 + 0x50] %asi + stxa %g0, [%o0 + 0x58] %asi + stxa %g0, [%o0 + 0x60] %asi + stxa %g0, [%o0 + 0x68] %asi + stxa %g0, [%o0 + 0x70] %asi + stxa %g0, [%o0 + 0x78] %asi + stxa %g0, [%o0 + 0x80] %asi + stxa %g0, [%o0 + 0x88] %asi + stxa %g0, [%o0 + 0x90] %asi + stxa %g0, [%o0 + 0x98] %asi + stxa %g0, [%o0 + 0xa0] %asi + stxa %g0, [%o0 + 0xa8] %asi + stxa %g0, [%o0 + 0xb0] %asi + stxa %g0, [%o0 + 0xb8] %asi + stxa %g0, [%o0 + 0xc0] %asi + stxa %g0, [%o0 + 0xc8] %asi + stxa %g0, [%o0 + 0xd0] %asi + stxa %g0, [%o0 + 0xd8] %asi + stxa %g0, [%o0 + 0xe0] %asi + stxa %g0, [%o0 + 0xe8] %asi + stxa %g0, [%o0 + 0xf0] %asi + stxa %g0, [%o0 + 0xf8] %asi + subcc %g7, 256, %g7 bne,pt %xcc, 1b - add %o0, 32, %o0 + add %o0, 256, %o0 + wr %g3, 0x0, %asi membar #Sync retl nop diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index d3c7a12..1d32b54 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -7,7 +7,7 @@ * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf */ -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/spinlock.h> #include <linux/module.h> @@ -55,7 +55,7 @@ int atomic_cmpxchg(atomic_t *v, int old, int new) } EXPORT_SYMBOL(atomic_cmpxchg); -int atomic_add_unless(atomic_t *v, int a, int u) +int __atomic_add_unless(atomic_t *v, int a, int u) { int ret; unsigned long flags; @@ -65,9 +65,9 @@ int atomic_add_unless(atomic_t *v, int a, int u) if (ret != u) v->counter += a; spin_unlock_irqrestore(ATOMIC_HASH(v), flags); - return ret != u; + return ret; } -EXPORT_SYMBOL(atomic_add_unless); +EXPORT_SYMBOL(__atomic_add_unless); /* Atomic operations are already serializing */ void atomic_set(atomic_t *v, int i) diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S new file mode 100644 index 0000000..b39389f --- /dev/null +++ b/arch/sparc/lib/ffs.S @@ -0,0 +1,84 @@ +#include <linux/linkage.h> + + .register %g2,#scratch + + .text + .align 32 + +ENTRY(ffs) + brnz,pt %o0, 1f + mov 1, %o1 + retl + clr %o0 + nop + nop +ENTRY(__ffs) + sllx %o0, 32, %g1 /* 1 */ + srlx %o0, 32, %g2 + + clr %o1 /* 2 */ + movrz %g1, %g2, %o0 + + movrz %g1, 32, %o1 /* 3 */ +1: clr %o2 + + sllx %o0, (64 - 16), %g1 /* 4 */ + srlx %o0, 16, %g2 + + movrz %g1, %g2, %o0 /* 5 */ + clr %o3 + + movrz %g1, 16, %o2 /* 6 */ + clr %o4 + + and %o0, 0xff, %g1 /* 7 */ + srlx %o0, 8, %g2 + + movrz %g1, %g2, %o0 /* 8 */ + clr %o5 + + movrz %g1, 8, %o3 /* 9 */ + add %o2, %o1, %o2 + + and %o0, 0xf, %g1 /* 10 */ + srlx %o0, 4, %g2 + + movrz %g1, %g2, %o0 /* 11 */ + add %o2, %o3, %o2 + + movrz %g1, 4, %o4 /* 12 */ + + and %o0, 0x3, %g1 /* 13 */ + srlx %o0, 2, %g2 + + movrz %g1, %g2, %o0 /* 14 */ + add %o2, %o4, %o2 + + movrz %g1, 2, %o5 /* 15 */ + + and %o0, 0x1, %g1 /* 16 */ + + add %o2, %o5, %o2 /* 17 */ + xor %g1, 0x1, %g1 + + retl /* 18 */ + add %o2, %g1, %o0 +ENDPROC(ffs) +ENDPROC(__ffs) + + .section .popc_6insn_patch, "ax" + .word ffs + brz,pn %o0, 98f + neg %o0, %g1 + xnor %o0, %g1, %o1 + popc %o1, %o0 +98: retl + nop + .word __ffs + neg %o0, %g1 + xnor %o0, %g1, %o1 + popc %o1, %o0 + retl + sub %o0, 1, %o0 + nop + .previous diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S new file mode 100644 index 0000000..95414e0 --- /dev/null +++ b/arch/sparc/lib/hweight.S @@ -0,0 +1,51 @@ +#include <linux/linkage.h> + + .text + .align 32 +ENTRY(__arch_hweight8) + ba,pt %xcc, __sw_hweight8 + nop + nop +ENDPROC(__arch_hweight8) + .section .popc_3insn_patch, "ax" + .word __arch_hweight8 + sllx %o0, 64-8, %g1 + retl + popc %g1, %o0 + .previous + +ENTRY(__arch_hweight16) + ba,pt %xcc, __sw_hweight16 + nop + nop +ENDPROC(__arch_hweight16) + .section .popc_3insn_patch, "ax" + .word __arch_hweight16 + sllx %o0, 64-16, %g1 + retl + popc %g1, %o0 + .previous + +ENTRY(__arch_hweight32) + ba,pt %xcc, __sw_hweight32 + nop + nop +ENDPROC(__arch_hweight32) + .section .popc_3insn_patch, "ax" + .word __arch_hweight32 + sllx %o0, 64-32, %g1 + retl + popc %g1, %o0 + .previous + +ENTRY(__arch_hweight64) + ba,pt %xcc, __sw_hweight64 + nop + nop +ENDPROC(__arch_hweight64) + .section .popc_3insn_patch, "ax" + .word __arch_hweight64 + retl + popc %o0, %o0 + nop + .previous diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3fd8e18..581531d 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1597,6 +1597,44 @@ static void __init tsb_phys_patch(void) static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; +static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) +{ + pa >>= KTSB_PHYS_SHIFT; + + while (start < end) { + unsigned int *ia = (unsigned int *)(unsigned long)*start; + + ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); + __asm__ __volatile__("flush %0" : : "r" (ia)); + + ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); + __asm__ __volatile__("flush %0" : : "r" (ia + 1)); + + start++; + } +} + +static void ktsb_phys_patch(void) +{ + extern unsigned int __swapper_tsb_phys_patch; + extern unsigned int __swapper_tsb_phys_patch_end; + unsigned long ktsb_pa; + + ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); + patch_one_ktsb_phys(&__swapper_tsb_phys_patch, + &__swapper_tsb_phys_patch_end, ktsb_pa); +#ifndef CONFIG_DEBUG_PAGEALLOC + { + extern unsigned int __swapper_4m_tsb_phys_patch; + extern unsigned int __swapper_4m_tsb_phys_patch_end; + ktsb_pa = (kern_base + + ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); + patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, + &__swapper_4m_tsb_phys_patch_end, ktsb_pa); + } +#endif +} + static void __init sun4v_ktsb_init(void) { unsigned long ktsb_pa; @@ -1716,8 +1754,10 @@ void __init paging_init(void) sun4u_pgprot_init(); if (tlb_type == cheetah_plus || - tlb_type == hypervisor) + tlb_type == hypervisor) { tsb_phys_patch(); + ktsb_phys_patch(); + } if (tlb_type == hypervisor) { sun4v_patch_tlb_handlers(); diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 0249b8b..b30f71a 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -12,6 +12,7 @@ config TILE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW select SYS_HYPERVISOR + select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386 # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 849ab2f..aec60dc 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -2,3 +2,41 @@ include include/asm-generic/Kbuild.asm header-y += ucontext.h header-y += hardwall.h + +generic-y += bug.h +generic-y += bugs.h +generic-y += cputime.h +generic-y += device.h +generic-y += div64.h +generic-y += emergency-restart.h +generic-y += errno.h +generic-y += fb.h +generic-y += fcntl.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipc.h +generic-y += ipcbuf.h +generic-y += irq_regs.h +generic-y += kdebug.h +generic-y += local.h +generic-y += module.h +generic-y += msgbuf.h +generic-y += mutex.h +generic-y += param.h +generic-y += parport.h +generic-y += poll.h +generic-y += posix_types.h +generic-y += resource.h +generic-y += scatterlist.h +generic-y += sembuf.h +generic-y += serial.h +generic-y += shmbuf.h +generic-y += shmparam.h +generic-y += socket.h +generic-y += sockios.h +generic-y += statfs.h +generic-y += termbits.h +generic-y += termios.h +generic-y += types.h +generic-y += ucontext.h +generic-y += xor.h diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index 739cfe0..921dbeb 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h @@ -121,15 +121,6 @@ static inline int atomic_read(const atomic_t *v) */ #define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0) -/** - * atomic_inc_not_zero - increment unless the number is zero - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1, so long as @v is non-zero. - * Returns non-zero if @v was non-zero, and zero otherwise. - */ -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - /* Nonexistent functions intended to cause link errors. */ extern unsigned long __xchg_called_with_bad_pointer(void); extern unsigned long __cmpxchg_called_with_bad_pointer(void); @@ -186,9 +177,4 @@ extern unsigned long __cmpxchg_called_with_bad_pointer(void); #include <asm/atomic_64.h> #endif -/* Provide the appropriate atomic_long_t definitions. */ -#ifndef __ASSEMBLY__ -#include <asm-generic/atomic-long.h> -#endif - #endif /* _ASM_TILE_ATOMIC_H */ diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index 92a8bee..c03349e0 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h @@ -11,7 +11,7 @@ * NON INFRINGEMENT. See the GNU General Public License for * more details. * - * Do not include directly; use <asm/atomic.h>. + * Do not include directly; use <linux/atomic.h>. */ #ifndef _ASM_TILE_ATOMIC_32_H @@ -21,7 +21,7 @@ #ifndef __ASSEMBLY__ -/* Tile-specific routines to support <asm/atomic.h>. */ +/* Tile-specific routines to support <linux/atomic.h>. */ int _atomic_xchg(atomic_t *v, int n); int _atomic_xchg_add(atomic_t *v, int i); int _atomic_xchg_add_unless(atomic_t *v, int a, int u); @@ -81,18 +81,18 @@ static inline int atomic_add_return(int i, atomic_t *v) } /** - * atomic_add_unless - add unless the number is already a given value + * __atomic_add_unless - add unless the number is already a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as @v was not already @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { smp_mb(); /* barrier for proper semantics */ - return _atomic_xchg_add_unless(v, a, u) != u; + return _atomic_xchg_add_unless(v, a, u); } /** @@ -199,7 +199,7 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as @v was not already @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) { diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h index 1c1e60d..27fe667 100644 --- a/arch/tile/include/asm/atomic_64.h +++ b/arch/tile/include/asm/atomic_64.h @@ -11,7 +11,7 @@ * NON INFRINGEMENT. See the GNU General Public License for * more details. * - * Do not include directly; use <asm/atomic.h>. + * Do not include directly; use <linux/atomic.h>. */ #ifndef _ASM_TILE_ATOMIC_64_H @@ -64,7 +64,7 @@ static inline int atomic_add_return(int i, atomic_t *v) return val; } -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int guess, oldval = v->counter; do { @@ -73,7 +73,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) guess = oldval; oldval = atomic_cmpxchg(v, guess, guess + a); } while (guess != oldval); - return oldval != u; + return oldval; } /* Now the true 64-bit operations. */ diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h index d31ab90..571b118 100644 --- a/arch/tile/include/asm/bitops_32.h +++ b/arch/tile/include/asm/bitops_32.h @@ -16,7 +16,7 @@ #define _ASM_TILE_BITOPS_32_H #include <linux/compiler.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> /* Tile-specific routines to support <asm/bitops.h>. */ diff --git a/arch/tile/include/asm/bitops_64.h b/arch/tile/include/asm/bitops_64.h index 99615e8..e9c8e38 100644 --- a/arch/tile/include/asm/bitops_64.h +++ b/arch/tile/include/asm/bitops_64.h @@ -16,7 +16,7 @@ #define _ASM_TILE_BITOPS_64_H #include <linux/compiler.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> /* See <asm/bitops.h> for API comments. */ @@ -97,9 +97,6 @@ static inline int test_and_change_bit(unsigned nr, return (oldval & mask) != 0; } -#define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit((nr), (unsigned long *)(addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit((nr), (unsigned long *)(addr)) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* _ASM_TILE_BITOPS_64_H */ diff --git a/arch/tile/include/asm/bug.h b/arch/tile/include/asm/bug.h deleted file mode 100644 index b12fd89..0000000 --- a/arch/tile/include/asm/bug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bug.h> diff --git a/arch/tile/include/asm/bugs.h b/arch/tile/include/asm/bugs.h deleted file mode 100644 index 61791e1..0000000 --- a/arch/tile/include/asm/bugs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/bugs.h> diff --git a/arch/tile/include/asm/cputime.h b/arch/tile/include/asm/cputime.h deleted file mode 100644 index 6d68ad7..0000000 --- a/arch/tile/include/asm/cputime.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/cputime.h> diff --git a/arch/tile/include/asm/device.h b/arch/tile/include/asm/device.h deleted file mode 100644 index f0a4c25..0000000 --- a/arch/tile/include/asm/device.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/device.h> diff --git a/arch/tile/include/asm/div64.h b/arch/tile/include/asm/div64.h deleted file mode 100644 index 6cd978c..0000000 --- a/arch/tile/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/div64.h> diff --git a/arch/tile/include/asm/emergency-restart.h b/arch/tile/include/asm/emergency-restart.h deleted file mode 100644 index 3711bd9..0000000 --- a/arch/tile/include/asm/emergency-restart.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/emergency-restart.h> diff --git a/arch/tile/include/asm/errno.h b/arch/tile/include/asm/errno.h deleted file mode 100644 index 4c82b50..0000000 --- a/arch/tile/include/asm/errno.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/errno.h> diff --git a/arch/tile/include/asm/fb.h b/arch/tile/include/asm/fb.h deleted file mode 100644 index 3a4988e..0000000 --- a/arch/tile/include/asm/fb.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/fb.h> diff --git a/arch/tile/include/asm/fcntl.h b/arch/tile/include/asm/fcntl.h deleted file mode 100644 index 46ab12d..0000000 --- a/arch/tile/include/asm/fcntl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/fcntl.h> diff --git a/arch/tile/include/asm/fixmap.h b/arch/tile/include/asm/fixmap.h index 51537ff..c66f793 100644 --- a/arch/tile/include/asm/fixmap.h +++ b/arch/tile/include/asm/fixmap.h @@ -75,12 +75,6 @@ extern void __set_fixmap(enum fixed_addresses idx, #define set_fixmap(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL) -/* - * Some hardware wants to get fixmapped without caching. - */ -#define set_fixmap_nocache(idx, phys) \ - __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) - #define clear_fixmap(idx) \ __set_fixmap(idx, 0, __pgprot(0)) diff --git a/arch/tile/include/asm/ioctl.h b/arch/tile/include/asm/ioctl.h deleted file mode 100644 index b279fe0..0000000 --- a/arch/tile/include/asm/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctl.h> diff --git a/arch/tile/include/asm/ioctls.h b/arch/tile/include/asm/ioctls.h deleted file mode 100644 index ec34c76..0000000 --- a/arch/tile/include/asm/ioctls.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ioctls.h> diff --git a/arch/tile/include/asm/ipc.h b/arch/tile/include/asm/ipc.h deleted file mode 100644 index a46e3d9..0000000 --- a/arch/tile/include/asm/ipc.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipc.h> diff --git a/arch/tile/include/asm/ipcbuf.h b/arch/tile/include/asm/ipcbuf.h deleted file mode 100644 index 84c7e51..0000000 --- a/arch/tile/include/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipcbuf.h> diff --git a/arch/tile/include/asm/irq_regs.h b/arch/tile/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b..0000000 --- a/arch/tile/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/tile/include/asm/kdebug.h b/arch/tile/include/asm/kdebug.h deleted file mode 100644 index 6ece1b0..0000000 --- a/arch/tile/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kdebug.h> diff --git a/arch/tile/include/asm/local.h b/arch/tile/include/asm/local.h deleted file mode 100644 index c11c530..0000000 --- a/arch/tile/include/asm/local.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local.h> diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h deleted file mode 100644 index 1e4b79f..0000000 --- a/arch/tile/include/asm/module.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/module.h> diff --git a/arch/tile/include/asm/msgbuf.h b/arch/tile/include/asm/msgbuf.h deleted file mode 100644 index 809134c..0000000 --- a/arch/tile/include/asm/msgbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/msgbuf.h> diff --git a/arch/tile/include/asm/mutex.h b/arch/tile/include/asm/mutex.h deleted file mode 100644 index ff6101a..0000000 --- a/arch/tile/include/asm/mutex.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/mutex-dec.h> diff --git a/arch/tile/include/asm/param.h b/arch/tile/include/asm/param.h deleted file mode 100644 index 965d454..0000000 --- a/arch/tile/include/asm/param.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/param.h> diff --git a/arch/tile/include/asm/parport.h b/arch/tile/include/asm/parport.h deleted file mode 100644 index cf252af..0000000 --- a/arch/tile/include/asm/parport.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/parport.h> diff --git a/arch/tile/include/asm/poll.h b/arch/tile/include/asm/poll.h deleted file mode 100644 index c98509d..0000000 --- a/arch/tile/include/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/poll.h> diff --git a/arch/tile/include/asm/posix_types.h b/arch/tile/include/asm/posix_types.h deleted file mode 100644 index 22cae62..0000000 --- a/arch/tile/include/asm/posix_types.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/posix_types.h> diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index 6be2246..c6cddd7 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h @@ -112,8 +112,6 @@ struct pt_regs *get_pt_regs(struct pt_regs *); /* Trace the current syscall. */ extern void do_syscall_trace(void); -extern void show_regs(struct pt_regs *); - #define arch_has_single_step() (1) /* diff --git a/arch/tile/include/asm/resource.h b/arch/tile/include/asm/resource.h deleted file mode 100644 index 04bc4db..0000000 --- a/arch/tile/include/asm/resource.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/resource.h> diff --git a/arch/tile/include/asm/scatterlist.h b/arch/tile/include/asm/scatterlist.h deleted file mode 100644 index 35d786f..0000000 --- a/arch/tile/include/asm/scatterlist.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/scatterlist.h> diff --git a/arch/tile/include/asm/sembuf.h b/arch/tile/include/asm/sembuf.h deleted file mode 100644 index 7673b83..0000000 --- a/arch/tile/include/asm/sembuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sembuf.h> diff --git a/arch/tile/include/asm/serial.h b/arch/tile/include/asm/serial.h deleted file mode 100644 index a0cb0caf..0000000 --- a/arch/tile/include/asm/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/serial.h> diff --git a/arch/tile/include/asm/shmbuf.h b/arch/tile/include/asm/shmbuf.h deleted file mode 100644 index 83c05fc..0000000 --- a/arch/tile/include/asm/shmbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/shmbuf.h> diff --git a/arch/tile/include/asm/shmparam.h b/arch/tile/include/asm/shmparam.h deleted file mode 100644 index 93f30de..0000000 --- a/arch/tile/include/asm/shmparam.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/shmparam.h> diff --git a/arch/tile/include/asm/socket.h b/arch/tile/include/asm/socket.h deleted file mode 100644 index 6b71384..0000000 --- a/arch/tile/include/asm/socket.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/socket.h> diff --git a/arch/tile/include/asm/sockios.h b/arch/tile/include/asm/sockios.h deleted file mode 100644 index def6d47..0000000 --- a/arch/tile/include/asm/sockios.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/sockios.h> diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index a8f2c6e..a5e4208 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h @@ -17,7 +17,7 @@ #ifndef _ASM_TILE_SPINLOCK_32_H #define _ASM_TILE_SPINLOCK_32_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/page.h> #include <asm/system.h> #include <linux/compiler.h> diff --git a/arch/tile/include/asm/statfs.h b/arch/tile/include/asm/statfs.h deleted file mode 100644 index 0b91fe1..0000000 --- a/arch/tile/include/asm/statfs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/statfs.h> diff --git a/arch/tile/include/asm/termbits.h b/arch/tile/include/asm/termbits.h deleted file mode 100644 index 3935b10..0000000 --- a/arch/tile/include/asm/termbits.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termbits.h> diff --git a/arch/tile/include/asm/termios.h b/arch/tile/include/asm/termios.h deleted file mode 100644 index 280d78a..0000000 --- a/arch/tile/include/asm/termios.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/termios.h> diff --git a/arch/tile/include/asm/types.h b/arch/tile/include/asm/types.h deleted file mode 100644 index b9e79bc..0000000 --- a/arch/tile/include/asm/types.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/types.h> diff --git a/arch/tile/include/asm/ucontext.h b/arch/tile/include/asm/ucontext.h deleted file mode 100644 index 9bc07b9..0000000 --- a/arch/tile/include/asm/ucontext.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ucontext.h> diff --git a/arch/tile/include/asm/xor.h b/arch/tile/include/asm/xor.h deleted file mode 100644 index c82eb12..0000000 --- a/arch/tile/include/asm/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/xor.h> diff --git a/arch/tile/include/hv/drv_srom_intf.h b/arch/tile/include/hv/drv_srom_intf.h new file mode 100644 index 0000000..6395faa --- /dev/null +++ b/arch/tile/include/hv/drv_srom_intf.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011 Tilera Corporation. All Rights Reserved. + * + * 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, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +/** + * @file drv_srom_intf.h + * Interface definitions for the SPI Flash ROM driver. + */ + +#ifndef _SYS_HV_INCLUDE_DRV_SROM_INTF_H +#define _SYS_HV_INCLUDE_DRV_SROM_INTF_H + +/** Read this offset to get the total device size. */ +#define SROM_TOTAL_SIZE_OFF 0xF0000000 + +/** Read this offset to get the device sector size. */ +#define SROM_SECTOR_SIZE_OFF 0xF0000004 + +/** Read this offset to get the device page size. */ +#define SROM_PAGE_SIZE_OFF 0xF0000008 + +/** Write this offset to flush any pending writes. */ +#define SROM_FLUSH_OFF 0xF1000000 + +/** Write this offset, plus the byte offset of the start of a sector, to + * erase a sector. Any write data is ignored, but there must be at least + * one byte of write data. Only applies when the driver is in MTD mode. + */ +#define SROM_ERASE_OFF 0xF2000000 + +#endif /* _SYS_HV_INCLUDE_DRV_SROM_INTF_H */ diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 72ade79..fc94607 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -21,7 +21,7 @@ #include <asm/ptrace.h> #include <asm/thread_info.h> #include <asm/irqflags.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/asm-offsets.h> #include <hv/hypervisor.h> #include <arch/abi.h> diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 6d4cb5d..2a8014c 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -228,7 +228,7 @@ err_cont: * (pin - 1) converts from the PCI standard's [1:4] convention to * a normal [0:3] range. */ -static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int tile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *controller = (struct pci_controller *)dev->sysdata; diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index c4be58c..f6f50f2a 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -78,7 +78,6 @@ static struct clocksource cycle_counter_cs = { .rating = 300, .read = clocksource_get_cycles, .mask = CLOCKSOURCE_MASK(64), - .shift = 22, /* typical value, e.g. x86 tsc uses this */ .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -91,8 +90,6 @@ void __init setup_clock(void) cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED); sched_clock_mult = clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT); - cycle_counter_cs.mult = - clocksource_hz2mult(cycles_per_sec, cycle_counter_cs.shift); } void __init calibrate_delay(void) @@ -107,7 +104,7 @@ void __init calibrate_delay(void) void __init time_init(void) { /* Initialize and register the clock source. */ - clocksource_register(&cycle_counter_cs); + clocksource_register_hz(&cycle_counter_cs, cycles_per_sec); /* Start up the tile-timer interrupt source on the boot cpu. */ setup_tile_timer(); diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c index 4657021..771b251 100644 --- a/arch/tile/lib/atomic_32.c +++ b/arch/tile/lib/atomic_32.c @@ -17,7 +17,7 @@ #include <linux/uaccess.h> #include <linux/module.h> #include <linux/mm.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/futex.h> #include <arch/chip.h> diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S index 2444873..1f75a2a 100644 --- a/arch/tile/lib/atomic_asm_32.S +++ b/arch/tile/lib/atomic_asm_32.S @@ -70,7 +70,7 @@ */ #include <linux/linkage.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/page.h> #include <asm/processor.h> diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 4e10c40..7309988c 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -836,8 +836,7 @@ void __init mem_init(void) #endif #ifdef CONFIG_FLATMEM - if (!mem_map) - BUG(); + BUG_ON(!mem_map); #endif #ifdef CONFIG_HIGHMEM diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 index d31ecf3..21bebe6 100644 --- a/arch/um/Kconfig.x86 +++ b/arch/um/Kconfig.x86 @@ -10,6 +10,10 @@ config CMPXCHG_LOCAL bool default n +config CMPXCHG_DOUBLE + bool + default n + source "arch/x86/Kconfig.cpu" endmenu diff --git a/arch/um/Makefile b/arch/um/Makefile index fab8121..c0f712c 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -41,7 +41,7 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ -Din6addr_loopback=kernel_in6addr_loopback \ - -Din6addr_any=kernel_in6addr_any + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr KBUILD_AFLAGS += $(ARCH_INCLUDE) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d51c404..364c8a1 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) * is done under a spinlock. Checking whether the device is in use is * line->tty->count > 1, also under the spinlock. * - * tty->count serves to decide whether the device should be enabled or - * disabled on the host. If it's equal to 1, then we are doing the + * line->count serves to decide whether the device should be enabled or + * disabled on the host. If it's equal to 0, then we are doing the * first open or last close. Otherwise, open and close just return. */ @@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty) goto out_unlock; err = 0; - if (tty->count > 1) + if (line->count++) goto out_unlock; - spin_unlock(&line->count_lock); - + BUG_ON(tty->driver_data); tty->driver_data = line; line->tty = tty; + spin_unlock(&line->count_lock); err = enable_chan(line); - if (err) + if (err) /* line_close() will be called by our caller */ return err; INIT_DELAYED_WORK(&line->task, line_timer_cb); @@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty) chan_window_size(&line->chan_list, &tty->winsize.ws_row, &tty->winsize.ws_col); - return err; + return 0; out_unlock: spin_unlock(&line->count_lock); @@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp) flush_buffer(line); spin_lock(&line->count_lock); - if (!line->valid) - goto out_unlock; + BUG_ON(!line->valid); - if (tty->count > 1) + if (--line->count) goto out_unlock; - spin_unlock(&line->count_lock); - line->tty = NULL; tty->driver_data = NULL; + spin_unlock(&line->count_lock); + if (line->sigio) { unregister_winch(tty); line->sigio = 0; @@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, spin_lock(&line->count_lock); - if (line->tty != NULL) { + if (line->count) { *error_out = "Device is already open"; goto out; } @@ -722,41 +721,53 @@ struct winch { int pid; struct tty_struct *tty; unsigned long stack; + struct work_struct work; }; -static void free_winch(struct winch *winch, int free_irq_ok) +static void __free_winch(struct work_struct *work) { - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); - - list_del(&winch->list); + struct winch *winch = container_of(work, struct winch, work); + free_irq(WINCH_IRQ, winch); if (winch->pid != -1) os_kill_process(winch->pid, 1); - if (winch->fd != -1) - os_close_file(winch->fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); } +static void free_winch(struct winch *winch) +{ + int fd = winch->fd; + winch->fd = -1; + if (fd != -1) + os_close_file(fd); + list_del(&winch->list); + __free_winch(&winch->work); +} + static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; struct tty_struct *tty; struct line *line; + int fd = winch->fd; int err; char c; - if (winch->fd != -1) { - err = generic_read(winch->fd, &c, NULL); + if (fd != -1) { + err = generic_read(fd, &c, NULL); if (err < 0) { if (err != -EAGAIN) { + winch->fd = -1; + list_del(&winch->list); + os_close_file(fd); printk(KERN_ERR "winch_interrupt : " "read failed, errno = %d\n", -err); printk(KERN_ERR "fd %d is losing SIGWINCH " "support\n", winch->tty_fd); - free_winch(winch, 0); + INIT_WORK(&winch->work, __free_winch); + schedule_work(&winch->work); return IRQ_HANDLED; } goto out; @@ -828,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); if (winch->tty == tty) { - free_winch(winch, 1); + free_winch(winch); break; } } @@ -844,7 +855,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - free_winch(winch, 1); + free_winch(winch); } spin_unlock(&winch_handler_lock); diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 8ac7146..2e1de57 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d, err = -errno; printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", errno); + close(fd); return err; } close(fd); diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index b7c5bab..1a7d275 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -42,12 +42,6 @@ extern long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); -extern int get_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); -extern int set_fpregs(struct user_i387_struct __user *buf, - struct task_struct *child); - -extern void show_regs(struct pt_regs *regs); extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h index 72f4f25..63df3ca 100644 --- a/arch/um/include/shared/line.h +++ b/arch/um/include/shared/line.h @@ -33,6 +33,7 @@ struct line_driver { struct line { struct tty_struct *tty; spinlock_t count_lock; + unsigned long count; int valid; char *init_str; diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index b0b4589..f1e0aa5 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); extern int restore_registers(int pid, struct uml_pt_regs *regs); extern int init_registers(int pid); -extern void get_safe_registers(unsigned long *regs); +extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); extern int put_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fab4371..21c1ae7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, arch_copy_thread(¤t->thread.arch, &p->thread.arch); } else { - get_safe_registers(p->thread.regs.regs.gp); + get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 701b672..c9da32b 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -50,23 +50,11 @@ long arch_ptrace(struct task_struct *child, long request, void __user *vp = p; switch (request) { - /* read word at location addr. */ - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: ret = peek_user(child, addr, data); break; - /* write the word at location addr. */ - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: ret = poke_user(child, addr, data); @@ -107,16 +95,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_GETFPREGS - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(vp, child); - break; -#endif -#ifdef PTRACE_SETFPREGS - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(vp, child); - break; -#endif case PTRACE_GET_THREAD_AREA: ret = ptrace_get_thread_area(child, addr, vp); break; @@ -154,12 +132,6 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif -#ifdef PTRACE_ARCH_PRCTL - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; -#endif default: ret = ptrace_request(child, request, addr, data); if (ret == -EIO) diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index 830fe6a..b866b9e 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c @@ -8,6 +8,8 @@ #include <string.h> #include <sys/ptrace.h> #include "sysdep/ptrace.h" +#include "sysdep/ptrace_user.h" +#include "registers.h" int save_registers(int pid, struct uml_pt_regs *regs) { @@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) /* This is set once at boot time and not changed thereafter */ static unsigned long exec_regs[MAX_REG_NR]; +static unsigned long exec_fp_regs[FP_SIZE]; int init_registers(int pid) { @@ -42,10 +45,14 @@ int init_registers(int pid) return -errno; arch_init_registers(pid); + get_fp_registers(pid, exec_fp_regs); return 0; } -void get_safe_registers(unsigned long *regs) +void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { memcpy(regs, exec_regs, sizeof(exec_regs)); + + if (fp_regs) + memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); } diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index d261f17..e771398 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { - get_safe_registers(syscall_regs); + get_safe_registers(syscall_regs, NULL); syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6e0a22..dee0e8c 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs) if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) fatal_sigsegv(); + if (put_fp_registers(pid, regs->fp)) + fatal_sigsegv(); + /* Now we set local_using_sysemu to be used for one loop */ local_using_sysemu = get_using_sysemu(); @@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs) fatal_sigsegv(); } + if (get_fp_registers(pid, regs->fp)) { + printk(UM_KERN_ERR "userspace - get_fp_registers failed, " + "errno = %d\n", errno); + fatal_sigsegv(); + } + UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if (WIFSTOPPED(status)) { @@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs) } static unsigned long thread_regs[MAX_REG_NR]; +static unsigned long thread_fp_regs[FP_SIZE]; static int __init init_thread_regs(void) { - get_safe_registers(thread_regs); + get_safe_registers(thread_regs, thread_fp_regs); /* Set parent's instruction pointer to start of clone-stub */ thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - @@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid) return err; } + err = put_fp_registers(pid, thread_fp_regs); + if (err < 0) { + printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " + "failed, pid = %d, err = %d\n", pid, err); + return err; + } + /* set a well known return code for detection of child write failure */ child_data->err = 12345678; diff --git a/arch/um/sys-i386/asm/ptrace.h b/arch/um/sys-i386/asm/ptrace.h index 0273e4d..5d2a591 100644 --- a/arch/um/sys-i386/asm/ptrace.h +++ b/arch/um/sys-i386/asm/ptrace.h @@ -42,11 +42,6 @@ */ struct user_desc; -extern int get_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *child); -extern int set_fpxregs(struct user_fxsr_struct __user *buf, - struct task_struct *tsk); - extern int ptrace_get_thread_area(struct task_struct *child, int idx, struct user_desc __user *user_desc); diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index d23b2d3..3375c27 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -145,7 +145,7 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long __user *) data); } -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -161,7 +161,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) return n; } -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -174,7 +174,7 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) (unsigned long *) &fpregs); } -int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -190,7 +190,7 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) return n; } -int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -206,5 +206,23 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { - return -EIO; + int ret = -EIO; + void __user *datap = (void __user *) data; + switch (request) { + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(datap, child); + break; + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(datap, child); + break; + case PTRACE_GETFPXREGS: /* Get the child FPU state. */ + ret = get_fpxregs(datap, child); + break; + case PTRACE_SETFPXREGS: /* Set the child FPU state. */ + ret = set_fpxregs(datap, child); + break; + default: + ret = -EIO; + } + return ret; } diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index d50e62e..c398a50 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -53,6 +53,7 @@ extern int sysemu_supported; struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FPX_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index f436136..4005506 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -145,7 +145,7 @@ int is_syscall(unsigned long addr) return instr == 0x050f; } -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -162,7 +162,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) return n; } -int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -182,12 +182,16 @@ long subarch_ptrace(struct task_struct *child, long request, void __user *datap = (void __user *) data; switch (request) { - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ + case PTRACE_GETFPREGS: /* Get the child FPU state. */ ret = get_fpregs(datap, child); break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ + case PTRACE_SETFPREGS: /* Set the child FPU state. */ ret = set_fpregs(datap, child); break; + case PTRACE_ARCH_PRCTL: + /* XXX Calls ptrace on the host - needs some SMP thinking */ + ret = arch_prctl(child, data, (void __user *) addr); + break; } return ret; diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h index fdba545..8ee8f8e 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -85,6 +85,7 @@ struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; + unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 100eab8..4892fbb 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -102,7 +102,7 @@ void pci_puv3_preinit(void) writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); } -static int __init pci_puv3_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->bus->number == 0) { #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 78fe57d..6a47bb2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -72,6 +72,7 @@ config X86 select USE_GENERIC_SMP_HELPERS if SMP select HAVE_BPF_JIT if (X86_64 && NET) select CLKEVT_I8253 + select ARCH_HAVE_NMI_SAFE_CMPXCHG config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) @@ -1905,7 +1906,7 @@ config PCI_BIOS # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT def_bool y - depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC)) + depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG)) config PCI_MMCONFIG def_bool y @@ -2024,11 +2025,44 @@ config OLPC Add support for detecting the unique features of the OLPC XO hardware. -config OLPC_XO1 - tristate "OLPC XO-1 support" - depends on OLPC && MFD_CS5535 - ---help--- - Add support for non-essential features of the OLPC XO-1 laptop. +config OLPC_XO1_PM + bool "OLPC XO-1 Power Management" + depends on OLPC && MFD_CS5535 && PM_SLEEP + select MFD_CORE + ---help--- + Add support for poweroff and suspend of the OLPC XO-1 laptop. + +config OLPC_XO1_RTC + bool "OLPC XO-1 Real Time Clock" + depends on OLPC_XO1_PM && RTC_DRV_CMOS + ---help--- + Add support for the XO-1 real time clock, which can be used as a + programmable wakeup source. + +config OLPC_XO1_SCI + bool "OLPC XO-1 SCI extras" + depends on OLPC && OLPC_XO1_PM + select POWER_SUPPLY + select GPIO_CS5535 + select MFD_CORE + ---help--- + Add support for SCI-based features of the OLPC XO-1 laptop: + - EC-driven system wakeups + - Power button + - Ebook switch + - Lid switch + - AC adapter status updates + - Battery status updates + +config OLPC_XO15_SCI + bool "OLPC XO-1.5 SCI extras" + depends on OLPC && ACPI + select POWER_SUPPLY + ---help--- + Add support for SCI-based features of the OLPC XO-1.5 laptop: + - EC-driven system wakeups + - AC adapter status updates + - Battery status updates endif # X86_32 diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index a0e866d..54edb207 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -672,7 +672,7 @@ ia32_sys_call_table: .quad sys32_vm86_warning /* vm86 */ .quad quiet_ni_syscall /* query_module */ .quad sys_poll - .quad compat_sys_nfsservctl + .quad quiet_ni_syscall /* old nfsservctl */ .quad sys_setresgid16 /* 170 */ .quad sys_getresgid16 .quad sys_prctl diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 5852519..f6f5c53 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -43,7 +43,7 @@ #include <asm/mman.h> #include <asm/types.h> #include <asm/uaccess.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/vgtod.h> #include <asm/sys_ia32.h> diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 4a0b7c7..7b3ca83 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -8,7 +8,7 @@ #include <asm/cpufeature.h> #include <asm/processor.h> #include <asm/apicdef.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/fixmap.h> #include <asm/mpspec.h> #include <asm/system.h> diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 952a826..10572e3 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -221,15 +221,15 @@ static inline int atomic_xchg(atomic_t *v, int new) } /** - * atomic_add_unless - add unless the number is already a given value + * __atomic_add_unless - add unless the number is already a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as @v was not already @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -241,10 +241,9 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) /* * atomic_dec_if_positive - decrement by 1 if old value positive @@ -319,5 +318,4 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2) # include "atomic64_64.h" #endif -#include <asm-generic/atomic-long.h> #endif /* _ASM_X86_ATOMIC_H */ diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index 2a934aa..24098aa 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -263,7 +263,7 @@ static inline int atomic64_add_negative(long long i, atomic64_t *v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) { diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 49fd1ea..017594d 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -202,7 +202,7 @@ static inline long atomic64_xchg(atomic64_t *v, long new) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static inline int atomic64_add_unless(atomic64_t *v, long a, long u) { diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 69d5813..1775d6e 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -458,10 +458,7 @@ static inline int fls(int x) #include <asm-generic/bitops/le.h> -#define ext2_set_bit_atomic(lock, nr, addr) \ - test_and_set_bit((nr), (unsigned long *)(addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) \ - test_and_clear_bit((nr), (unsigned long *)(addr)) +#include <asm-generic/bitops/ext2-atomic-setbit.h> #endif /* __KERNEL__ */ #endif /* _ASM_X86_BITOPS_H */ diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 7b439d9..41935fa 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -27,8 +27,8 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in desc->base2 = (info->base_addr & 0xff000000) >> 24; /* - * Don't allow setting of the lm bit. It is useless anyway - * because 64bit system calls require __USER_CS: + * Don't allow setting of the lm bit. It would confuse + * user_64bit_mode and would get overridden by sysret anyway. */ desc->l = 0; } diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 13f5504..0919905 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -21,7 +21,7 @@ #include <linux/profile.h> #include <linux/smp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/irq.h> #include <asm/sections.h> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index d02804d..d8e8eef 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -40,8 +40,6 @@ #include <linux/compiler.h> #include <asm/page.h> -#include <xen/xen.h> - #define build_mmio_read(name, size, type, reg, barrier) \ static inline type name(const volatile void __iomem *addr) \ { type ret; asm volatile("mov" size " %1,%0":reg (ret) \ @@ -334,6 +332,7 @@ extern void fixup_early_ioremap(void); extern bool is_early_ioremap_ptep(pte_t *ptep); #ifdef CONFIG_XEN +#include <xen/xen.h> struct bio_vec; extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index f9a3209..7e50f06 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -17,7 +17,6 @@ * Vectors 0 ... 31 : system traps and exceptions - hardcoded events * Vectors 32 ... 127 : device interrupts * Vector 128 : legacy int80 syscall interface - * Vector 204 : legacy x86_64 vsyscall emulation * Vectors 129 ... INVALIDATE_TLB_VECTOR_START-1 except 204 : device interrupts * Vectors INVALIDATE_TLB_VECTOR_START ... 255 : special interrupts * @@ -51,9 +50,6 @@ #ifdef CONFIG_X86_32 # define SYSCALL_VECTOR 0x80 #endif -#ifdef CONFIG_X86_64 -# define VSYSCALL_EMU_VECTOR 0xcc -#endif /* * Vectors 0x30-0x3f are used for ISA interrupts. diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h index fe2cc6e..d73f157 100644 --- a/arch/x86/include/asm/kdebug.h +++ b/arch/x86/include/asm/kdebug.h @@ -28,7 +28,6 @@ extern void show_registers(struct pt_regs *regs); extern void show_trace(struct task_struct *t, struct pt_regs *regs, unsigned long *sp, unsigned long bp); extern void __show_regs(struct pt_regs *regs, int all); -extern void show_regs(struct pt_regs *regs); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); #ifdef CONFIG_KEXEC diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h index 2e99724..9cdae5d 100644 --- a/arch/x86/include/asm/local.h +++ b/arch/x86/include/asm/local.h @@ -4,7 +4,7 @@ #include <linux/percpu.h> #include <asm/system.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/asm.h> typedef struct { diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 716b48a..c9321f3 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -124,7 +124,7 @@ extern struct atomic_notifier_head x86_mce_decoder_chain; #include <linux/percpu.h> #include <linux/init.h> -#include <asm/atomic.h> +#include <linux/atomic.h> extern int mce_disabled; extern int mce_p5_enabled; diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 8b5393e..6902152 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -2,7 +2,7 @@ #define _ASM_X86_MMU_CONTEXT_H #include <asm/desc.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/pgalloc.h> #include <asm/tlbflush.h> #include <asm/paravirt.h> diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h index 5ca6801..87bdbca 100644 --- a/arch/x86/include/asm/olpc.h +++ b/arch/x86/include/asm/olpc.h @@ -13,6 +13,7 @@ struct olpc_platform_t { #define OLPC_F_PRESENT 0x01 #define OLPC_F_DCON 0x02 +#define OLPC_F_EC_WIDE_SCI 0x04 #ifdef CONFIG_OLPC @@ -62,6 +63,13 @@ static inline int olpc_board_at_least(uint32_t rev) return olpc_platform_info.boardrev >= rev; } +extern void olpc_ec_wakeup_set(u16 value); +extern void olpc_ec_wakeup_clear(u16 value); +extern bool olpc_ec_wakeup_available(void); + +extern int olpc_ec_mask_write(u16 bits); +extern int olpc_ec_sci_query(u16 *sci_value); + #else static inline int machine_is_olpc(void) @@ -74,6 +82,20 @@ static inline int olpc_has_dcon(void) return 0; } +static inline void olpc_ec_wakeup_set(u16 value) { } +static inline void olpc_ec_wakeup_clear(u16 value) { } + +static inline bool olpc_ec_wakeup_available(void) +{ + return false; +} + +#endif + +#ifdef CONFIG_OLPC_XO1_PM +extern void do_olpc_suspend_lowlevel(void); +extern void olpc_xo1_pm_wakeup_set(u16 value); +extern void olpc_xo1_pm_wakeup_clear(u16 value); #endif extern int pci_olpc_init(void); @@ -83,14 +105,19 @@ extern int pci_olpc_init(void); extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, unsigned char *outbuf, size_t outlen); -extern int olpc_ec_mask_set(uint8_t bits); -extern int olpc_ec_mask_unset(uint8_t bits); - /* EC commands */ -#define EC_FIRMWARE_REV 0x08 -#define EC_WLAN_ENTER_RESET 0x35 -#define EC_WLAN_LEAVE_RESET 0x25 +#define EC_FIRMWARE_REV 0x08 +#define EC_WRITE_SCI_MASK 0x1b +#define EC_WAKE_UP_WLAN 0x24 +#define EC_WLAN_LEAVE_RESET 0x25 +#define EC_READ_EB_MODE 0x2a +#define EC_SET_SCI_INHIBIT 0x32 +#define EC_SET_SCI_INHIBIT_RELEASE 0x34 +#define EC_WLAN_ENTER_RESET 0x35 +#define EC_WRITE_EXT_SCI_MASK 0x38 +#define EC_SCI_QUERY 0x84 +#define EC_EXT_SCI_QUERY 0x85 /* SCI source values */ @@ -99,10 +126,12 @@ extern int olpc_ec_mask_unset(uint8_t bits); #define EC_SCI_SRC_BATTERY 0x02 #define EC_SCI_SRC_BATSOC 0x04 #define EC_SCI_SRC_BATERR 0x08 -#define EC_SCI_SRC_EBOOK 0x10 -#define EC_SCI_SRC_WLAN 0x20 +#define EC_SCI_SRC_EBOOK 0x10 /* XO-1 only */ +#define EC_SCI_SRC_WLAN 0x20 /* XO-1 only */ #define EC_SCI_SRC_ACPWR 0x40 -#define EC_SCI_SRC_ALL 0x7F +#define EC_SCI_SRC_BATCRIT 0x80 +#define EC_SCI_SRC_GPWAKE 0x100 /* XO-1.5 only */ +#define EC_SCI_SRC_ALL 0x1FF /* GPIO assignments */ @@ -116,7 +145,7 @@ extern int olpc_ec_mask_unset(uint8_t bits); #define OLPC_GPIO_SMB_CLK 14 #define OLPC_GPIO_SMB_DATA 15 #define OLPC_GPIO_WORKAUX geode_gpio(24) -#define OLPC_GPIO_LID geode_gpio(26) -#define OLPC_GPIO_ECSCI geode_gpio(27) +#define OLPC_GPIO_LID 26 +#define OLPC_GPIO_ECSCI 27 #endif /* _ASM_X86_OLPC_H */ diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 2c76521..8e8b9a4 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -41,6 +41,7 @@ #include <asm/desc_defs.h> #include <asm/kmap_types.h> +#include <asm/pgtable_types.h> struct page; struct thread_struct; @@ -63,6 +64,11 @@ struct paravirt_callee_save { struct pv_info { unsigned int kernel_rpl; int shared_kernel_pmd; + +#ifdef CONFIG_X86_64 + u16 extra_user_64bit_cs; /* __USER_CS if none */ +#endif + int paravirt_enabled; const char *name; }; diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 2193715..0d1171c 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -751,8 +751,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) :: "a" (eax), "c" (ecx)); } -extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); - extern void select_idle_routine(const struct cpuinfo_x86 *c); extern void init_amd_e400_c1e_mask(void); diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index df12870..644dd885 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h @@ -19,7 +19,7 @@ #include <linux/pci.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/setup.h> #include <asm/irq_controller.h> diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 94e7618..3566454 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -131,6 +131,9 @@ struct pt_regs { #ifdef __KERNEL__ #include <linux/init.h> +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt_types.h> +#endif struct cpuinfo_x86; struct task_struct; @@ -187,6 +190,22 @@ static inline int v8086_mode(struct pt_regs *regs) #endif } +#ifdef CONFIG_X86_64 +static inline bool user_64bit_mode(struct pt_regs *regs) +{ +#ifndef CONFIG_PARAVIRT + /* + * On non-paravirt systems, this is the only long mode CPL 3 + * selector. We do not allow long mode selectors in the LDT. + */ + return regs->cs == __USER_CS; +#else + /* Headers are too twisted for this to go in paravirt.h. */ + return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; +#endif +} +#endif + /* * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode * when it traps. The previous stack will be directly underneath the saved diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index a518c0a..c59cc97 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -44,7 +44,7 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); #elif defined(__x86_64__) __asm__ ( - "mul %[mul_frac] ; shrd $32, %[hi], %[lo]" + "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]" : [lo]"=a"(product), [hi]"=d"(tmp) : "0"(delta), diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index e9e51f7..ee67edf 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -1,7 +1,7 @@ #ifndef _ASM_X86_SPINLOCK_H #define _ASM_X86_SPINLOCK_H -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/page.h> #include <asm/processor.h> #include <linux/compiler.h> diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 1f2e61e..a1fe5c1 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -21,7 +21,7 @@ struct task_struct; struct exec_domain; #include <asm/processor.h> #include <asm/ftrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h> struct thread_info { struct task_struct *task; /* main task structure */ diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 2bae0a5..0012d09 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -40,7 +40,6 @@ asmlinkage void alignment_check(void); asmlinkage void machine_check(void); #endif /* CONFIG_X86_MCE */ asmlinkage void simd_coprocessor_error(void); -asmlinkage void emulate_vsyscall(void); dotraplinkage void do_divide_error(struct pt_regs *, long); dotraplinkage void do_debug(struct pt_regs *, long); @@ -67,7 +66,6 @@ dotraplinkage void do_alignment_check(struct pt_regs *, long); dotraplinkage void do_machine_check(struct pt_regs *, long); #endif dotraplinkage void do_simd_coprocessor_error(struct pt_regs *, long); -dotraplinkage void do_emulate_vsyscall(struct pt_regs *, long); #ifdef CONFIG_X86_32 dotraplinkage void do_iret_error(struct pt_regs *, long); #endif diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 705bf13..2010405 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h @@ -414,7 +414,7 @@ __SYSCALL(__NR_query_module, sys_ni_syscall) __SYSCALL(__NR_quotactl, sys_quotactl) #define __NR_nfsservctl 180 -__SYSCALL(__NR_nfsservctl, sys_nfsservctl) +__SYSCALL(__NR_nfsservctl, sys_ni_syscall) /* reserved for LiS/STREAMS */ #define __NR_getpmsg 181 @@ -681,6 +681,8 @@ __SYSCALL(__NR_syncfs, sys_syncfs) __SYSCALL(__NR_sendmmsg, sys_sendmmsg) #define __NR_setns 308 __SYSCALL(__NR_setns, sys_setns) +#define __NR_getcpu 309 +__SYSCALL(__NR_getcpu, sys_getcpu) #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h index 6010707..eaea1d3 100644 --- a/arch/x86/include/asm/vsyscall.h +++ b/arch/x86/include/asm/vsyscall.h @@ -27,6 +27,12 @@ extern struct timezone sys_tz; extern void map_vsyscall(void); +/* + * Called on instruction fetch fault in vsyscall page. + * Returns true if handled. + */ +extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_VSYSCALL_H */ diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 64a619d..7ff4669 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -39,7 +39,7 @@ typedef struct xpaddr { ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) extern unsigned long *machine_to_phys_mapping; -extern unsigned int machine_to_phys_order; +extern unsigned long machine_to_phys_nr; extern unsigned long get_phys_to_machine(unsigned long pfn); extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); @@ -87,7 +87,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) if (xen_feature(XENFEAT_auto_translated_physmap)) return mfn; - if (unlikely((mfn >> machine_to_phys_order) != 0)) { + if (unlikely(mfn >= machine_to_phys_nr)) { pfn = ~0; goto try_override; } diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0410557..82f2912 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -17,19 +17,6 @@ CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif -# -# vsyscalls (which work on the user stack) should have -# no stack-protector checks: -# -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) -CFLAGS_hpet.o := $(nostackp) -CFLAGS_paravirt.o := $(nostackp) -GCOV_PROFILE_vsyscall_64.o := n -GCOV_PROFILE_hpet.o := n -GCOV_PROFILE_tsc.o := n -GCOV_PROFILE_paravirt.o := n - obj-y := process_$(BITS).o signal.o entry_$(BITS).o obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o ldt.o dumpstack.o diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 5812404..f50e7fb 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -149,6 +149,29 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); +/* + * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, + * which can obviate IPI to trigger checking of need_resched. + * We execute MONITOR against need_resched and enter optimized wait state + * through MWAIT. Whenever someone changes need_resched, we would be woken + * up from MWAIT (without an IPI). + * + * New with Core Duo processors, MWAIT can take some hints based on CPU + * capability. + */ +void mwait_idle_with_hints(unsigned long ax, unsigned long cx) +{ + if (!need_resched()) { + if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) + clflush((void *)¤t_thread_info()->flags); + + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) + __mwait(ax, cx); + } +} + void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) { unsigned int cpu = smp_processor_id(); diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index b117efd..8a439d3 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -30,7 +30,7 @@ #include <linux/syscore_ops.h> #include <linux/io.h> #include <linux/gfp.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mtrr.h> #include <asm/pgtable.h> #include <asm/proto.h> diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index b24be38..52fa563 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -38,7 +38,7 @@ #include <asm/perf_event.h> #include <asm/x86_init.h> #include <asm/pgalloc.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/mpspec.h> #include <asm/i8259.h> #include <asm/proto.h> diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 9536b3f..5d513bc 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -48,7 +48,7 @@ #include <linux/io.h> #include <asm/apicdef.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/fixmap.h> #include <asm/mpspec.h> #include <asm/setup.h> diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index adc66c3..34b1859 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -207,7 +207,6 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | APIC_DM_INIT; uv_write_global_mmr64(pnode, UVH_IPI_INT, val); - mdelay(10); val = (1UL << UVH_IPI_INT_SEND_SHFT) | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 22a073d..6218439 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -21,7 +21,7 @@ #include <linux/topology.h> #include <linux/cpumask.h> #include <asm/pgtable.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/proto.h> #include <asm/setup.h> #include <asm/apic.h> diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 08119a3..6b96110 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -149,7 +149,6 @@ struct set_mtrr_data { */ static int mtrr_rendezvous_handler(void *info) { -#ifdef CONFIG_SMP struct set_mtrr_data *data = info; /* @@ -171,7 +170,6 @@ static int mtrr_rendezvous_handler(void *info) } else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) { mtrr_if->set_all(); } -#endif return 0; } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4ee3abf..cfa62ec 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1900,6 +1900,9 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) perf_callchain_store(entry, regs->ip); + if (!current->mm) + return; + if (perf_callchain_user32(regs, entry)) return; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 45fbb8f..f88af2c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1590,6 +1590,7 @@ static __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ + case 45: /* SandyBridge, "Romely-EP" */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 5c1a9197..f3f6f53 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -54,6 +54,7 @@ #include <asm/ftrace.h> #include <asm/irq_vectors.h> #include <asm/cpufeature.h> +#include <asm/alternative-asm.h> /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ #include <linux/elf-em.h> @@ -873,12 +874,7 @@ ENTRY(simd_coprocessor_error) 661: pushl_cfi $do_general_protection 662: .section .altinstructions,"a" - .balign 4 - .long 661b - .long 663f - .word X86_FEATURE_XMM - .byte 662b-661b - .byte 664f-663f + altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f .previous .section .altinstr_replacement,"ax" 663: pushl $do_simd_coprocessor_error diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e13329d..6419bb0 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1111,7 +1111,6 @@ zeroentry spurious_interrupt_bug do_spurious_interrupt_bug zeroentry coprocessor_error do_coprocessor_error errorentry alignment_check do_alignment_check zeroentry simd_coprocessor_error do_simd_coprocessor_error -zeroentry emulate_vsyscall do_emulate_vsyscall /* Reload gs selector with exception handling */ diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 65b8f5c..6104852 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -14,7 +14,7 @@ #include <linux/io.h> #include <linux/delay.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/timer.h> #include <asm/hw_irq.h> diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index f09d4bb..b3300e6 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -15,7 +15,7 @@ #include <linux/io.h> #include <linux/delay.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/timer.h> #include <asm/hw_irq.h> diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 613a793..d90272e 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -307,6 +307,10 @@ struct pv_info pv_info = { .paravirt_enabled = 0, .kernel_rpl = 0, .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ + +#ifdef CONFIG_X86_64 + .extra_user_64bit_cs = __USER_CS, +#endif }; struct pv_init_ops pv_init_ops = { diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index e1ba8cb2..e7e3b01 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -438,29 +438,6 @@ void cpu_idle_wait(void) } EXPORT_SYMBOL_GPL(cpu_idle_wait); -/* - * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, - * which can obviate IPI to trigger checking of need_resched. - * We execute MONITOR against need_resched and enter optimized wait state - * through MWAIT. Whenever someone changes need_resched, we would be woken - * up from MWAIT (without an IPI). - * - * New with Core Duo processors, MWAIT can take some hints based on CPU - * capability. - */ -void mwait_idle_with_hints(unsigned long ax, unsigned long cx) -{ - if (!need_resched()) { - if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) - clflush((void *)¤t_thread_info()->flags); - - __monitor((void *)¤t_thread_info()->flags, 0, 0); - smp_mb(); - if (!need_resched()) - __mwait(ax, cx); - } -} - /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a069c0c..2196c70 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -38,6 +38,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/kdebug.h> +#include <linux/cpuidle.h> #include <asm/pgtable.h> #include <asm/system.h> @@ -109,7 +110,8 @@ void cpu_idle(void) local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); - pm_idle(); + if (cpuidle_idle_call()) + pm_idle(); start_critical_timings(); } tick_nohz_restart_sched_tick(); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ca6f7ab..f693e44 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -37,6 +37,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/ftrace.h> +#include <linux/cpuidle.h> #include <asm/pgtable.h> #include <asm/system.h> @@ -136,7 +137,8 @@ void cpu_idle(void) enter_idle(); /* Don't trace irqs off for idle */ stop_critical_timings(); - pm_idle(); + if (cpuidle_idle_call()) + pm_idle(); start_critical_timings(); /* In many cases the interrupt that ended idle diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 7977f0c..c346d11 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -74,7 +74,7 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) #ifdef CONFIG_X86_64 case 0x40 ... 0x4f: - if (regs->cs != __USER_CS) + if (!user_64bit_mode(regs)) /* 32-bit mode: register increment */ return 0; /* 64-bit mode: REX prefix */ diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index fbb0a04..bc19be3 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -168,7 +168,7 @@ ENTRY(sys_call_table) .long ptregs_vm86 .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* Old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index fbc097a..6913369 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -49,7 +49,7 @@ #include <asm/stacktrace.h> #include <asm/processor.h> #include <asm/debugreg.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/traps.h> #include <asm/desc.h> @@ -872,12 +872,6 @@ void __init trap_init(void) set_bit(SYSCALL_VECTOR, used_vectors); #endif -#ifdef CONFIG_X86_64 - BUG_ON(test_bit(VSYSCALL_EMU_VECTOR, used_vectors)); - set_system_intr_gate(VSYSCALL_EMU_VECTOR, &emulate_vsyscall); - set_bit(VSYSCALL_EMU_VECTOR, used_vectors); -#endif - /* * Should be a barrier for any external CPU state: */ diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 4aa9c54..0f703f1 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -71,7 +71,6 @@ PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(6); /* RW_ */ #ifdef CONFIG_X86_64 - user PT_LOAD FLAGS(5); /* R_E */ #ifdef CONFIG_SMP percpu PT_LOAD FLAGS(6); /* RW_ */ #endif @@ -154,44 +153,16 @@ SECTIONS #ifdef CONFIG_X86_64 -#define VSYSCALL_ADDR (-10*1024*1024) - -#define VLOAD_OFFSET (VSYSCALL_ADDR - __vsyscall_0 + LOAD_OFFSET) -#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) - -#define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0) -#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) - - . = ALIGN(4096); - __vsyscall_0 = .; - - . = VSYSCALL_ADDR; - .vsyscall : AT(VLOAD(.vsyscall)) { - *(.vsyscall_0) - - . = 1024; - *(.vsyscall_1) - - . = 2048; - *(.vsyscall_2) - - . = 4096; /* Pad the whole page. */ - } :user =0xcc - . = ALIGN(__vsyscall_0 + PAGE_SIZE, PAGE_SIZE); - -#undef VSYSCALL_ADDR -#undef VLOAD_OFFSET -#undef VLOAD -#undef VVIRT_OFFSET -#undef VVIRT - + . = ALIGN(PAGE_SIZE); __vvar_page = .; .vvar : AT(ADDR(.vvar) - LOAD_OFFSET) { + /* work around gold bug 13023 */ + __vvar_beginning_hack = .; - /* Place all vvars at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) \ - . = offset; \ + /* Place all vvars at the offsets in asm/vvar.h. */ +#define EMIT_VVAR(name, offset) \ + . = __vvar_beginning_hack + offset; \ *(.vvar_ ## name) #define __VVAR_KERNEL_LDS #include <asm/vvar.h> diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index dda7dff..18ae83d 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -18,9 +18,6 @@ * use the vDSO. */ -/* Disable profiling for userspace code: */ -#define DISABLE_BRANCH_PROFILING - #include <linux/time.h> #include <linux/init.h> #include <linux/kernel.h> @@ -50,12 +47,36 @@ #include <asm/vgtod.h> #include <asm/traps.h> +#define CREATE_TRACE_POINTS +#include "vsyscall_trace.h" + DEFINE_VVAR(int, vgetcpu_mode); DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) = { .lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), }; +static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; + +static int __init vsyscall_setup(char *str) +{ + if (str) { + if (!strcmp("emulate", str)) + vsyscall_mode = EMULATE; + else if (!strcmp("native", str)) + vsyscall_mode = NATIVE; + else if (!strcmp("none", str)) + vsyscall_mode = NONE; + else + return -EINVAL; + + return 0; + } + + return -EINVAL; +} +early_param("vsyscall", vsyscall_setup); + void update_vsyscall_tz(void) { unsigned long flags; @@ -100,7 +121,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, printk("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", level, tsk->comm, task_pid_nr(tsk), - message, regs->ip - 2, regs->cs, + message, regs->ip, regs->cs, regs->sp, regs->ax, regs->si, regs->di); } @@ -118,46 +139,39 @@ static int addr_to_vsyscall_nr(unsigned long addr) return nr; } -void dotraplinkage do_emulate_vsyscall(struct pt_regs *regs, long error_code) +bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) { struct task_struct *tsk; unsigned long caller; int vsyscall_nr; long ret; - local_irq_enable(); - /* - * Real 64-bit user mode code has cs == __USER_CS. Anything else - * is bogus. + * No point in checking CS -- the only way to get here is a user mode + * trap to a high address, which means that we're in 64-bit user code. */ - if (regs->cs != __USER_CS) { - /* - * If we trapped from kernel mode, we might as well OOPS now - * instead of returning to some random address and OOPSing - * then. - */ - BUG_ON(!user_mode(regs)); - /* Compat mode and non-compat 32-bit CS should both segfault. */ - warn_bad_vsyscall(KERN_WARNING, regs, - "illegal int 0xcc from 32-bit mode"); - goto sigsegv; + WARN_ON_ONCE(address != regs->ip); + + if (vsyscall_mode == NONE) { + warn_bad_vsyscall(KERN_INFO, regs, + "vsyscall attempted with vsyscall=none"); + return false; } - /* - * x86-ism here: regs->ip points to the instruction after the int 0xcc, - * and int 0xcc is two bytes long. - */ - vsyscall_nr = addr_to_vsyscall_nr(regs->ip - 2); + vsyscall_nr = addr_to_vsyscall_nr(address); + + trace_emulate_vsyscall(vsyscall_nr); + if (vsyscall_nr < 0) { warn_bad_vsyscall(KERN_WARNING, regs, - "illegal int 0xcc (exploit attempt?)"); + "misaligned vsyscall (exploit attempt or buggy program) -- look up the vsyscall kernel parameter if you need a workaround"); goto sigsegv; } if (get_user(caller, (unsigned long __user *)regs->sp) != 0) { - warn_bad_vsyscall(KERN_WARNING, regs, "int 0xcc with bad stack (exploit attempt?)"); + warn_bad_vsyscall(KERN_WARNING, regs, + "vsyscall with bad stack (exploit attempt?)"); goto sigsegv; } @@ -202,13 +216,11 @@ void dotraplinkage do_emulate_vsyscall(struct pt_regs *regs, long error_code) regs->ip = caller; regs->sp += 8; - local_irq_disable(); - return; + return true; sigsegv: - regs->ip -= 2; /* The faulting instruction should be the int 0xcc. */ force_sig(SIGSEGV, current); - local_irq_disable(); + return true; } /* @@ -256,15 +268,21 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) void __init map_vsyscall(void) { - extern char __vsyscall_0; - unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); + extern char __vsyscall_page; + unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); extern char __vvar_page; unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page); - /* Note that VSYSCALL_MAPPED_PAGES must agree with the code below. */ - __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); + __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall, + vsyscall_mode == NATIVE + ? PAGE_KERNEL_VSYSCALL + : PAGE_KERNEL_VVAR); + BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_FIRST_PAGE) != + (unsigned long)VSYSCALL_START); + __set_fixmap(VVAR_PAGE, physaddr_vvar_page, PAGE_KERNEL_VVAR); - BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) != (unsigned long)VVAR_ADDRESS); + BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) != + (unsigned long)VVAR_ADDRESS); } static int __init vsyscall_init(void) diff --git a/arch/x86/kernel/vsyscall_emu_64.S b/arch/x86/kernel/vsyscall_emu_64.S index ffa845e..c9596a9 100644 --- a/arch/x86/kernel/vsyscall_emu_64.S +++ b/arch/x86/kernel/vsyscall_emu_64.S @@ -7,21 +7,31 @@ */ #include <linux/linkage.h> + #include <asm/irq_vectors.h> +#include <asm/page_types.h> +#include <asm/unistd_64.h> + +__PAGE_ALIGNED_DATA + .globl __vsyscall_page + .balign PAGE_SIZE, 0xcc + .type __vsyscall_page, @object +__vsyscall_page: + + mov $__NR_gettimeofday, %rax + syscall + ret -/* The unused parts of the page are filled with 0xcc by the linker script. */ + .balign 1024, 0xcc + mov $__NR_time, %rax + syscall + ret -.section .vsyscall_0, "a" -ENTRY(vsyscall_0) - int $VSYSCALL_EMU_VECTOR -END(vsyscall_0) + .balign 1024, 0xcc + mov $__NR_getcpu, %rax + syscall + ret -.section .vsyscall_1, "a" -ENTRY(vsyscall_1) - int $VSYSCALL_EMU_VECTOR -END(vsyscall_1) + .balign 4096, 0xcc -.section .vsyscall_2, "a" -ENTRY(vsyscall_2) - int $VSYSCALL_EMU_VECTOR -END(vsyscall_2) + .size __vsyscall_page, 4096 diff --git a/arch/x86/kernel/vsyscall_trace.h b/arch/x86/kernel/vsyscall_trace.h new file mode 100644 index 0000000..a8b2ede --- /dev/null +++ b/arch/x86/kernel/vsyscall_trace.h @@ -0,0 +1,29 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vsyscall + +#if !defined(__VSYSCALL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __VSYSCALL_TRACE_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(emulate_vsyscall, + + TP_PROTO(int nr), + + TP_ARGS(nr), + + TP_STRUCT__entry(__field(int, nr)), + + TP_fast_assign( + __entry->nr = nr; + ), + + TP_printk("nr = %d", __entry->nr) +); + +#endif + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../arch/x86/kernel +#define TRACE_INCLUDE_FILE vsyscall_trace +#include <trace/define_trace.h> diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 988724b..ff5790d 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -22,6 +22,8 @@ config KVM depends on HAVE_KVM # for device assignment: depends on PCI + # for TASKSTATS/TASK_DELAY_ACCT: + depends on NET select PREEMPT_NOTIFIERS select MMU_NOTIFIER select ANON_INODES @@ -31,6 +33,7 @@ config KVM select KVM_ASYNC_PF select USER_RETURN_NOTIFIER select KVM_MMIO + select TASKSTATS select TASK_DELAY_ACCT ---help--- Support hosting fully virtualized guest machines using hardware diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 2b2255b..57dcbd4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -33,7 +33,7 @@ #include <asm/page.h> #include <asm/current.h> #include <asm/apicdef.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include "kvm_cache_regs.h" #include "irq.h" #include "trace.h" diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c index abd86e86..ae432ea 100644 --- a/arch/x86/kvm/timer.c +++ b/arch/x86/kvm/timer.c @@ -15,7 +15,7 @@ #include <linux/kvm_host.h> #include <linux/kvm.h> #include <linux/hrtimer.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include "kvm_timer.h" static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c index 540179e..042f682 100644 --- a/arch/x86/lib/atomic64_32.c +++ b/arch/x86/lib/atomic64_32.c @@ -4,7 +4,7 @@ #include <asm/processor.h> #include <asm/cmpxchg.h> -#include <asm/atomic.h> +#include <linux/atomic.h> long long atomic64_read_cx8(long long, const atomic64_t *v); EXPORT_SYMBOL(atomic64_read_cx8); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 4d09df0..0d17c8c 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -17,6 +17,7 @@ #include <asm/traps.h> /* dotraplinkage, ... */ #include <asm/pgalloc.h> /* pgd_*(), ... */ #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ +#include <asm/vsyscall.h> /* * Page fault error code bits: @@ -105,7 +106,7 @@ check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr, * but for now it's good enough to assume that long * mode only uses well known segments or kernel. */ - return (!user_mode(regs)) || (regs->cs == __USER_CS); + return (!user_mode(regs) || user_64bit_mode(regs)); #endif case 0x60: /* 0x64 thru 0x67 are valid prefixes in all modes. */ @@ -720,6 +721,18 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, if (is_errata100(regs, address)) return; +#ifdef CONFIG_X86_64 + /* + * Instruction fetch faults in the vsyscall page might need + * emulation. + */ + if (unlikely((error_code & PF_INSTR) && + ((address & ~0xfff) == VSYSCALL_START))) { + if (emulate_vsyscall(regs, address)) + return; + } +#endif + if (unlikely(show_unhandled_signals)) show_signal_msg(regs, error_code, address, tsk); diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index c83c3d0..de54b9b 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -33,7 +33,7 @@ #include <asm/pgtable.h> #include <linux/mmiotrace.h> #include <asm/e820.h> /* for ISA_START_ADDRESS */ -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/percpu.h> #include <linux/cpu.h> diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 68c3c13..039d913 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -246,10 +246,9 @@ static void add_resources(struct pci_root_info *info) conflict = insert_resource_conflict(root, res); if (conflict) - dev_err(&info->bridge->dev, - "address space collision: host bridge window %pR " - "conflicts with %s %pR\n", - res, conflict->name, conflict); + dev_info(&info->bridge->dev, + "ignoring host bridge window %pR (conflicts with %s %pR)\n", + res, conflict->name, conflict); else pci_bus_add_resource(info->bus, res, 0); } @@ -361,6 +360,20 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) } } + /* After the PCI-E bus has been walked and all devices discovered, + * configure any settings of the fabric that might be necessary. + */ + if (bus) { + struct pci_bus *child; + list_for_each_entry(child, &bus->children, node) { + struct pci_dev *self = child->self; + if (!self) + continue; + + pcie_bus_configure_settings(child, self->pcie_mpss); + } + } + if (!bus) kfree(sd); diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 67858be..9917609 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c @@ -257,6 +257,7 @@ static int ce4100_conf_read(unsigned int seg, unsigned int bus, { int i; + WARN_ON(seg); if (bus == 1) { for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { if (bus1_fixups[i].dev_func == devfn && @@ -282,6 +283,7 @@ static int ce4100_conf_write(unsigned int seg, unsigned int bus, { int i; + WARN_ON(seg); if (bus == 1) { for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { if (bus1_fixups[i].dev_func == devfn && diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 5fe7502..92df322 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -247,13 +247,6 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { }, #endif /* __i386__ */ { - .callback = find_sort_method, - .ident = "Dell System", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - }, - }, - { .callback = set_bf_sort, .ident = "Dell PowerEdge 1950", .matches = { @@ -294,6 +287,13 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { }, }, { + .callback = find_sort_method, + .ident = "Dell System", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + }, + }, + { .callback = set_bf_sort, .ident = "HP ProLiant BL20p G3", .matches = { diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index e6fd847..4f2c704 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c @@ -22,7 +22,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, { unsigned long flags; - if ((bus > 255) || (devfn > 255) || (reg > 4095)) { + if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) { *value = -1; return -EINVAL; } @@ -53,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, { unsigned long flags; - if ((bus > 255) || (devfn > 255) || (reg > 4095)) + if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; raw_spin_lock_irqsave(&pci_config_lock, flags); @@ -97,6 +97,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, unsigned long flags; int dev, fn; + WARN_ON(seg); if ((bus > 255) || (devfn > 255) || (reg > 255)) { *value = -1; return -EINVAL; @@ -138,6 +139,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus, unsigned long flags; int dev, fn; + WARN_ON(seg); if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 5c9e245..512a88c 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c @@ -34,6 +34,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, unsigned long flags; void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); + WARN_ON(seg); if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; @@ -73,6 +74,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, unsigned long flags; void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); + WARN_ON(seg); if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c index 13700ec..5262603 100644 --- a/arch/x86/pci/olpc.c +++ b/arch/x86/pci/olpc.c @@ -206,6 +206,8 @@ static int pci_olpc_read(unsigned int seg, unsigned int bus, { uint32_t *addr; + WARN_ON(seg); + /* Use the hardware mechanism for non-simulated devices */ if (!is_simulated(bus, devfn)) return pci_direct_conf1.read(seg, bus, devfn, reg, len, value); @@ -264,6 +266,8 @@ static int pci_olpc_read(unsigned int seg, unsigned int bus, static int pci_olpc_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, uint32_t value) { + WARN_ON(seg); + /* Use the hardware mechanism for non-simulated devices */ if (!is_simulated(bus, devfn)) return pci_direct_conf1.write(seg, bus, devfn, reg, len, value); diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index a5f7d0d..f685535 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -181,6 +181,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, unsigned long flags; unsigned long bx = (bus << 8) | devfn; + WARN_ON(seg); if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; @@ -247,6 +248,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, unsigned long flags; unsigned long bx = (bus << 8) | devfn; + WARN_ON(seg); if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 03008f7..6f2f8ee 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -24,7 +24,7 @@ static void pci_visws_disable_irq(struct pci_dev *dev) { } unsigned int pci_bus0, pci_bus1; -static int __init visws_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __init visws_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq, bus = dev->bus->number; diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile index f61ccdd..1ea3877 100644 --- a/arch/x86/platform/mrst/Makefile +++ b/arch/x86/platform/mrst/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_X86_MRST) += mrst.o obj-$(CONFIG_X86_MRST) += vrtc.o obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o +obj-$(CONFIG_X86_MRST) += pmu.o diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 7000e74b..58425ad 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -689,7 +689,9 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) irq_attr.trigger = 1; irq_attr.polarity = 1; io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); - } + } else + pentry->irq = 0; /* No irq */ + switch (pentry->type) { case SFI_DEV_TYPE_IPC: /* ID as IRQ is a hack that will go away */ diff --git a/arch/x86/platform/mrst/pmu.c b/arch/x86/platform/mrst/pmu.c new file mode 100644 index 0000000..9281da7 --- /dev/null +++ b/arch/x86/platform/mrst/pmu.c @@ -0,0 +1,817 @@ +/* + * mrst/pmu.c - driver for MRST Power Management Unit + * + * Copyright (c) 2011, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/cpuidle.h> +#include <linux/debugfs.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/seq_file.h> +#include <linux/sfi.h> +#include <asm/intel_scu_ipc.h> +#include "pmu.h" + +#define IPCMSG_FW_REVISION 0xF4 + +struct mrst_device { + u16 pci_dev_num; /* DEBUG only */ + u16 lss; + u16 latest_request; + unsigned int pci_state_counts[PCI_D3cold + 1]; /* DEBUG only */ +}; + +/* + * comlete list of MRST PCI devices + */ +static struct mrst_device mrst_devs[] = { +/* 0 */ { 0x0800, LSS_SPI0 }, /* Moorestown SPI Ctrl 0 */ +/* 1 */ { 0x0801, LSS_SPI1 }, /* Moorestown SPI Ctrl 1 */ +/* 2 */ { 0x0802, LSS_I2C0 }, /* Moorestown I2C 0 */ +/* 3 */ { 0x0803, LSS_I2C1 }, /* Moorestown I2C 1 */ +/* 4 */ { 0x0804, LSS_I2C2 }, /* Moorestown I2C 2 */ +/* 5 */ { 0x0805, LSS_KBD }, /* Moorestown Keyboard Ctrl */ +/* 6 */ { 0x0806, LSS_USB_HC }, /* Moorestown USB Ctrl */ +/* 7 */ { 0x0807, LSS_SD_HC0 }, /* Moorestown SD Host Ctrl 0 */ +/* 8 */ { 0x0808, LSS_SD_HC1 }, /* Moorestown SD Host Ctrl 1 */ +/* 9 */ { 0x0809, LSS_NAND }, /* Moorestown NAND Ctrl */ +/* 10 */ { 0x080a, LSS_AUDIO }, /* Moorestown Audio Ctrl */ +/* 11 */ { 0x080b, LSS_IMAGING }, /* Moorestown ISP */ +/* 12 */ { 0x080c, LSS_SECURITY }, /* Moorestown Security Controller */ +/* 13 */ { 0x080d, LSS_DISPLAY }, /* Moorestown External Displays */ +/* 14 */ { 0x080e, 0 }, /* Moorestown SCU IPC */ +/* 15 */ { 0x080f, LSS_GPIO }, /* Moorestown GPIO Controller */ +/* 16 */ { 0x0810, 0 }, /* Moorestown Power Management Unit */ +/* 17 */ { 0x0811, LSS_USB_OTG }, /* Moorestown OTG Ctrl */ +/* 18 */ { 0x0812, LSS_SPI2 }, /* Moorestown SPI Ctrl 2 */ +/* 19 */ { 0x0813, 0 }, /* Moorestown SC DMA */ +/* 20 */ { 0x0814, LSS_AUDIO_LPE }, /* Moorestown LPE DMA */ +/* 21 */ { 0x0815, LSS_AUDIO_SSP }, /* Moorestown SSP0 */ + +/* 22 */ { 0x084F, LSS_SD_HC2 }, /* Moorestown SD Host Ctrl 2 */ + +/* 23 */ { 0x4102, 0 }, /* Lincroft */ +/* 24 */ { 0x4110, 0 }, /* Lincroft */ +}; + +/* n.b. We ignore PCI-id 0x815 in LSS9 b/c MeeGo has no driver for it */ +static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0}; +static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803, + 0x0804, 0x0805, 0x080f, 0}; + +/* handle concurrent SMP invokations of pmu_pci_set_power_state() */ +static spinlock_t mrst_pmu_power_state_lock; + +static unsigned int wake_counters[MRST_NUM_LSS]; /* DEBUG only */ +static unsigned int pmu_irq_stats[INT_INVALID + 1]; /* DEBUG only */ + +static int graphics_is_off; +static int lss_s0i3_enabled; +static bool mrst_pmu_s0i3_enable; + +/* debug counters */ +static u32 pmu_wait_ready_calls; +static u32 pmu_wait_ready_udelays; +static u32 pmu_wait_ready_udelays_max; +static u32 pmu_wait_done_calls; +static u32 pmu_wait_done_udelays; +static u32 pmu_wait_done_udelays_max; +static u32 pmu_set_power_state_entry; +static u32 pmu_set_power_state_send_cmd; + +static struct mrst_device *pci_id_2_mrst_dev(u16 pci_dev_num) +{ + int index = 0; + + if ((pci_dev_num >= 0x0800) && (pci_dev_num <= 0x815)) + index = pci_dev_num - 0x800; + else if (pci_dev_num == 0x084F) + index = 22; + else if (pci_dev_num == 0x4102) + index = 23; + else if (pci_dev_num == 0x4110) + index = 24; + + if (pci_dev_num != mrst_devs[index].pci_dev_num) { + WARN_ONCE(1, FW_BUG "Unknown PCI device 0x%04X\n", pci_dev_num); + return 0; + } + + return &mrst_devs[index]; +} + +/** + * mrst_pmu_validate_cstates + * @dev: cpuidle_device + * + * Certain states are not appropriate for governor to pick in some cases. + * This function will be called as cpuidle_device's prepare callback and + * thus tells governor to ignore such states when selecting the next state + * to enter. + */ + +#define IDLE_STATE4_IS_C6 4 +#define IDLE_STATE5_IS_S0I3 5 + +int mrst_pmu_invalid_cstates(void) +{ + int cpu = smp_processor_id(); + + /* + * Demote to C4 if the PMU is busy. + * Since LSS changes leave the busy bit clear... + * busy means either the PMU is waiting for an ACK-C6 that + * isn't coming due to an MWAIT that returned immediately; + * or we returned from S0i3 successfully, and the PMU + * is not done sending us interrupts. + */ + if (pmu_read_busy_status()) + return 1 << IDLE_STATE4_IS_C6 | 1 << IDLE_STATE5_IS_S0I3; + + /* + * Disallow S0i3 if: PMU is not initialized, or CPU1 is active, + * or if device LSS is insufficient, or the GPU is active, + * or if it has been explicitly disabled. + */ + if (!pmu_reg || !cpumask_equal(cpu_online_mask, cpumask_of(cpu)) || + !lss_s0i3_enabled || !graphics_is_off || !mrst_pmu_s0i3_enable) + return 1 << IDLE_STATE5_IS_S0I3; + else + return 0; +} + +/* + * pmu_update_wake_counters(): read PM_WKS, update wake_counters[] + * DEBUG only. + */ +static void pmu_update_wake_counters(void) +{ + int lss; + u32 wake_status; + + wake_status = pmu_read_wks(); + + for (lss = 0; lss < MRST_NUM_LSS; ++lss) { + if (wake_status & (1 << lss)) + wake_counters[lss]++; + } +} + +int mrst_pmu_s0i3_entry(void) +{ + int status; + + /* Clear any possible error conditions */ + pmu_write_ics(0x300); + + /* set wake control to current D-states */ + pmu_write_wssc(S0I3_SSS_TARGET); + + status = mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd); + pmu_update_wake_counters(); + return status; +} + +/* poll for maximum of 5ms for busy bit to clear */ +static int pmu_wait_ready(void) +{ + int udelays; + + pmu_wait_ready_calls++; + + for (udelays = 0; udelays < 500; ++udelays) { + if (udelays > pmu_wait_ready_udelays_max) + pmu_wait_ready_udelays_max = udelays; + + if (pmu_read_busy_status() == 0) + return 0; + + udelay(10); + pmu_wait_ready_udelays++; + } + + /* + * if this fires, observe + * /sys/kernel/debug/mrst_pmu_wait_ready_calls + * /sys/kernel/debug/mrst_pmu_wait_ready_udelays + */ + WARN_ONCE(1, "SCU not ready for 5ms"); + return -EBUSY; +} +/* poll for maximum of 50ms us for busy bit to clear */ +static int pmu_wait_done(void) +{ + int udelays; + + pmu_wait_done_calls++; + + for (udelays = 0; udelays < 500; ++udelays) { + if (udelays > pmu_wait_done_udelays_max) + pmu_wait_done_udelays_max = udelays; + + if (pmu_read_busy_status() == 0) + return 0; + + udelay(100); + pmu_wait_done_udelays++; + } + + /* + * if this fires, observe + * /sys/kernel/debug/mrst_pmu_wait_done_calls + * /sys/kernel/debug/mrst_pmu_wait_done_udelays + */ + WARN_ONCE(1, "SCU not done for 50ms"); + return -EBUSY; +} + +u32 mrst_pmu_msi_is_disabled(void) +{ + return pmu_msi_is_disabled(); +} + +void mrst_pmu_enable_msi(void) +{ + pmu_msi_enable(); +} + +/** + * pmu_irq - pmu driver interrupt handler + * Context: interrupt context + */ +static irqreturn_t pmu_irq(int irq, void *dummy) +{ + union pmu_pm_ics pmu_ics; + + pmu_ics.value = pmu_read_ics(); + + if (!pmu_ics.bits.pending) + return IRQ_NONE; + + switch (pmu_ics.bits.cause) { + case INT_SPURIOUS: + case INT_CMD_DONE: + case INT_CMD_ERR: + case INT_WAKE_RX: + case INT_SS_ERROR: + case INT_S0IX_MISS: + case INT_NO_ACKC6: + pmu_irq_stats[pmu_ics.bits.cause]++; + break; + default: + pmu_irq_stats[INT_INVALID]++; + } + + pmu_write_ics(pmu_ics.value); /* Clear pending interrupt */ + + return IRQ_HANDLED; +} + +/* + * Translate PCI power management to MRST LSS D-states + */ +static int pci_2_mrst_state(int lss, pci_power_t pci_state) +{ + switch (pci_state) { + case PCI_D0: + if (SSMSK(D0i1, lss) & D0I1_ACG_SSS_TARGET) + return D0i1; + else + return D0; + case PCI_D1: + return D0i1; + case PCI_D2: + return D0i2; + case PCI_D3hot: + case PCI_D3cold: + return D0i3; + default: + WARN(1, "pci_state %d\n", pci_state); + return 0; + } +} + +static int pmu_issue_command(u32 pm_ssc) +{ + union pmu_pm_set_cfg_cmd_t command; + + if (pmu_read_busy_status()) { + pr_debug("pmu is busy, Operation not permitted\n"); + return -1; + } + + /* + * enable interrupts in PMU so that interrupts are + * propagated when ioc bit for a particular set + * command is set + */ + + pmu_irq_enable(); + + /* Configure the sub systems for pmu2 */ + + pmu_write_ssc(pm_ssc); + + /* + * Send the set config command for pmu its configured + * for mode CM_IMMEDIATE & hence with No Trigger + */ + + command.pmu2_params.d_param.cfg_mode = CM_IMMEDIATE; + command.pmu2_params.d_param.cfg_delay = 0; + command.pmu2_params.d_param.rsvd = 0; + + /* construct the command to send SET_CFG to particular PMU */ + command.pmu2_params.d_param.cmd = SET_CFG_CMD; + command.pmu2_params.d_param.ioc = 0; + command.pmu2_params.d_param.mode_id = 0; + command.pmu2_params.d_param.sys_state = SYS_STATE_S0I0; + + /* write the value of PM_CMD into particular PMU */ + pr_debug("pmu command being written %x\n", + command.pmu_pm_set_cfg_cmd_value); + + pmu_write_cmd(command.pmu_pm_set_cfg_cmd_value); + + return 0; +} + +static u16 pmu_min_lss_pci_req(u16 *ids, u16 pci_state) +{ + u16 existing_request; + int i; + + for (i = 0; ids[i]; ++i) { + struct mrst_device *mrst_dev; + + mrst_dev = pci_id_2_mrst_dev(ids[i]); + if (unlikely(!mrst_dev)) + continue; + + existing_request = mrst_dev->latest_request; + if (existing_request < pci_state) + pci_state = existing_request; + } + return pci_state; +} + +/** + * pmu_pci_set_power_state - Callback function is used by all the PCI devices + * for a platform specific device power on/shutdown. + */ + +int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t pci_state) +{ + u32 old_sss, new_sss; + int status = 0; + struct mrst_device *mrst_dev; + + pmu_set_power_state_entry++; + + BUG_ON(pdev->vendor != PCI_VENDOR_ID_INTEL); + BUG_ON(pci_state < PCI_D0 || pci_state > PCI_D3cold); + + mrst_dev = pci_id_2_mrst_dev(pdev->device); + if (unlikely(!mrst_dev)) + return -ENODEV; + + mrst_dev->pci_state_counts[pci_state]++; /* count invocations */ + + /* PMU driver calls self as part of PCI initialization, ignore */ + if (pdev->device == PCI_DEV_ID_MRST_PMU) + return 0; + + BUG_ON(!pmu_reg); /* SW bug if called before initialized */ + + spin_lock(&mrst_pmu_power_state_lock); + + if (pdev->d3_delay) { + dev_dbg(&pdev->dev, "d3_delay %d, should be 0\n", + pdev->d3_delay); + pdev->d3_delay = 0; + } + /* + * If Lincroft graphics, simply remember state + */ + if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY + && !((pdev->class & PCI_SUB_CLASS_MASK) >> 8)) { + if (pci_state == PCI_D0) + graphics_is_off = 0; + else + graphics_is_off = 1; + goto ret; + } + + if (!mrst_dev->lss) + goto ret; /* device with no LSS */ + + if (mrst_dev->latest_request == pci_state) + goto ret; /* no change */ + + mrst_dev->latest_request = pci_state; /* record latest request */ + + /* + * LSS9 and LSS10 contain multiple PCI devices. + * Use the lowest numbered (highest power) state in the LSS + */ + if (mrst_dev->lss == 9) + pci_state = pmu_min_lss_pci_req(mrst_lss9_pci_ids, pci_state); + else if (mrst_dev->lss == 10) + pci_state = pmu_min_lss_pci_req(mrst_lss10_pci_ids, pci_state); + + status = pmu_wait_ready(); + if (status) + goto ret; + + old_sss = pmu_read_sss(); + new_sss = old_sss & ~SSMSK(3, mrst_dev->lss); + new_sss |= SSMSK(pci_2_mrst_state(mrst_dev->lss, pci_state), + mrst_dev->lss); + + if (new_sss == old_sss) + goto ret; /* nothing to do */ + + pmu_set_power_state_send_cmd++; + + status = pmu_issue_command(new_sss); + + if (unlikely(status != 0)) { + dev_err(&pdev->dev, "Failed to Issue a PM command\n"); + goto ret; + } + + if (pmu_wait_done()) + goto ret; + + lss_s0i3_enabled = + ((pmu_read_sss() & S0I3_SSS_TARGET) == S0I3_SSS_TARGET); +ret: + spin_unlock(&mrst_pmu_power_state_lock); + return status; +} + +#ifdef CONFIG_DEBUG_FS +static char *d0ix_names[] = {"D0", "D0i1", "D0i2", "D0i3"}; + +static inline const char *d0ix_name(int state) +{ + return d0ix_names[(int) state]; +} + +static int debug_mrst_pmu_show(struct seq_file *s, void *unused) +{ + struct pci_dev *pdev = NULL; + u32 cur_pmsss; + int lss; + + seq_printf(s, "0x%08X D0I1_ACG_SSS_TARGET\n", D0I1_ACG_SSS_TARGET); + + cur_pmsss = pmu_read_sss(); + + seq_printf(s, "0x%08X S0I3_SSS_TARGET\n", S0I3_SSS_TARGET); + + seq_printf(s, "0x%08X Current SSS ", cur_pmsss); + seq_printf(s, lss_s0i3_enabled ? "\n" : "[BLOCKS s0i3]\n"); + + if (cpumask_equal(cpu_online_mask, cpumask_of(0))) + seq_printf(s, "cpu0 is only cpu online\n"); + else + seq_printf(s, "cpu0 is NOT only cpu online [BLOCKS S0i3]\n"); + + seq_printf(s, "GFX: %s\n", graphics_is_off ? "" : "[BLOCKS s0i3]"); + + + for_each_pci_dev(pdev) { + int pos; + u16 pmcsr; + struct mrst_device *mrst_dev; + int i; + + mrst_dev = pci_id_2_mrst_dev(pdev->device); + + seq_printf(s, "%s %04x/%04X %-16.16s ", + dev_name(&pdev->dev), + pdev->vendor, pdev->device, + dev_driver_string(&pdev->dev)); + + if (unlikely (!mrst_dev)) { + seq_printf(s, " UNKNOWN\n"); + continue; + } + + if (mrst_dev->lss) + seq_printf(s, "LSS %2d %-4s ", mrst_dev->lss, + d0ix_name(((cur_pmsss >> + (mrst_dev->lss * 2)) & 0x3))); + else + seq_printf(s, " "); + + /* PCI PM config space setting */ + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pos != 0) { + pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); + seq_printf(s, "PCI-%-4s", + pci_power_name(pmcsr & PCI_PM_CTRL_STATE_MASK)); + } else { + seq_printf(s, " "); + } + + seq_printf(s, " %s ", pci_power_name(mrst_dev->latest_request)); + for (i = 0; i <= PCI_D3cold; ++i) + seq_printf(s, "%d ", mrst_dev->pci_state_counts[i]); + + if (mrst_dev->lss) { + unsigned int lssmask; + + lssmask = SSMSK(D0i3, mrst_dev->lss); + + if ((lssmask & S0I3_SSS_TARGET) && + ((lssmask & cur_pmsss) != + (lssmask & S0I3_SSS_TARGET))) + seq_printf(s , "[BLOCKS s0i3]"); + } + + seq_printf(s, "\n"); + } + seq_printf(s, "Wake Counters:\n"); + for (lss = 0; lss < MRST_NUM_LSS; ++lss) + seq_printf(s, "LSS%d %d\n", lss, wake_counters[lss]); + + seq_printf(s, "Interrupt Counters:\n"); + seq_printf(s, + "INT_SPURIOUS \t%8u\n" "INT_CMD_DONE \t%8u\n" + "INT_CMD_ERR \t%8u\n" "INT_WAKE_RX \t%8u\n" + "INT_SS_ERROR \t%8u\n" "INT_S0IX_MISS\t%8u\n" + "INT_NO_ACKC6 \t%8u\n" "INT_INVALID \t%8u\n", + pmu_irq_stats[INT_SPURIOUS], pmu_irq_stats[INT_CMD_DONE], + pmu_irq_stats[INT_CMD_ERR], pmu_irq_stats[INT_WAKE_RX], + pmu_irq_stats[INT_SS_ERROR], pmu_irq_stats[INT_S0IX_MISS], + pmu_irq_stats[INT_NO_ACKC6], pmu_irq_stats[INT_INVALID]); + + seq_printf(s, "mrst_pmu_wait_ready_calls %8d\n", + pmu_wait_ready_calls); + seq_printf(s, "mrst_pmu_wait_ready_udelays %8d\n", + pmu_wait_ready_udelays); + seq_printf(s, "mrst_pmu_wait_ready_udelays_max %8d\n", + pmu_wait_ready_udelays_max); + seq_printf(s, "mrst_pmu_wait_done_calls %8d\n", + pmu_wait_done_calls); + seq_printf(s, "mrst_pmu_wait_done_udelays %8d\n", + pmu_wait_done_udelays); + seq_printf(s, "mrst_pmu_wait_done_udelays_max %8d\n", + pmu_wait_done_udelays_max); + seq_printf(s, "mrst_pmu_set_power_state_entry %8d\n", + pmu_set_power_state_entry); + seq_printf(s, "mrst_pmu_set_power_state_send_cmd %8d\n", + pmu_set_power_state_send_cmd); + seq_printf(s, "SCU busy: %d\n", pmu_read_busy_status()); + + return 0; +} + +static int debug_mrst_pmu_open(struct inode *inode, struct file *file) +{ + return single_open(file, debug_mrst_pmu_show, NULL); +} + +static const struct file_operations devices_state_operations = { + .open = debug_mrst_pmu_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* DEBUG_FS */ + +/* + * Validate SCU PCI shim PCI vendor capability byte + * against LSS hard-coded in mrst_devs[] above. + * DEBUG only. + */ +static void pmu_scu_firmware_debug(void) +{ + struct pci_dev *pdev = NULL; + + for_each_pci_dev(pdev) { + struct mrst_device *mrst_dev; + u8 pci_config_lss; + int pos; + + mrst_dev = pci_id_2_mrst_dev(pdev->device); + if (unlikely(!mrst_dev)) { + printk(KERN_ERR FW_BUG "pmu: Unknown " + "PCI device 0x%04X\n", pdev->device); + continue; + } + + if (mrst_dev->lss == 0) + continue; /* no LSS in our table */ + + pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR); + if (!pos != 0) { + printk(KERN_ERR FW_BUG "pmu: 0x%04X " + "missing PCI Vendor Capability\n", + pdev->device); + continue; + } + pci_read_config_byte(pdev, pos + 4, &pci_config_lss); + if (!(pci_config_lss & PCI_VENDOR_CAP_LOG_SS_MASK)) { + printk(KERN_ERR FW_BUG "pmu: 0x%04X " + "invalid PCI Vendor Capability 0x%x " + " expected LSS 0x%X\n", + pdev->device, pci_config_lss, mrst_dev->lss); + continue; + } + pci_config_lss &= PCI_VENDOR_CAP_LOG_ID_MASK; + + if (mrst_dev->lss == pci_config_lss) + continue; + + printk(KERN_ERR FW_BUG "pmu: 0x%04X LSS = %d, expected %d\n", + pdev->device, pci_config_lss, mrst_dev->lss); + } +} + +/** + * pmu_probe + */ +static int __devinit pmu_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) +{ + int ret; + struct mrst_pmu_reg *pmu; + + /* Init the device */ + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "Unable to Enable PCI device\n"); + return ret; + } + + ret = pci_request_regions(pdev, MRST_PMU_DRV_NAME); + if (ret < 0) { + dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n"); + goto out_err1; + } + + /* Map the memory of PMU reg base */ + pmu = pci_iomap(pdev, 0, 0); + if (!pmu) { + dev_err(&pdev->dev, "Unable to map the PMU address space\n"); + ret = -ENOMEM; + goto out_err2; + } + +#ifdef CONFIG_DEBUG_FS + /* /sys/kernel/debug/mrst_pmu */ + (void) debugfs_create_file("mrst_pmu", S_IFREG | S_IRUGO, + NULL, NULL, &devices_state_operations); +#endif + pmu_reg = pmu; /* success */ + + if (request_irq(pdev->irq, pmu_irq, 0, MRST_PMU_DRV_NAME, NULL)) { + dev_err(&pdev->dev, "Registering isr has failed\n"); + ret = -1; + goto out_err3; + } + + pmu_scu_firmware_debug(); + + pmu_write_wkc(S0I3_WAKE_SOURCES); /* Enable S0i3 wakeup sources */ + + pmu_wait_ready(); + + pmu_write_ssc(D0I1_ACG_SSS_TARGET); /* Enable Auto-Clock_Gating */ + pmu_write_cmd(0x201); + + spin_lock_init(&mrst_pmu_power_state_lock); + + /* Enable the hardware interrupt */ + pmu_irq_enable(); + return 0; + +out_err3: + free_irq(pdev->irq, NULL); + pci_iounmap(pdev, pmu_reg); + pmu_reg = NULL; +out_err2: + pci_release_region(pdev, 0); +out_err1: + pci_disable_device(pdev); + return ret; +} + +static void __devexit pmu_remove(struct pci_dev *pdev) +{ + dev_err(&pdev->dev, "Mid PM pmu_remove called\n"); + + /* Freeing up the irq */ + free_irq(pdev->irq, NULL); + + pci_iounmap(pdev, pmu_reg); + pmu_reg = NULL; + + /* disable the current PCI device */ + pci_release_region(pdev, 0); + pci_disable_device(pdev); +} + +static DEFINE_PCI_DEVICE_TABLE(pmu_pci_ids) = { + { PCI_VDEVICE(INTEL, PCI_DEV_ID_MRST_PMU), 0 }, + { } +}; + +MODULE_DEVICE_TABLE(pci, pmu_pci_ids); + +static struct pci_driver driver = { + .name = MRST_PMU_DRV_NAME, + .id_table = pmu_pci_ids, + .probe = pmu_probe, + .remove = __devexit_p(pmu_remove), +}; + +/** + * pmu_pci_register - register the PMU driver as PCI device + */ +static int __init pmu_pci_register(void) +{ + return pci_register_driver(&driver); +} + +/* Register and probe via fs_initcall() to preceed device_initcall() */ +fs_initcall(pmu_pci_register); + +static void __exit mid_pci_cleanup(void) +{ + pci_unregister_driver(&driver); +} + +static int ia_major; +static int ia_minor; + +static int pmu_sfi_parse_oem(struct sfi_table_header *table) +{ + struct sfi_table_simple *sb; + + sb = (struct sfi_table_simple *)table; + ia_major = (sb->pentry[1] >> 0) & 0xFFFF; + ia_minor = (sb->pentry[1] >> 16) & 0xFFFF; + printk(KERN_INFO "mrst_pmu: IA FW version v%x.%x\n", + ia_major, ia_minor); + + return 0; +} + +static int __init scu_fw_check(void) +{ + int ret; + u32 fw_version; + + if (!pmu_reg) + return 0; /* this driver didn't probe-out */ + + sfi_table_parse("OEMB", NULL, NULL, pmu_sfi_parse_oem); + + if (ia_major < 0x6005 || ia_minor < 0x1525) { + WARN(1, "mrst_pmu: IA FW version too old\n"); + return -1; + } + + ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0, + &fw_version, 1); + + if (ret) { + WARN(1, "mrst_pmu: IPC FW version? %d\n", ret); + } else { + int scu_major = (fw_version >> 8) & 0xFF; + int scu_minor = (fw_version >> 0) & 0xFF; + + printk(KERN_INFO "mrst_pmu: firmware v%x\n", fw_version); + + if ((scu_major >= 0xC0) && (scu_minor >= 0x49)) { + printk(KERN_INFO "mrst_pmu: enabling S0i3\n"); + mrst_pmu_s0i3_enable = true; + } else { + WARN(1, "mrst_pmu: S0i3 disabled, old firmware %X.%X", + scu_major, scu_minor); + } + } + return 0; +} +late_initcall(scu_fw_check); +module_exit(mid_pci_cleanup); diff --git a/arch/x86/platform/mrst/pmu.h b/arch/x86/platform/mrst/pmu.h new file mode 100644 index 0000000..bfbfe64 --- /dev/null +++ b/arch/x86/platform/mrst/pmu.h @@ -0,0 +1,234 @@ +/* + * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c + * + * Copyright (c) 2011, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _MRST_PMU_H_ +#define _MRST_PMU_H_ + +#define PCI_DEV_ID_MRST_PMU 0x0810 +#define MRST_PMU_DRV_NAME "mrst_pmu" +#define PCI_SUB_CLASS_MASK 0xFF00 + +#define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F +#define PCI_VENDOR_CAP_LOG_SS_MASK 0x80 + +#define SUB_SYS_ALL_D0I1 0x01155555 +#define S0I3_WAKE_SOURCES 0x00001FFF + +#define PM_S0I3_COMMAND \ + ((0 << 31) | /* Reserved */ \ + (0 << 30) | /* Core must be idle */ \ + (0xc2 << 22) | /* ACK C6 trigger */ \ + (3 << 19) | /* Trigger on DMI message */ \ + (3 << 16) | /* Enter S0i3 */ \ + (0 << 13) | /* Numeric mode ID (sw) */ \ + (3 << 9) | /* Trigger mode */ \ + (0 << 8) | /* Do not interrupt */ \ + (1 << 0)) /* Set configuration */ + +#define LSS_DMI 0 +#define LSS_SD_HC0 1 +#define LSS_SD_HC1 2 +#define LSS_NAND 3 +#define LSS_IMAGING 4 +#define LSS_SECURITY 5 +#define LSS_DISPLAY 6 +#define LSS_USB_HC 7 +#define LSS_USB_OTG 8 +#define LSS_AUDIO 9 +#define LSS_AUDIO_LPE 9 +#define LSS_AUDIO_SSP 9 +#define LSS_I2C0 10 +#define LSS_I2C1 10 +#define LSS_I2C2 10 +#define LSS_KBD 10 +#define LSS_SPI0 10 +#define LSS_SPI1 10 +#define LSS_SPI2 10 +#define LSS_GPIO 10 +#define LSS_SRAM 11 /* used by SCU, do not touch */ +#define LSS_SD_HC2 12 +/* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */ +#define MRST_NUM_LSS 13 + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define SSMSK(mask, lss) ((mask) << ((lss) * 2)) +#define D0 0 +#define D0i1 1 +#define D0i2 2 +#define D0i3 3 + +#define S0I3_SSS_TARGET ( \ + SSMSK(D0i1, LSS_DMI) | \ + SSMSK(D0i3, LSS_SD_HC0) | \ + SSMSK(D0i3, LSS_SD_HC1) | \ + SSMSK(D0i3, LSS_NAND) | \ + SSMSK(D0i3, LSS_SD_HC2) | \ + SSMSK(D0i3, LSS_IMAGING) | \ + SSMSK(D0i3, LSS_SECURITY) | \ + SSMSK(D0i3, LSS_DISPLAY) | \ + SSMSK(D0i3, LSS_USB_HC) | \ + SSMSK(D0i3, LSS_USB_OTG) | \ + SSMSK(D0i3, LSS_AUDIO) | \ + SSMSK(D0i1, LSS_I2C0)) + +/* + * D0i1 on Langwell is Autonomous Clock Gating (ACG). + * Enable ACG on every LSS except camera and audio + */ +#define D0I1_ACG_SSS_TARGET \ + (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO)) + +enum cm_mode { + CM_NOP, /* ignore the config mode value */ + CM_IMMEDIATE, + CM_DELAY, + CM_TRIGGER, + CM_INVALID +}; + +enum sys_state { + SYS_STATE_S0I0, + SYS_STATE_S0I1, + SYS_STATE_S0I2, + SYS_STATE_S0I3, + SYS_STATE_S3, + SYS_STATE_S5 +}; + +#define SET_CFG_CMD 1 + +enum int_status { + INT_SPURIOUS = 0, + INT_CMD_DONE = 1, + INT_CMD_ERR = 2, + INT_WAKE_RX = 3, + INT_SS_ERROR = 4, + INT_S0IX_MISS = 5, + INT_NO_ACKC6 = 6, + INT_INVALID = 7, +}; + +/* PMU register interface */ +static struct mrst_pmu_reg { + u32 pm_sts; /* 0x00 */ + u32 pm_cmd; /* 0x04 */ + u32 pm_ics; /* 0x08 */ + u32 _resv1; /* 0x0C */ + u32 pm_wkc[2]; /* 0x10 */ + u32 pm_wks[2]; /* 0x18 */ + u32 pm_ssc[4]; /* 0x20 */ + u32 pm_sss[4]; /* 0x30 */ + u32 pm_wssc[4]; /* 0x40 */ + u32 pm_c3c4; /* 0x50 */ + u32 pm_c5c6; /* 0x54 */ + u32 pm_msi_disable; /* 0x58 */ +} *pmu_reg; + +static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); } +static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); } +static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); } +static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); } + +static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); } +static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); } +static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); } +static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); } +static inline void pmu_write_wssc(u32 arg) + { writel(arg, &pmu_reg->pm_wssc[0]); } + +static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); } +static inline u32 pmu_msi_is_disabled(void) + { return readl(&pmu_reg->pm_msi_disable); } + +union pmu_pm_ics { + struct { + u32 cause:8; + u32 enable:1; + u32 pending:1; + u32 reserved:22; + } bits; + u32 value; +}; + +static inline void pmu_irq_enable(void) +{ + union pmu_pm_ics pmu_ics; + + pmu_ics.value = pmu_read_ics(); + pmu_ics.bits.enable = 1; + pmu_write_ics(pmu_ics.value); +} + +union pmu_pm_status { + struct { + u32 pmu_rev:8; + u32 pmu_busy:1; + u32 mode_id:4; + u32 Reserved:19; + } pmu_status_parts; + u32 pmu_status_value; +}; + +static inline int pmu_read_busy_status(void) +{ + union pmu_pm_status result; + + result.pmu_status_value = pmu_read_sts(); + + return result.pmu_status_parts.pmu_busy; +} + +/* pmu set config parameters */ +struct cfg_delay_param_t { + u32 cmd:8; + u32 ioc:1; + u32 cfg_mode:4; + u32 mode_id:3; + u32 sys_state:3; + u32 cfg_delay:8; + u32 rsvd:5; +}; + +struct cfg_trig_param_t { + u32 cmd:8; + u32 ioc:1; + u32 cfg_mode:4; + u32 mode_id:3; + u32 sys_state:3; + u32 cfg_trig_type:3; + u32 cfg_trig_val:8; + u32 cmbi:1; + u32 rsvd1:1; +}; + +union pmu_pm_set_cfg_cmd_t { + union { + struct cfg_delay_param_t d_param; + struct cfg_trig_param_t t_param; + } pmu2_params; + u32 pmu_pm_set_cfg_cmd_value; +}; + +#ifdef FUTURE_PATCH +extern int mrst_s0i3_entry(u32 regval, u32 *regaddr); +#else +static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; } +#endif +#endif diff --git a/arch/x86/platform/olpc/Makefile b/arch/x86/platform/olpc/Makefile index 81c5e21..fd332c5 100644 --- a/arch/x86/platform/olpc/Makefile +++ b/arch/x86/platform/olpc/Makefile @@ -1,2 +1,5 @@ obj-$(CONFIG_OLPC) += olpc.o olpc_ofw.o olpc_dt.o -obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o +obj-$(CONFIG_OLPC_XO1_PM) += olpc-xo1-pm.o xo1-wakeup.o +obj-$(CONFIG_OLPC_XO1_RTC) += olpc-xo1-rtc.o +obj-$(CONFIG_OLPC_XO1_SCI) += olpc-xo1-sci.o +obj-$(CONFIG_OLPC_XO15_SCI) += olpc-xo15-sci.o diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c new file mode 100644 index 0000000..6f3855a --- /dev/null +++ b/arch/x86/platform/olpc/olpc-xo1-pm.c @@ -0,0 +1,215 @@ +/* + * Support for power management features of the OLPC XO-1 laptop + * + * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> + * Copyright (C) 2010 One Laptop per Child + * Copyright (C) 2006 Red Hat, Inc. + * Copyright (C) 2006 Advanced Micro Devices, Inc. + * + * 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/cs5535.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/mfd/core.h> +#include <linux/suspend.h> + +#include <asm/io.h> +#include <asm/olpc.h> + +#define DRV_NAME "olpc-xo1-pm" + +static unsigned long acpi_base; +static unsigned long pms_base; + +static u16 wakeup_mask = CS5536_PM_PWRBTN; + +static struct { + unsigned long address; + unsigned short segment; +} ofw_bios_entry = { 0xF0000 + PAGE_OFFSET, __KERNEL_CS }; + +/* Set bits in the wakeup mask */ +void olpc_xo1_pm_wakeup_set(u16 value) +{ + wakeup_mask |= value; +} +EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_set); + +/* Clear bits in the wakeup mask */ +void olpc_xo1_pm_wakeup_clear(u16 value) +{ + wakeup_mask &= ~value; +} +EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_clear); + +static int xo1_power_state_enter(suspend_state_t pm_state) +{ + unsigned long saved_sci_mask; + int r; + + /* Only STR is supported */ + if (pm_state != PM_SUSPEND_MEM) + return -EINVAL; + + r = olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0); + if (r) + return r; + + /* + * Save SCI mask (this gets lost since PM1_EN is used as a mask for + * wakeup events, which is not necessarily the same event set) + */ + saved_sci_mask = inl(acpi_base + CS5536_PM1_STS); + saved_sci_mask &= 0xffff0000; + + /* Save CPU state */ + do_olpc_suspend_lowlevel(); + + /* Resume path starts here */ + + /* Restore SCI mask (using dword access to CS5536_PM1_EN) */ + outl(saved_sci_mask, acpi_base + CS5536_PM1_STS); + + /* Tell the EC to stop inhibiting SCIs */ + olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0); + + /* + * Tell the wireless module to restart USB communication. + * Must be done twice. + */ + olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); + olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); + + return 0; +} + +asmlinkage int xo1_do_sleep(u8 sleep_state) +{ + void *pgd_addr = __va(read_cr3()); + + /* Program wakeup mask (using dword access to CS5536_PM1_EN) */ + outl(wakeup_mask << 16, acpi_base + CS5536_PM1_STS); + + __asm__("movl %0,%%eax" : : "r" (pgd_addr)); + __asm__("call *(%%edi); cld" + : : "D" (&ofw_bios_entry)); + __asm__("movb $0x34, %al\n\t" + "outb %al, $0x70\n\t" + "movb $0x30, %al\n\t" + "outb %al, $0x71\n\t"); + return 0; +} + +static void xo1_power_off(void) +{ + printk(KERN_INFO "OLPC XO-1 power off sequence...\n"); + + /* Enable all of these controls with 0 delay */ + outl(0x40000000, pms_base + CS5536_PM_SCLK); + outl(0x40000000, pms_base + CS5536_PM_IN_SLPCTL); + outl(0x40000000, pms_base + CS5536_PM_WKXD); + outl(0x40000000, pms_base + CS5536_PM_WKD); + + /* Clear status bits (possibly unnecessary) */ + outl(0x0002ffff, pms_base + CS5536_PM_SSC); + outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS); + + /* Write SLP_EN bit to start the machinery */ + outl(0x00002000, acpi_base + CS5536_PM1_CNT); +} + +static int xo1_power_state_valid(suspend_state_t pm_state) +{ + /* suspend-to-RAM only */ + return pm_state == PM_SUSPEND_MEM; +} + +static const struct platform_suspend_ops xo1_suspend_ops = { + .valid = xo1_power_state_valid, + .enter = xo1_power_state_enter, +}; + +static int __devinit xo1_pm_probe(struct platform_device *pdev) +{ + struct resource *res; + int err; + + /* don't run on non-XOs */ + if (!machine_is_olpc()) + return -ENODEV; + + err = mfd_cell_enable(pdev); + if (err) + return err; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) { + dev_err(&pdev->dev, "can't fetch device resource info\n"); + return -EIO; + } + if (strcmp(pdev->name, "cs5535-pms") == 0) + pms_base = res->start; + else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) + acpi_base = res->start; + + /* If we have both addresses, we can override the poweroff hook */ + if (pms_base && acpi_base) { + suspend_set_ops(&xo1_suspend_ops); + pm_power_off = xo1_power_off; + printk(KERN_INFO "OLPC XO-1 support registered\n"); + } + + return 0; +} + +static int __devexit xo1_pm_remove(struct platform_device *pdev) +{ + mfd_cell_disable(pdev); + + if (strcmp(pdev->name, "cs5535-pms") == 0) + pms_base = 0; + else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) + acpi_base = 0; + + pm_power_off = NULL; + return 0; +} + +static struct platform_driver cs5535_pms_driver = { + .driver = { + .name = "cs5535-pms", + .owner = THIS_MODULE, + }, + .probe = xo1_pm_probe, + .remove = __devexit_p(xo1_pm_remove), +}; + +static struct platform_driver cs5535_acpi_driver = { + .driver = { + .name = "olpc-xo1-pm-acpi", + .owner = THIS_MODULE, + }, + .probe = xo1_pm_probe, + .remove = __devexit_p(xo1_pm_remove), +}; + +static int __init xo1_pm_init(void) +{ + int r; + + r = platform_driver_register(&cs5535_pms_driver); + if (r) + return r; + + r = platform_driver_register(&cs5535_acpi_driver); + if (r) + platform_driver_unregister(&cs5535_pms_driver); + + return r; +} +arch_initcall(xo1_pm_init); diff --git a/arch/x86/platform/olpc/olpc-xo1-rtc.c b/arch/x86/platform/olpc/olpc-xo1-rtc.c new file mode 100644 index 0000000..a2b4efd --- /dev/null +++ b/arch/x86/platform/olpc/olpc-xo1-rtc.c @@ -0,0 +1,81 @@ +/* + * Support for OLPC XO-1 Real Time Clock (RTC) + * + * Copyright (C) 2011 One Laptop per Child + * + * 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/mc146818rtc.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> +#include <linux/of.h> + +#include <asm/msr.h> +#include <asm/olpc.h> + +static void rtc_wake_on(struct device *dev) +{ + olpc_xo1_pm_wakeup_set(CS5536_PM_RTC); +} + +static void rtc_wake_off(struct device *dev) +{ + olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC); +} + +static struct resource rtc_platform_resource[] = { + [0] = { + .start = RTC_PORT(0), + .end = RTC_PORT(1), + .flags = IORESOURCE_IO, + }, + [1] = { + .start = RTC_IRQ, + .end = RTC_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct cmos_rtc_board_info rtc_info = { + .rtc_day_alarm = 0, + .rtc_mon_alarm = 0, + .rtc_century = 0, + .wake_on = rtc_wake_on, + .wake_off = rtc_wake_off, +}; + +static struct platform_device xo1_rtc_device = { + .name = "rtc_cmos", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_platform_resource), + .dev.platform_data = &rtc_info, + .resource = rtc_platform_resource, +}; + +static int __init xo1_rtc_init(void) +{ + int r; + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc"); + if (!node) + return 0; + of_node_put(node); + + pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n"); + rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm); + rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm); + rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century); + + r = platform_device_register(&xo1_rtc_device); + if (r) + return r; + + device_init_wakeup(&xo1_rtc_device.dev, 1); + return 0; +} +arch_initcall(xo1_rtc_init); diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c new file mode 100644 index 0000000..1d4c783 --- /dev/null +++ b/arch/x86/platform/olpc/olpc-xo1-sci.c @@ -0,0 +1,614 @@ +/* + * Support for OLPC XO-1 System Control Interrupts (SCI) + * + * Copyright (C) 2010 One Laptop per Child + * Copyright (C) 2006 Red Hat, Inc. + * Copyright (C) 2006 Advanced Micro Devices, Inc. + * + * 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/cs5535.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/mfd/core.h> +#include <linux/power_supply.h> +#include <linux/suspend.h> +#include <linux/workqueue.h> + +#include <asm/io.h> +#include <asm/msr.h> +#include <asm/olpc.h> + +#define DRV_NAME "olpc-xo1-sci" +#define PFX DRV_NAME ": " + +static unsigned long acpi_base; +static struct input_dev *power_button_idev; +static struct input_dev *ebook_switch_idev; +static struct input_dev *lid_switch_idev; + +static int sci_irq; + +static bool lid_open; +static bool lid_inverted; +static int lid_wake_mode; + +enum lid_wake_modes { + LID_WAKE_ALWAYS, + LID_WAKE_OPEN, + LID_WAKE_CLOSE, +}; + +static const char * const lid_wake_mode_names[] = { + [LID_WAKE_ALWAYS] = "always", + [LID_WAKE_OPEN] = "open", + [LID_WAKE_CLOSE] = "close", +}; + +static void battery_status_changed(void) +{ + struct power_supply *psy = power_supply_get_by_name("olpc-battery"); + + if (psy) { + power_supply_changed(psy); + put_device(psy->dev); + } +} + +static void ac_status_changed(void) +{ + struct power_supply *psy = power_supply_get_by_name("olpc-ac"); + + if (psy) { + power_supply_changed(psy); + put_device(psy->dev); + } +} + +/* Report current ebook switch state through input layer */ +static void send_ebook_state(void) +{ + unsigned char state; + + if (olpc_ec_cmd(EC_READ_EB_MODE, NULL, 0, &state, 1)) { + pr_err(PFX "failed to get ebook state\n"); + return; + } + + input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state); + input_sync(ebook_switch_idev); +} + +static void flip_lid_inverter(void) +{ + /* gpio is high; invert so we'll get l->h event interrupt */ + if (lid_inverted) + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT); + else + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_INPUT_INVERT); + lid_inverted = !lid_inverted; +} + +static void detect_lid_state(void) +{ + /* + * the edge detector hookup on the gpio inputs on the geode is + * odd, to say the least. See http://dev.laptop.org/ticket/5703 + * for details, but in a nutshell: we don't use the edge + * detectors. instead, we make use of an anomoly: with the both + * edge detectors turned off, we still get an edge event on a + * positive edge transition. to take advantage of this, we use the + * front-end inverter to ensure that that's the edge we're always + * going to see next. + */ + + int state; + + state = cs5535_gpio_isset(OLPC_GPIO_LID, GPIO_READ_BACK); + lid_open = !state ^ !lid_inverted; /* x ^^ y */ + if (!state) + return; + + flip_lid_inverter(); +} + +/* Report current lid switch state through input layer */ +static void send_lid_state(void) +{ + input_report_switch(lid_switch_idev, SW_LID, !lid_open); + input_sync(lid_switch_idev); +} + +static ssize_t lid_wake_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const char *mode = lid_wake_mode_names[lid_wake_mode]; + return sprintf(buf, "%s\n", mode); +} +static ssize_t lid_wake_mode_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int i; + for (i = 0; i < ARRAY_SIZE(lid_wake_mode_names); i++) { + const char *mode = lid_wake_mode_names[i]; + if (strlen(mode) != count || strncasecmp(mode, buf, count)) + continue; + + lid_wake_mode = i; + return count; + } + return -EINVAL; +} +static DEVICE_ATTR(lid_wake_mode, S_IWUSR | S_IRUGO, lid_wake_mode_show, + lid_wake_mode_set); + +/* + * Process all items in the EC's SCI queue. + * + * This is handled in a workqueue because olpc_ec_cmd can be slow (and + * can even timeout). + * + * If propagate_events is false, the queue is drained without events being + * generated for the interrupts. + */ +static void process_sci_queue(bool propagate_events) +{ + int r; + u16 data; + + do { + r = olpc_ec_sci_query(&data); + if (r || !data) + break; + + pr_debug(PFX "SCI 0x%x received\n", data); + + switch (data) { + case EC_SCI_SRC_BATERR: + case EC_SCI_SRC_BATSOC: + case EC_SCI_SRC_BATTERY: + case EC_SCI_SRC_BATCRIT: + battery_status_changed(); + break; + case EC_SCI_SRC_ACPWR: + ac_status_changed(); + break; + } + + if (data == EC_SCI_SRC_EBOOK && propagate_events) + send_ebook_state(); + } while (data); + + if (r) + pr_err(PFX "Failed to clear SCI queue"); +} + +static void process_sci_queue_work(struct work_struct *work) +{ + process_sci_queue(true); +} + +static DECLARE_WORK(sci_work, process_sci_queue_work); + +static irqreturn_t xo1_sci_intr(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + u32 sts; + u32 gpe; + + sts = inl(acpi_base + CS5536_PM1_STS); + outl(sts | 0xffff, acpi_base + CS5536_PM1_STS); + + gpe = inl(acpi_base + CS5536_PM_GPE0_STS); + outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS); + + dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe); + + if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) { + input_report_key(power_button_idev, KEY_POWER, 1); + input_sync(power_button_idev); + input_report_key(power_button_idev, KEY_POWER, 0); + input_sync(power_button_idev); + } + + if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */ + cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS); + schedule_work(&sci_work); + } + + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS); + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS); + detect_lid_state(); + send_lid_state(); + + return IRQ_HANDLED; +} + +static int xo1_sci_suspend(struct platform_device *pdev, pm_message_t state) +{ + if (device_may_wakeup(&power_button_idev->dev)) + olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN); + else + olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN); + + if (device_may_wakeup(&ebook_switch_idev->dev)) + olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK); + else + olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK); + + if (!device_may_wakeup(&lid_switch_idev->dev)) { + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE); + } else if ((lid_open && lid_wake_mode == LID_WAKE_OPEN) || + (!lid_open && lid_wake_mode == LID_WAKE_CLOSE)) { + flip_lid_inverter(); + + /* we may have just caused an event */ + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS); + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS); + + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE); + } + + return 0; +} + +static int xo1_sci_resume(struct platform_device *pdev) +{ + /* + * We don't know what may have happened while we were asleep. + * Reestablish our lid setup so we're sure to catch all transitions. + */ + detect_lid_state(); + send_lid_state(); + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE); + + /* Enable all EC events */ + olpc_ec_mask_write(EC_SCI_SRC_ALL); + + /* Power/battery status might have changed too */ + battery_status_changed(); + ac_status_changed(); + return 0; +} + +static int __devinit setup_sci_interrupt(struct platform_device *pdev) +{ + u32 lo, hi; + u32 sts; + int r; + + rdmsr(0x51400020, lo, hi); + sci_irq = (lo >> 20) & 15; + + if (sci_irq) { + dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq); + } else { + /* Zero means masked */ + dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n"); + sci_irq = 3; + lo |= 0x00300000; + wrmsrl(0x51400020, lo); + } + + /* Select level triggered in PIC */ + if (sci_irq < 8) { + lo = inb(CS5536_PIC_INT_SEL1); + lo |= 1 << sci_irq; + outb(lo, CS5536_PIC_INT_SEL1); + } else { + lo = inb(CS5536_PIC_INT_SEL2); + lo |= 1 << (sci_irq - 8); + outb(lo, CS5536_PIC_INT_SEL2); + } + + /* Enable SCI from power button, and clear pending interrupts */ + sts = inl(acpi_base + CS5536_PM1_STS); + outl((CS5536_PM_PWRBTN << 16) | 0xffff, acpi_base + CS5536_PM1_STS); + + r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev); + if (r) + dev_err(&pdev->dev, "can't request interrupt\n"); + + return r; +} + +static int __devinit setup_ec_sci(void) +{ + int r; + + r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI"); + if (r) + return r; + + gpio_direction_input(OLPC_GPIO_ECSCI); + + /* Clear pending EC SCI events */ + cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS); + cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS); + + /* + * Enable EC SCI events, and map them to both a PME and the SCI + * interrupt. + * + * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can + * be mapped to regular interrupts *or* Geode-specific Power + * Management Events (PMEs) - events that bring the system out of + * suspend. In this case, we want both of those things - the system + * wakeup, *and* the ability to get an interrupt when an event occurs. + * + * To achieve this, we map the GPIO to a PME, and then we use one + * of the many generic knobs on the CS5535 PIC to additionally map the + * PME to the regular SCI interrupt line. + */ + cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE); + + /* Set the SCI to cause a PME event on group 7 */ + cs5535_gpio_setup_event(OLPC_GPIO_ECSCI, 7, 1); + + /* And have group 7 also fire the SCI interrupt */ + cs5535_pic_unreqz_select_high(7, sci_irq); + + return 0; +} + +static void free_ec_sci(void) +{ + gpio_free(OLPC_GPIO_ECSCI); +} + +static int __devinit setup_lid_events(void) +{ + int r; + + r = gpio_request(OLPC_GPIO_LID, "OLPC-LID"); + if (r) + return r; + + gpio_direction_input(OLPC_GPIO_LID); + + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT); + lid_inverted = 0; + + /* Clear edge detection and event enable for now */ + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE); + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN); + cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN); + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS); + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS); + + /* Set the LID to cause an PME event on group 6 */ + cs5535_gpio_setup_event(OLPC_GPIO_LID, 6, 1); + + /* Set PME group 6 to fire the SCI interrupt */ + cs5535_gpio_set_irq(6, sci_irq); + + /* Enable the event */ + cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE); + + return 0; +} + +static void free_lid_events(void) +{ + gpio_free(OLPC_GPIO_LID); +} + +static int __devinit setup_power_button(struct platform_device *pdev) +{ + int r; + + power_button_idev = input_allocate_device(); + if (!power_button_idev) + return -ENOMEM; + + power_button_idev->name = "Power Button"; + power_button_idev->phys = DRV_NAME "/input0"; + set_bit(EV_KEY, power_button_idev->evbit); + set_bit(KEY_POWER, power_button_idev->keybit); + + power_button_idev->dev.parent = &pdev->dev; + device_init_wakeup(&power_button_idev->dev, 1); + + r = input_register_device(power_button_idev); + if (r) { + dev_err(&pdev->dev, "failed to register power button: %d\n", r); + input_free_device(power_button_idev); + } + + return r; +} + +static void free_power_button(void) +{ + input_unregister_device(power_button_idev); + input_free_device(power_button_idev); +} + +static int __devinit setup_ebook_switch(struct platform_device *pdev) +{ + int r; + + ebook_switch_idev = input_allocate_device(); + if (!ebook_switch_idev) + return -ENOMEM; + + ebook_switch_idev->name = "EBook Switch"; + ebook_switch_idev->phys = DRV_NAME "/input1"; + set_bit(EV_SW, ebook_switch_idev->evbit); + set_bit(SW_TABLET_MODE, ebook_switch_idev->swbit); + + ebook_switch_idev->dev.parent = &pdev->dev; + device_set_wakeup_capable(&ebook_switch_idev->dev, true); + + r = input_register_device(ebook_switch_idev); + if (r) { + dev_err(&pdev->dev, "failed to register ebook switch: %d\n", r); + input_free_device(ebook_switch_idev); + } + + return r; +} + +static void free_ebook_switch(void) +{ + input_unregister_device(ebook_switch_idev); + input_free_device(ebook_switch_idev); +} + +static int __devinit setup_lid_switch(struct platform_device *pdev) +{ + int r; + + lid_switch_idev = input_allocate_device(); + if (!lid_switch_idev) + return -ENOMEM; + + lid_switch_idev->name = "Lid Switch"; + lid_switch_idev->phys = DRV_NAME "/input2"; + set_bit(EV_SW, lid_switch_idev->evbit); + set_bit(SW_LID, lid_switch_idev->swbit); + + lid_switch_idev->dev.parent = &pdev->dev; + device_set_wakeup_capable(&lid_switch_idev->dev, true); + + r = input_register_device(lid_switch_idev); + if (r) { + dev_err(&pdev->dev, "failed to register lid switch: %d\n", r); + goto err_register; + } + + r = device_create_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode); + if (r) { + dev_err(&pdev->dev, "failed to create wake mode attr: %d\n", r); + goto err_create_attr; + } + + return 0; + +err_create_attr: + input_unregister_device(lid_switch_idev); +err_register: + input_free_device(lid_switch_idev); + return r; +} + +static void free_lid_switch(void) +{ + device_remove_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode); + input_unregister_device(lid_switch_idev); + input_free_device(lid_switch_idev); +} + +static int __devinit xo1_sci_probe(struct platform_device *pdev) +{ + struct resource *res; + int r; + + /* don't run on non-XOs */ + if (!machine_is_olpc()) + return -ENODEV; + + r = mfd_cell_enable(pdev); + if (r) + return r; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) { + dev_err(&pdev->dev, "can't fetch device resource info\n"); + return -EIO; + } + acpi_base = res->start; + + r = setup_power_button(pdev); + if (r) + return r; + + r = setup_ebook_switch(pdev); + if (r) + goto err_ebook; + + r = setup_lid_switch(pdev); + if (r) + goto err_lid; + + r = setup_lid_events(); + if (r) + goto err_lidevt; + + r = setup_ec_sci(); + if (r) + goto err_ecsci; + + /* Enable PME generation for EC-generated events */ + outl(CS5536_GPIOM6_PME_EN | CS5536_GPIOM7_PME_EN, + acpi_base + CS5536_PM_GPE0_EN); + + /* Clear pending events */ + outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS); + process_sci_queue(false); + + /* Initial sync */ + send_ebook_state(); + detect_lid_state(); + send_lid_state(); + + r = setup_sci_interrupt(pdev); + if (r) + goto err_sci; + + /* Enable all EC events */ + olpc_ec_mask_write(EC_SCI_SRC_ALL); + + return r; + +err_sci: + free_ec_sci(); +err_ecsci: + free_lid_events(); +err_lidevt: + free_lid_switch(); +err_lid: + free_ebook_switch(); +err_ebook: + free_power_button(); + return r; +} + +static int __devexit xo1_sci_remove(struct platform_device *pdev) +{ + mfd_cell_disable(pdev); + free_irq(sci_irq, pdev); + cancel_work_sync(&sci_work); + free_ec_sci(); + free_lid_events(); + free_lid_switch(); + free_ebook_switch(); + free_power_button(); + acpi_base = 0; + return 0; +} + +static struct platform_driver xo1_sci_driver = { + .driver = { + .name = "olpc-xo1-sci-acpi", + }, + .probe = xo1_sci_probe, + .remove = __devexit_p(xo1_sci_remove), + .suspend = xo1_sci_suspend, + .resume = xo1_sci_resume, +}; + +static int __init xo1_sci_init(void) +{ + return platform_driver_register(&xo1_sci_driver); +} +arch_initcall(xo1_sci_init); diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c deleted file mode 100644 index ab81fb2..0000000 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Support for features of the OLPC XO-1 laptop - * - * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> - * Copyright (C) 2010 One Laptop per Child - * Copyright (C) 2006 Red Hat, Inc. - * Copyright (C) 2006 Advanced Micro Devices, Inc. - * - * 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/module.h> -#include <linux/platform_device.h> -#include <linux/pm.h> -#include <linux/mfd/core.h> - -#include <asm/io.h> -#include <asm/olpc.h> - -#define DRV_NAME "olpc-xo1" - -/* PMC registers (PMS block) */ -#define PM_SCLK 0x10 -#define PM_IN_SLPCTL 0x20 -#define PM_WKXD 0x34 -#define PM_WKD 0x30 -#define PM_SSC 0x54 - -/* PM registers (ACPI block) */ -#define PM1_CNT 0x08 -#define PM_GPE0_STS 0x18 - -static unsigned long acpi_base; -static unsigned long pms_base; - -static void xo1_power_off(void) -{ - printk(KERN_INFO "OLPC XO-1 power off sequence...\n"); - - /* Enable all of these controls with 0 delay */ - outl(0x40000000, pms_base + PM_SCLK); - outl(0x40000000, pms_base + PM_IN_SLPCTL); - outl(0x40000000, pms_base + PM_WKXD); - outl(0x40000000, pms_base + PM_WKD); - - /* Clear status bits (possibly unnecessary) */ - outl(0x0002ffff, pms_base + PM_SSC); - outl(0xffffffff, acpi_base + PM_GPE0_STS); - - /* Write SLP_EN bit to start the machinery */ - outl(0x00002000, acpi_base + PM1_CNT); -} - -static int __devinit olpc_xo1_probe(struct platform_device *pdev) -{ - struct resource *res; - int err; - - /* don't run on non-XOs */ - if (!machine_is_olpc()) - return -ENODEV; - - err = mfd_cell_enable(pdev); - if (err) - return err; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); - return -EIO; - } - if (strcmp(pdev->name, "cs5535-pms") == 0) - pms_base = res->start; - else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) - acpi_base = res->start; - - /* If we have both addresses, we can override the poweroff hook */ - if (pms_base && acpi_base) { - pm_power_off = xo1_power_off; - printk(KERN_INFO "OLPC XO-1 support registered\n"); - } - - return 0; -} - -static int __devexit olpc_xo1_remove(struct platform_device *pdev) -{ - mfd_cell_disable(pdev); - - if (strcmp(pdev->name, "cs5535-pms") == 0) - pms_base = 0; - else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) - acpi_base = 0; - - pm_power_off = NULL; - return 0; -} - -static struct platform_driver cs5535_pms_drv = { - .driver = { - .name = "cs5535-pms", - .owner = THIS_MODULE, - }, - .probe = olpc_xo1_probe, - .remove = __devexit_p(olpc_xo1_remove), -}; - -static struct platform_driver cs5535_acpi_drv = { - .driver = { - .name = "olpc-xo1-pm-acpi", - .owner = THIS_MODULE, - }, - .probe = olpc_xo1_probe, - .remove = __devexit_p(olpc_xo1_remove), -}; - -static int __init olpc_xo1_init(void) -{ - int r; - - r = platform_driver_register(&cs5535_pms_drv); - if (r) - return r; - - r = platform_driver_register(&cs5535_acpi_drv); - if (r) - platform_driver_unregister(&cs5535_pms_drv); - - return r; -} - -static void __exit olpc_xo1_exit(void) -{ - platform_driver_unregister(&cs5535_acpi_drv); - platform_driver_unregister(&cs5535_pms_drv); -} - -MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:cs5535-pms"); - -module_init(olpc_xo1_init); -module_exit(olpc_xo1_exit); diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c new file mode 100644 index 0000000..2b235b7 --- /dev/null +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -0,0 +1,168 @@ +/* + * Support for OLPC XO-1.5 System Control Interrupts (SCI) + * + * Copyright (C) 2009-2010 One Laptop per Child + * + * 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/device.h> +#include <linux/slab.h> +#include <linux/workqueue.h> +#include <linux/power_supply.h> + +#include <acpi/acpi_bus.h> +#include <acpi/acpi_drivers.h> +#include <asm/olpc.h> + +#define DRV_NAME "olpc-xo15-sci" +#define PFX DRV_NAME ": " +#define XO15_SCI_CLASS DRV_NAME +#define XO15_SCI_DEVICE_NAME "OLPC XO-1.5 SCI" + +static unsigned long xo15_sci_gpe; + +static void battery_status_changed(void) +{ + struct power_supply *psy = power_supply_get_by_name("olpc-battery"); + + if (psy) { + power_supply_changed(psy); + put_device(psy->dev); + } +} + +static void ac_status_changed(void) +{ + struct power_supply *psy = power_supply_get_by_name("olpc-ac"); + + if (psy) { + power_supply_changed(psy); + put_device(psy->dev); + } +} + +static void process_sci_queue(void) +{ + u16 data; + int r; + + do { + r = olpc_ec_sci_query(&data); + if (r || !data) + break; + + pr_debug(PFX "SCI 0x%x received\n", data); + + switch (data) { + case EC_SCI_SRC_BATERR: + case EC_SCI_SRC_BATSOC: + case EC_SCI_SRC_BATTERY: + case EC_SCI_SRC_BATCRIT: + battery_status_changed(); + break; + case EC_SCI_SRC_ACPWR: + ac_status_changed(); + break; + } + } while (data); + + if (r) + pr_err(PFX "Failed to clear SCI queue"); +} + +static void process_sci_queue_work(struct work_struct *work) +{ + process_sci_queue(); +} + +static DECLARE_WORK(sci_work, process_sci_queue_work); + +static u32 xo15_sci_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context) +{ + schedule_work(&sci_work); + return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; +} + +static int xo15_sci_add(struct acpi_device *device) +{ + unsigned long long tmp; + acpi_status status; + + if (!device) + return -EINVAL; + + strcpy(acpi_device_name(device), XO15_SCI_DEVICE_NAME); + strcpy(acpi_device_class(device), XO15_SCI_CLASS); + + /* Get GPE bit assignment (EC events). */ + status = acpi_evaluate_integer(device->handle, "_GPE", NULL, &tmp); + if (ACPI_FAILURE(status)) + return -EINVAL; + + xo15_sci_gpe = tmp; + status = acpi_install_gpe_handler(NULL, xo15_sci_gpe, + ACPI_GPE_EDGE_TRIGGERED, + xo15_sci_gpe_handler, device); + if (ACPI_FAILURE(status)) + return -ENODEV; + + dev_info(&device->dev, "Initialized, GPE = 0x%lx\n", xo15_sci_gpe); + + /* Flush queue, and enable all SCI events */ + process_sci_queue(); + olpc_ec_mask_write(EC_SCI_SRC_ALL); + + acpi_enable_gpe(NULL, xo15_sci_gpe); + + /* Enable wake-on-EC */ + if (device->wakeup.flags.valid) + device_init_wakeup(&device->dev, true); + + return 0; +} + +static int xo15_sci_remove(struct acpi_device *device, int type) +{ + acpi_disable_gpe(NULL, xo15_sci_gpe); + acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); + cancel_work_sync(&sci_work); + return 0; +} + +static int xo15_sci_resume(struct acpi_device *device) +{ + /* Enable all EC events */ + olpc_ec_mask_write(EC_SCI_SRC_ALL); + + /* Power/battery status might have changed */ + battery_status_changed(); + ac_status_changed(); + + return 0; +} + +static const struct acpi_device_id xo15_sci_device_ids[] = { + {"XO15EC", 0}, + {"", 0}, +}; + +static struct acpi_driver xo15_sci_drv = { + .name = DRV_NAME, + .class = XO15_SCI_CLASS, + .ids = xo15_sci_device_ids, + .ops = { + .add = xo15_sci_add, + .remove = xo15_sci_remove, + .resume = xo15_sci_resume, + }, +}; + +static int __init xo15_sci_init(void) +{ + return acpi_bus_register_driver(&xo15_sci_drv); +} +device_initcall(xo15_sci_init); diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c index 0060fd5..7cce722 100644 --- a/arch/x86/platform/olpc/olpc.c +++ b/arch/x86/platform/olpc/olpc.c @@ -19,6 +19,7 @@ #include <linux/string.h> #include <linux/platform_device.h> #include <linux/of.h> +#include <linux/syscore_ops.h> #include <asm/geode.h> #include <asm/setup.h> @@ -30,6 +31,9 @@ EXPORT_SYMBOL_GPL(olpc_platform_info); static DEFINE_SPINLOCK(ec_lock); +/* EC event mask to be applied during suspend (defining wakeup sources). */ +static u16 ec_wakeup_mask; + /* what the timeout *should* be (in ms) */ #define EC_BASE_TIMEOUT 20 @@ -157,13 +161,13 @@ restart: if (inbuf && inlen) { /* write data to EC */ for (i = 0; i < inlen; i++) { + pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); + outb(inbuf[i], 0x68); if (wait_on_ibf(0x6c, 0)) { printk(KERN_ERR "olpc-ec: timeout waiting for" " EC accept data!\n"); goto err; } - pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); - outb(inbuf[i], 0x68); } } if (outbuf && outlen) { @@ -188,6 +192,88 @@ err: } EXPORT_SYMBOL_GPL(olpc_ec_cmd); +void olpc_ec_wakeup_set(u16 value) +{ + ec_wakeup_mask |= value; +} +EXPORT_SYMBOL_GPL(olpc_ec_wakeup_set); + +void olpc_ec_wakeup_clear(u16 value) +{ + ec_wakeup_mask &= ~value; +} +EXPORT_SYMBOL_GPL(olpc_ec_wakeup_clear); + +/* + * Returns true if the compile and runtime configurations allow for EC events + * to wake the system. + */ +bool olpc_ec_wakeup_available(void) +{ + if (!machine_is_olpc()) + return false; + + /* + * XO-1 EC wakeups are available when olpc-xo1-sci driver is + * compiled in + */ +#ifdef CONFIG_OLPC_XO1_SCI + if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */ + return true; +#endif + + /* + * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is + * compiled in + */ +#ifdef CONFIG_OLPC_XO15_SCI + if (olpc_platform_info.boardrev >= olpc_board_pre(0xd0)) /* XO-1.5 */ + return true; +#endif + + return false; +} +EXPORT_SYMBOL_GPL(olpc_ec_wakeup_available); + +int olpc_ec_mask_write(u16 bits) +{ + if (olpc_platform_info.flags & OLPC_F_EC_WIDE_SCI) { + __be16 ec_word = cpu_to_be16(bits); + return olpc_ec_cmd(EC_WRITE_EXT_SCI_MASK, (void *) &ec_word, 2, + NULL, 0); + } else { + unsigned char ec_byte = bits & 0xff; + return olpc_ec_cmd(EC_WRITE_SCI_MASK, &ec_byte, 1, NULL, 0); + } +} +EXPORT_SYMBOL_GPL(olpc_ec_mask_write); + +int olpc_ec_sci_query(u16 *sci_value) +{ + int ret; + + if (olpc_platform_info.flags & OLPC_F_EC_WIDE_SCI) { + __be16 ec_word; + ret = olpc_ec_cmd(EC_EXT_SCI_QUERY, + NULL, 0, (void *) &ec_word, 2); + if (ret == 0) + *sci_value = be16_to_cpu(ec_word); + } else { + unsigned char ec_byte; + ret = olpc_ec_cmd(EC_SCI_QUERY, NULL, 0, &ec_byte, 1); + if (ret == 0) + *sci_value = ec_byte; + } + + return ret; +} +EXPORT_SYMBOL_GPL(olpc_ec_sci_query); + +static int olpc_ec_suspend(void) +{ + return olpc_ec_mask_write(ec_wakeup_mask); +} + static bool __init check_ofw_architecture(struct device_node *root) { const char *olpc_arch; @@ -242,6 +328,10 @@ static int __init add_xo1_platform_devices(void) return 0; } +static struct syscore_ops olpc_syscore_ops = { + .suspend = olpc_ec_suspend, +}; + static int __init olpc_init(void) { int r = 0; @@ -266,6 +356,9 @@ static int __init olpc_init(void) !cs5535_has_vsa2()) x86_init.pci.arch_init = pci_olpc_init; #endif + /* EC version 0x5f adds support for wide SCI mask */ + if (olpc_platform_info.ecver >= 0x5f) + olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n", ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", @@ -278,6 +371,8 @@ static int __init olpc_init(void) return r; } + register_syscore_ops(&olpc_syscore_ops); + return 0; } diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c index d39f63d..d6ee929 100644 --- a/arch/x86/platform/olpc/olpc_dt.c +++ b/arch/x86/platform/olpc/olpc_dt.c @@ -165,6 +165,107 @@ static struct of_pdt_ops prom_olpc_ops __initdata = { .pkg2path = olpc_dt_pkg2path, }; +static phandle __init olpc_dt_finddevice(const char *path) +{ + phandle node; + const void *args[] = { path }; + void *res[] = { &node }; + + if (olpc_ofw("finddevice", args, res)) { + pr_err("olpc_dt: finddevice failed!\n"); + return 0; + } + + if ((s32) node == -1) + return 0; + + return node; +} + +static int __init olpc_dt_interpret(const char *words) +{ + int result; + const void *args[] = { words }; + void *res[] = { &result }; + + if (olpc_ofw("interpret", args, res)) { + pr_err("olpc_dt: interpret failed!\n"); + return -1; + } + + return result; +} + +/* + * Extract board revision directly from OFW device tree. + * We can't use olpc_platform_info because that hasn't been set up yet. + */ +static u32 __init olpc_dt_get_board_revision(void) +{ + phandle node; + __be32 rev; + int r; + + node = olpc_dt_finddevice("/"); + if (!node) + return 0; + + r = olpc_dt_getproperty(node, "board-revision-int", + (char *) &rev, sizeof(rev)); + if (r < 0) + return 0; + + return be32_to_cpu(rev); +} + +void __init olpc_dt_fixup(void) +{ + int r; + char buf[64]; + phandle node; + u32 board_rev; + + node = olpc_dt_finddevice("/battery@0"); + if (!node) + return; + + /* + * If the battery node has a compatible property, we are running a new + * enough firmware and don't have fixups to make. + */ + r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf)); + if (r > 0) + return; + + pr_info("PROM DT: Old firmware detected, applying fixes\n"); + + /* Add olpc,xo1-battery compatible marker to battery node */ + olpc_dt_interpret("\" /battery@0\" find-device" + " \" olpc,xo1-battery\" +compatible" + " device-end"); + + board_rev = olpc_dt_get_board_revision(); + if (!board_rev) + return; + + if (board_rev >= olpc_board_pre(0xd0)) { + /* XO-1.5: add dcon device */ + olpc_dt_interpret("\" /pci/display@1\" find-device" + " new-device" + " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" + " finish-device device-end"); + } else { + /* XO-1: add dcon device, mark RTC as olpc,xo1-rtc */ + olpc_dt_interpret("\" /pci/display@1,1\" find-device" + " new-device" + " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" + " finish-device device-end" + " \" /rtc\" find-device" + " \" olpc,xo1-rtc\" +compatible" + " device-end"); + } +} + void __init olpc_dt_build_devicetree(void) { phandle root; @@ -172,6 +273,8 @@ void __init olpc_dt_build_devicetree(void) if (!olpc_ofw_is_installed()) return; + olpc_dt_fixup(); + root = olpc_dt_getsibling(0); if (!root) { pr_err("PROM: unable to get root node from OFW!\n"); diff --git a/arch/x86/platform/olpc/xo1-wakeup.S b/arch/x86/platform/olpc/xo1-wakeup.S new file mode 100644 index 0000000..948deb2 --- /dev/null +++ b/arch/x86/platform/olpc/xo1-wakeup.S @@ -0,0 +1,124 @@ +.text +#include <linux/linkage.h> +#include <asm/segment.h> +#include <asm/page.h> +#include <asm/pgtable_32.h> + + .macro writepost,value + movb $0x34, %al + outb %al, $0x70 + movb $\value, %al + outb %al, $0x71 + .endm + +wakeup_start: + # OFW lands us here, running in protected mode, with a + # kernel-compatible GDT already setup. + + # Clear any dangerous flags + pushl $0 + popfl + + writepost 0x31 + + # Set up %cr3 + movl $initial_page_table - __PAGE_OFFSET, %eax + movl %eax, %cr3 + + movl saved_cr4, %eax + movl %eax, %cr4 + + movl saved_cr0, %eax + movl %eax, %cr0 + + # Control registers were modified, pipeline resync is needed + jmp 1f +1: + + movw $__KERNEL_DS, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + lgdt saved_gdt + lidt saved_idt + lldt saved_ldt + ljmp $(__KERNEL_CS),$1f +1: + movl %cr3, %eax + movl %eax, %cr3 + wbinvd + + # Go back to the return point + jmp ret_point + +save_registers: + sgdt saved_gdt + sidt saved_idt + sldt saved_ldt + + pushl %edx + movl %cr4, %edx + movl %edx, saved_cr4 + + movl %cr0, %edx + movl %edx, saved_cr0 + + popl %edx + + movl %ebx, saved_context_ebx + movl %ebp, saved_context_ebp + movl %esi, saved_context_esi + movl %edi, saved_context_edi + + pushfl + popl saved_context_eflags + + ret + +restore_registers: + movl saved_context_ebp, %ebp + movl saved_context_ebx, %ebx + movl saved_context_esi, %esi + movl saved_context_edi, %edi + + pushl saved_context_eflags + popfl + + ret + +ENTRY(do_olpc_suspend_lowlevel) + call save_processor_state + call save_registers + + # This is the stack context we want to remember + movl %esp, saved_context_esp + + pushl $3 + call xo1_do_sleep + + jmp wakeup_start + .p2align 4,,7 +ret_point: + movl saved_context_esp, %esp + + writepost 0x32 + + call restore_registers + call restore_processor_state + ret + +.data +saved_gdt: .long 0,0 +saved_idt: .long 0,0 +saved_ldt: .long 0 +saved_cr4: .long 0 +saved_cr0: .long 0 +saved_context_esp: .long 0 +saved_context_edi: .long 0 +saved_context_esi: .long 0 +saved_context_ebx: .long 0 +saved_context_ebp: .long 0 +saved_context_eflags: .long 0 diff --git a/arch/x86/vdso/vdso.S b/arch/x86/vdso/vdso.S index 1b979c1..01f5e3b 100644 --- a/arch/x86/vdso/vdso.S +++ b/arch/x86/vdso/vdso.S @@ -9,6 +9,7 @@ __PAGE_ALIGNED_DATA vdso_start: .incbin "arch/x86/vdso/vdso.so" vdso_end: + .align PAGE_SIZE /* extra data here leaks to userspace. */ .previous diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S index e2800af..e354bce 100644 --- a/arch/x86/vdso/vdso32/sysenter.S +++ b/arch/x86/vdso/vdso32/sysenter.S @@ -43,7 +43,7 @@ __kernel_vsyscall: .space 7,0x90 /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ - jmp .Lenter_kernel + int $0x80 /* 16: System call normal return point is here! */ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ pop %ebp diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index ccf73b2..add2c2d 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -13,7 +13,9 @@ CFLAGS_mmu.o := $(nostackp) obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ time.o xen-asm.o xen-asm_$(BITS).o \ grant-table.o suspend.o platform-pci-unplug.o \ - p2m.o trace.o + p2m.o + +obj-$(CONFIG_EVENT_TRACING) += trace.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 974a528..2d69617 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -77,8 +77,8 @@ EXPORT_SYMBOL_GPL(xen_domain_type); unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; EXPORT_SYMBOL(machine_to_phys_mapping); -unsigned int machine_to_phys_order; -EXPORT_SYMBOL(machine_to_phys_order); +unsigned long machine_to_phys_nr; +EXPORT_SYMBOL(machine_to_phys_nr); struct start_info *xen_start_info; EXPORT_SYMBOL_GPL(xen_start_info); @@ -951,6 +951,10 @@ static const struct pv_info xen_info __initconst = { .paravirt_enabled = 1, .shared_kernel_pmd = 0, +#ifdef CONFIG_X86_64 + .extra_user_64bit_cs = FLAT_USER_CS64, +#endif + .name = "Xen", }; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index f987bde..20a6142 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1713,15 +1713,19 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) void __init xen_setup_machphys_mapping(void) { struct xen_machphys_mapping mapping; - unsigned long machine_to_phys_nr_ents; if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { machine_to_phys_mapping = (unsigned long *)mapping.v_start; - machine_to_phys_nr_ents = mapping.max_mfn + 1; + machine_to_phys_nr = mapping.max_mfn + 1; } else { - machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; + machine_to_phys_nr = MACH2PHYS_NR_ENTRIES; } - machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); +#ifdef CONFIG_X86_32 + if ((machine_to_phys_mapping + machine_to_phys_nr) + < machine_to_phys_mapping) + machine_to_phys_nr = (unsigned long *)NULL + - machine_to_phys_mapping; +#endif } #ifdef CONFIG_X86_64 @@ -1916,6 +1920,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) # endif #else case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: + case VVAR_PAGE: #endif case FIX_TEXT_POKE0: case FIX_TEXT_POKE1: @@ -1956,7 +1961,8 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) #ifdef CONFIG_X86_64 /* Replicate changes to map the vsyscall page into the user pagetable vsyscall mapping. */ - if (idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) { + if ((idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) || + idx == VVAR_PAGE) { unsigned long vaddr = __fix_to_virt(idx); set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte); } diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 60aeeb5..c3b8d44 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -9,6 +9,7 @@ #include <linux/mm.h> #include <linux/pm.h> #include <linux/memblock.h> +#include <linux/cpuidle.h> #include <asm/elf.h> #include <asm/vdso.h> @@ -92,8 +93,6 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, if (end <= start) return 0; - printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ", - start, end); for(pfn = start; pfn < end; pfn++) { unsigned long mfn = pfn_to_mfn(pfn); @@ -106,14 +105,14 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); - WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", - start, end, ret); + WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); if (ret == 1) { __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); len++; } } - printk(KERN_CONT "%ld pages freed\n", len); + printk(KERN_INFO "Freeing %lx-%lx pfn range: %lu pages freed\n", + start, end, len); return len; } @@ -139,7 +138,7 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, if (last_end < max_addr) released += xen_release_chunk(last_end, max_addr); - printk(KERN_INFO "released %ld pages of unused memory\n", released); + printk(KERN_INFO "released %lu pages of unused memory\n", released); return released; } @@ -185,6 +184,19 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, PFN_UP(start_pci), PFN_DOWN(last)); return identity; } + +static unsigned long __init xen_get_max_pages(void) +{ + unsigned long max_pages = MAX_DOMAIN_PAGES; + domid_t domid = DOMID_SELF; + int ret; + + ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); + if (ret > 0) + max_pages = ret; + return min(max_pages, MAX_DOMAIN_PAGES); +} + /** * machine_specific_memory_setup - Hook for machine specific memory setup. **/ @@ -293,6 +305,12 @@ char * __init xen_memory_setup(void) sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); + extra_limit = xen_get_max_pages(); + if (extra_limit >= max_pfn) + extra_pages = extra_limit - max_pfn; + else + extra_pages = 0; + extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); /* @@ -426,7 +444,7 @@ void __init xen_arch_setup(void) #ifdef CONFIG_X86_32 boot_cpu_data.hlt_works_ok = 1; #endif - pm_idle = default_idle; + disable_cpuidle(); boot_option_idle_override = IDLE_HALT; fiddle_vdso(); diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index b4533a8..d4fc6d4 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -32,6 +32,7 @@ #include <xen/page.h> #include <xen/events.h> +#include <xen/hvc-console.h> #include "xen-ops.h" #include "mmu.h" @@ -207,6 +208,15 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) unsigned cpu; unsigned int i; + if (skip_ioapic_setup) { + char *m = (max_cpus == 0) ? + "The nosmp parameter is incompatible with Xen; " \ + "use Xen dom0_max_vcpus=1 parameter" : + "The noapic parameter is incompatible with Xen"; + + xen_raw_printk(m); + panic(m); + } xen_init_lock_cpu(0); smp_store_cpu_info(0); @@ -521,8 +531,6 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) native_smp_prepare_cpus(max_cpus); WARN_ON(xen_smp_intr_init(0)); - if (!xen_have_vector_callback) - return; xen_init_lock_cpu(0); xen_init_spinlocks(); } @@ -546,6 +554,8 @@ static void xen_hvm_cpu_die(unsigned int cpu) void __init xen_hvm_smp_init(void) { + if (!xen_have_vector_callback) + return; smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; smp_ops.smp_send_reschedule = xen_smp_send_reschedule; smp_ops.cpu_up = xen_hvm_cpu_up; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 5158c50..163b467 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -168,9 +168,10 @@ cycle_t xen_clocksource_read(void) struct pvclock_vcpu_time_info *src; cycle_t ret; - src = &get_cpu_var(xen_vcpu)->time; + preempt_disable_notrace(); + src = &__get_cpu_var(xen_vcpu)->time; ret = pvclock_clocksource_read(src); - put_cpu_var(xen_vcpu); + preempt_enable_notrace(); return ret; } diff --git a/arch/x86/xen/trace.c b/arch/x86/xen/trace.c index 734beba..520022d 100644 --- a/arch/x86/xen/trace.c +++ b/arch/x86/xen/trace.c @@ -1,4 +1,5 @@ #include <linux/ftrace.h> +#include <xen/interface/xen.h> #define N(x) [__HYPERVISOR_##x] = "("#x")" static const char *xen_hypercall_names[] = { diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S index 22a2093..b040b0e 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S @@ -113,11 +113,13 @@ xen_iret_start_crit: /* * If there's something pending, mask events again so we can - * jump back into xen_hypervisor_callback + * jump back into xen_hypervisor_callback. Otherwise do not + * touch XEN_vcpu_info_mask. */ - sete XEN_vcpu_info_mask(%eax) + jne 1f + movb $1, XEN_vcpu_info_mask(%eax) - popl %eax +1: popl %eax /* * From this point on the registers are restored and the stack diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index a96a061..23592ef 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -225,15 +225,15 @@ static inline int atomic_sub_return(int i, atomic_t * v) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t * @a: the amount to add to v... * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -245,10 +245,9 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) break; c = old; } - return c != (u); + return c; } -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { @@ -292,7 +291,6 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() -#include <asm-generic/atomic-long.h> #endif /* __KERNEL__ */ #endif /* _XTENSA_ATOMIC_H */ diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index c8fac8d..40aa7fe 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@ -108,19 +108,7 @@ static inline unsigned long __fls(unsigned long word) #include <asm-generic/bitops/find.h> #include <asm-generic/bitops/le.h> -#ifdef __XTENSA_EL__ -# define ext2_set_bit_atomic(lock,nr,addr) \ - test_and_set_bit((nr), (unsigned long*)(addr)) -# define ext2_clear_bit_atomic(lock,nr,addr) \ - test_and_clear_bit((nr), (unsigned long*)(addr)) -#elif defined(__XTENSA_EB__) -# define ext2_set_bit_atomic(lock,nr,addr) \ - test_and_set_bit((nr) ^ 0x18, (unsigned long*)(addr)) -# define ext2_clear_bit_atomic(lock,nr,addr) \ - test_and_clear_bit((nr) ^ 0x18, (unsigned long*)(addr)) -#else -# error processor byte order undefined! -#endif +#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/hweight.h> #include <asm-generic/bitops/lock.h> diff --git a/arch/xtensa/include/asm/posix_types.h b/arch/xtensa/include/asm/posix_types.h index 43f9dd1..6b2190c 100644 --- a/arch/xtensa/include/asm/posix_types.h +++ b/arch/xtensa/include/asm/posix_types.h @@ -58,7 +58,7 @@ typedef struct { #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) #define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) #define __FD_ZERO(set) \ ((void) memset ((void *) (set), 0, sizeof (__kernel_fd_set))) diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 0d42c93..d85d38d 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -120,7 +120,6 @@ struct pt_regs { (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) # define instruction_pointer(regs) ((regs)->pc) -extern void show_regs(struct pt_regs *); # ifndef CONFIG_SMP # define profile_pc(regs) instruction_pointer(regs) diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index a6f934f..798ee6d 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h @@ -455,7 +455,7 @@ __SYSCALL(203, sys_reboot, 3) #define __NR_quotactl 204 __SYSCALL(204, sys_quotactl, 4) #define __NR_nfsservctl 205 -__SYSCALL(205, sys_nfsservctl, 3) +__SYSCALL(205, sys_ni_syscall, 0) #define __NR__sysctl 206 __SYSCALL(206, sys_sysctl, 1) #define __NR_bdflush 207 diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index e3558b9..47041e7 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -40,7 +40,7 @@ #include <asm/platform.h> #include <asm/mmu.h> #include <asm/irq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/asm-offsets.h> #include <asm/regs.h> |