diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-04-29 09:36:24 +0200 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-04-29 09:36:24 +0200 |
commit | 7407cf355fdf5500430be966dbbde84a27293bad (patch) | |
tree | 922861288ff38558ed721a79653f52b17b13bb95 /arch/arm | |
parent | 6a47dc1418682c83d603b491df1d048f73aa973e (diff) | |
parent | 79dba2eaa771c3173957eccfd288e0e0d12e4d3f (diff) | |
download | op-kernel-dev-7407cf355fdf5500430be966dbbde84a27293bad.zip op-kernel-dev-7407cf355fdf5500430be966dbbde84a27293bad.tar.gz |
Merge branch 'master' into for-2.6.35
Conflicts:
fs/block_dev.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'arch/arm')
47 files changed, 364 insertions, 192 deletions
diff --git a/arch/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig index 216ad00..9405e32 100644 --- a/arch/arm/configs/n8x0_defconfig +++ b/arch/arm/configs/n8x0_defconfig @@ -1058,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig index f5c6e11..881faea 100644 --- a/arch/arm/configs/omap_zoom2_defconfig +++ b/arch/arm/configs/omap_zoom2_defconfig @@ -661,7 +661,7 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/arm/configs/omap_zoom3_defconfig b/arch/arm/configs/omap_zoom3_defconfig index ea9a501..5e55b55 100644 --- a/arch/arm/configs/omap_zoom3_defconfig +++ b/arch/arm/configs/omap_zoom3_defconfig @@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index 45135ff..473f9e1 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig @@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y @@ -480,7 +478,6 @@ CONFIG_BT_HIDP=m # CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set CONFIG_WIRELESS=y CONFIG_CFG80211=y # CONFIG_CFG80211_REG_DEBUG is not set diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 7f36d00..feb988a 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -11,7 +11,11 @@ #define kmap_prot PAGE_KERNEL -#define flush_cache_kmaps() flush_cache_all() +#define flush_cache_kmaps() \ + do { \ + if (cache_is_vivt()) \ + flush_cache_all(); \ + } while (0) extern pte_t *pkmap_page_table; @@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page); extern void *kmap_high_get(struct page *page); extern void kunmap_high(struct page *page); +extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte); +extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); + +/* + * The following functions are already defined by <linux/highmem.h> + * when CONFIG_HIGHMEM is not set. + */ +#ifdef CONFIG_HIGHMEM extern void *kmap(struct page *page); extern void kunmap(struct page *page); extern void *kmap_atomic(struct page *page, enum km_type type); extern void kunmap_atomic(void *kvaddr, enum km_type type); extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); extern struct page *kmap_atomic_to_page(const void *ptr); +#endif #endif diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c019949..c4b2ea3 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h @@ -18,6 +18,7 @@ enum km_type { KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, + KM_L1_CACHE, KM_L2_CACHE, KM_TYPE_NR }; diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h index bf65e9f..47f023a 100644 --- a/arch/arm/include/asm/ucontext.h +++ b/arch/arm/include/asm/ucontext.h @@ -59,23 +59,22 @@ struct iwmmxt_sigframe { #endif /* CONFIG_IWMMXT */ #ifdef CONFIG_VFP -#if __LINUX_ARM_ARCH__ < 6 -/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra - * word after the registers, and a word of padding at the end for - * alignment. */ #define VFP_MAGIC 0x56465001 -#define VFP_STORAGE_SIZE 152 -#else -#define VFP_MAGIC 0x56465002 -#define VFP_STORAGE_SIZE 144 -#endif struct vfp_sigframe { unsigned long magic; unsigned long size; - union vfp_state storage; -}; + struct user_vfp ufp; + struct user_vfp_exc ufp_exc; +} __attribute__((__aligned__(8))); + +/* + * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc, + * 4 bytes padding. + */ +#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe) + #endif /* CONFIG_VFP */ /* @@ -91,7 +90,7 @@ struct aux_sigframe { #ifdef CONFIG_IWMMXT struct iwmmxt_sigframe iwmmxt; #endif -#if 0 && defined CONFIG_VFP /* Not yet saved. */ +#ifdef CONFIG_VFP struct vfp_sigframe vfp; #endif /* Something that isn't a valid magic number for any coprocessor. */ diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h index df95e05..05ac4b0 100644 --- a/arch/arm/include/asm/user.h +++ b/arch/arm/include/asm/user.h @@ -83,11 +83,21 @@ struct user{ /* * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 - * are ignored by the ptrace system call. + * are ignored by the ptrace system call and the signal handler. */ struct user_vfp { unsigned long long fpregs[32]; unsigned long fpscr; }; +/* + * VFP exception registers exposed to user space during signal delivery. + * Fields not relavant to the current VFP architecture are ignored. + */ +struct user_vfp_exc { + unsigned long fpexc; + unsigned long fpinst; + unsigned long fpinst2; +}; + #endif /* _ARM_USER_H */ diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index e7714f3..907d5a6 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -18,6 +18,7 @@ #include <asm/cacheflush.h> #include <asm/ucontext.h> #include <asm/unistd.h> +#include <asm/vfp.h> #include "ptrace.h" #include "signal.h" @@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) #endif +#ifdef CONFIG_VFP + +static int preserve_vfp_context(struct vfp_sigframe __user *frame) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; + const unsigned long magic = VFP_MAGIC; + const unsigned long size = VFP_STORAGE_SIZE; + int err = 0; + + vfp_sync_hwstate(thread); + __put_user_error(magic, &frame->magic, err); + __put_user_error(size, &frame->size, err); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __put_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Copy the exception registers. + */ + __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); + __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; +} + +static int restore_vfp_context(struct vfp_sigframe __user *frame) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; + unsigned long magic; + unsigned long size; + unsigned long fpexc; + int err = 0; + + __get_user_error(magic, &frame->magic, err); + __get_user_error(size, &frame->size, err); + + if (err) + return -EFAULT; + if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) + return -EINVAL; + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __get_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Sanitise and restore the exception registers. + */ + __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); + /* Ensure the VFP is enabled. */ + fpexc |= FPEXC_EN; + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + h->fpexc = fpexc; + + __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + if (!err) + vfp_flush_hwstate(thread); + + return err ? -EFAULT : 0; +} + +#endif + /* * Do a signal return; undo the signal stack. These are aligned to 64-bit. */ @@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= restore_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP -// if (err == 0) -// err |= vfp_restore_state(&sf->aux.vfp); + if (err == 0) + err |= restore_vfp_context(&aux->vfp); #endif return err; @@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= preserve_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP -// if (err == 0) -// err |= vfp_save_state(&sf->aux.vfp); + if (err == 0) + err |= preserve_vfp_context(&aux->vfp); #endif __put_user_error(0, &aux->end_magic, err); diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 027dd57..d400455 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_d obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o - obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 9fcbd6c..9c5b48e 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -175,8 +175,6 @@ ENTRY(at91_slow_clock) orr r3, r3, #(1 << 29) /* bit 29 always set */ str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] - wait_pllalock - /* Save PLLB setting and disable it */ ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] str r3, .saved_pllbr @@ -184,8 +182,6 @@ ENTRY(at91_slow_clock) mov r3, #AT91_PMC_PLLCOUNT str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] - wait_pllblock - /* Turn off the main oscillator */ ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] bic r3, r3, #AT91_PMC_MOSCEN diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 9ad1185..20cfbcc 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -68,12 +68,6 @@ struct sys_timer omap_timer; * --------------------------------------------------------------------------- */ -#if defined(CONFIG_ARCH_OMAP16XX) -#define TIMER_32K_SYNCHRONIZED 0xfffbc410 -#else -#error OMAP 32KHz timer does not currently work on 15XX! -#endif - /* 16xx specific defines */ #define OMAP1_32K_TIMER_BASE 0xfffb9000 #define OMAP1_32K_TIMER_CR 0x08 @@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = { .set_mode = omap_32k_timer_set_mode, }; -/* - * The 32KHz synchronized timer is an additional timer on 16xx. - * It is always running. - */ -static inline unsigned long omap_32k_sync_timer_read(void) -{ - return omap_readl(TIMER_32K_SYNCHRONIZED); -} - static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = &clockevent_32k_timer; diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index a8a3d1e..2455dcc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -59,8 +59,10 @@ config MACH_OMAP3_BEAGLE select OMAP_PACKAGE_CBB config MACH_DEVKIT8000 - bool "DEVKIT8000 board" - depends on ARCH_OMAP3 + bool "DEVKIT8000 board" + depends on ARCH_OMAP3 + select OMAP_PACKAGE_CUS + select OMAP_MUX config MACH_OMAP_LDP bool "OMAP3 LDP board" diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index a0a2a11..504d2bd 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[] __initdata = { static void __init omap_sdp_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); + omap_serial_init(); zoom_peripherals_init(); board_smc91x_init(); enable_board_wakeup_source(); diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 6ae8805..c1c4389 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -294,9 +294,9 @@ static struct omap_board_mux board_mux[] __initdata = { static void __init am3517_evm_init(void) { - am3517_evm_i2c_init(); - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + am3517_evm_i2c_init(); platform_add_devices(am3517_evm_devices, ARRAY_SIZE(am3517_evm_devices)); diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 5bfc13b..47e3af2 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -50,7 +50,6 @@ #include <linux/input/matrix_keypad.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> -#include <linux/usb/otg.h> #include <linux/dm9000.h> #include <linux/interrupt.h> @@ -269,20 +268,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev, devkit8000_vmmc1_supply.dev = mmc[0].dev; devkit8000_vsim_supply.dev = mmc[0].dev; - /* REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect - */ - - gpio_request(gpio + 1, "EHCI_nOC"); - gpio_direction_input(gpio + 1); - - /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ - gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); - gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); - - /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ - gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; - return 0; } @@ -303,7 +288,7 @@ static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = { .dev = &devkit8000_lcd_device.dev, }, { - .supply = "vdss_dsi", + .supply = "vdds_dsi", .dev = &devkit8000_dss_device.dev, } }; @@ -639,17 +624,21 @@ static struct omap_musb_board_data musb_board_data = { static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = 147, + .reset_gpio_port[1] = -EINVAL, .reset_gpio_port[2] = -EINVAL }; static void __init devkit8000_init(void) { + omap_serial_init(); + + omap_dm9000_init(); + devkit8000_i2c_init(); platform_add_devices(devkit8000_devices, ARRAY_SIZE(devkit8000_devices)); @@ -659,25 +648,15 @@ static void __init devkit8000_init(void) spi_register_board_info(devkit8000_spi_board_info, ARRAY_SIZE(devkit8000_spi_board_info)); - omap_serial_init(); - - omap_dm9000_init(); - devkit8000_ads7846_init(); - omap_mux_init_gpio(170, OMAP_PIN_INPUT); - - gpio_request(170, "DVI_nPD"); - /* REVISIT leave DVI powered down until it's needed ... */ - gpio_direction_output(170, true); - usb_musb_init(&musb_board_data); usb_ehci_init(&ehci_pdata); devkit8000_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ - omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT); - omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); } static void __init devkit8000_map_io(void) diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 3c7789d..d55c57b 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -458,13 +458,13 @@ static struct omap_musb_board_data musb_board_data = { }; static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = IGEP2_GPIO_USBH_NRESET, + .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET, + .reset_gpio_port[1] = -EINVAL, .reset_gpio_port[2] = -EINVAL, }; diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index da9bcb8..3ccc34e 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -216,7 +216,7 @@ static void __init n8x0_onenand_init(void) {} */ #define N8X0_SLOT_SWITCH_GPIO 96 #define N810_EMMC_VSD_GPIO 23 -#define NN810_EMMC_VIO_GPIO 9 +#define N810_EMMC_VIO_GPIO 9 static int n8x0_mmc_switch_slot(struct device *dev, int slot) { @@ -304,10 +304,10 @@ static void n810_set_power_emmc(struct device *dev, if (power_on) { gpio_set_value(N810_EMMC_VSD_GPIO, 1); msleep(1); - gpio_set_value(NN810_EMMC_VIO_GPIO, 1); + gpio_set_value(N810_EMMC_VIO_GPIO, 1); msleep(1); } else { - gpio_set_value(NN810_EMMC_VIO_GPIO, 0); + gpio_set_value(N810_EMMC_VIO_GPIO, 0); msleep(50); gpio_set_value(N810_EMMC_VSD_GPIO, 0); msleep(50); @@ -468,7 +468,7 @@ static void n8x0_mmc_cleanup(struct device *dev) if (machine_is_nokia_n810()) { gpio_free(N810_EMMC_VSD_GPIO); - gpio_free(NN810_EMMC_VIO_GPIO); + gpio_free(N810_EMMC_VIO_GPIO); } } @@ -529,7 +529,7 @@ void __init n8x0_mmc_init(void) err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch"); if (err) - return err; + return; gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0); @@ -537,17 +537,17 @@ void __init n8x0_mmc_init(void) err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf"); if (err) { gpio_free(N8X0_SLOT_SWITCH_GPIO); - return err; + return; } gpio_direction_output(N810_EMMC_VSD_GPIO, 0); - err = gpio_request(NN810_EMMC_VIO_GPIO, "MMC slot 2 Vdd"); + err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd"); if (err) { gpio_free(N8X0_SLOT_SWITCH_GPIO); gpio_free(N810_EMMC_VSD_GPIO); - return err; + return; } - gpio_direction_output(NN810_EMMC_VIO_GPIO, 0); + gpio_direction_output(N810_EMMC_VIO_GPIO, 0); } mmc_data[0] = &mmc1_data; diff --git a/arch/arm/mach-omap2/board-sdp-flash.c b/arch/arm/mach-omap2/board-sdp-flash.c index b1b88de..2d02632 100644 --- a/arch/arm/mach-omap2/board-sdp-flash.c +++ b/arch/arm/mach-omap2/board-sdp-flash.c @@ -253,20 +253,20 @@ void __init sdp_flash_init(struct flash_partitions sdp_partition_info[]) } if (norcs > GPMC_CS_NUM) - printk(KERN_INFO "OneNAND: Unable to find configuration " - " in GPMC\n "); + printk(KERN_INFO "NOR: Unable to find configuration " + "in GPMC\n"); else board_nor_init(sdp_partition_info[0], norcs); if (onenandcs > GPMC_CS_NUM) printk(KERN_INFO "OneNAND: Unable to find configuration " - " in GPMC\n "); + "in GPMC\n"); else board_onenand_init(sdp_partition_info[1], onenandcs); if (nandcs > GPMC_CS_NUM) printk(KERN_INFO "NAND: Unable to find configuration " - " in GPMC\n "); + "in GPMC\n"); else board_nand_init(sdp_partition_info[2], nandcs); } diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index bb4018b..e15d2e8 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -96,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = { static struct platform_device zoom_debugboard_serial_device = { .name = "serial8250", - .id = 3, + .id = PLAT8250_DEV_PLATFORM, .dev = { .platform_data = serial_platform_data, }, diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index ca95d8d..6b39849 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -280,7 +280,6 @@ static void enable_board_wakeup_source(void) void __init zoom_peripherals_init(void) { omap_i2c_init(); - omap_serial_init(); usb_musb_init(&musb_board_data); enable_board_wakeup_source(); } diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index d5153b6..9cba556 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -895,7 +895,7 @@ static struct clk dpll4_m4x2_ck = { .ops = &clkops_omap2_dflt_wait, .parent = &dpll4_m4_ck, .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), - .enable_bit = OMAP3430_PWRDN_CAM_SHIFT, + .enable_bit = OMAP3430_PWRDN_DSS1_SHIFT, .flags = INVERT_ENABLE, .clkdm_name = "dpll4_clkdm", .recalc = &omap3_clkoutx2_recalc, diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 28b1079..a5c0c9c 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2671,10 +2671,10 @@ static struct omap_clk omap44xx_clks[] = { CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X), CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X), CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X), - CLK("omap-mcspi.1", "ick", &dummy_ck, CK_443X), - CLK("omap-mcspi.2", "ick", &dummy_ck, CK_443X), - CLK("omap-mcspi.3", "ick", &dummy_ck, CK_443X), - CLK("omap-mcspi.4", "ick", &dummy_ck, CK_443X), + CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X), + CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X), + CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X), + CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X), CLK(NULL, "uart1_ick", &dummy_ck, CK_443X), CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index b87ad66..6e568ec 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -240,7 +240,7 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable) bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO; else bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO; - } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) { + } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { if (enable) bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO; else @@ -812,7 +812,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm) cm_set_mod_reg_bits(OMAP24XX_FORCESTATE, clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); - } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) { + } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP << __ffs(clkdm->clktrctrl_mask)); @@ -856,7 +856,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm) cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE, clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); - } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) { + } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP << __ffs(clkdm->clktrctrl_mask)); diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 23e4d77..2271b9b 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -726,7 +726,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, if (!cpu_is_omap44xx()) return; base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET; - irq = OMAP44XX_IRQ_MMC4; + irq = OMAP44XX_IRQ_MMC5; break; default: continue; diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 64d74f0..e57fb29 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -39,6 +39,9 @@ static int omap2_nand_gpmc_retime(void) struct gpmc_timings t; int err; + if (!gpmc_nand_data->gpmc_t) + return 0; + memset(&t, 0, sizeof(t)); t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk); t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on); diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index ff25c7e..50fd749 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S @@ -52,7 +52,7 @@ omap_irq_base: .word 0 mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision and \tmp, \tmp, #0x000f0000 @ only check architecture - cmp \tmp, #0x00060000 @ is v6? + cmp \tmp, #0x00070000 @ is v6? beq 2400f @ found v6 so it's omap24xx mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision and \tmp, \tmp, #0x000000f0 @ check cortex 8 or 9 diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index aa3f65c..ef0e7a0 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -33,7 +33,7 @@ ENTRY(omap_secondary_startup) hold: ldr r12,=0x103 dsb - smc @ read from AuxCoreBoot0 + smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f @@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} ldr r12, =0x104 dsb - smc + smc #0 ldmfd sp!, {r1-r12, pc} END(omap_modify_auxcoreboot0) @@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr) stmfd sp!, {r2-r12, lr} ldr r12, =0x105 dsb - smc + smc #0 ldmfd sp!, {r2-r12, pc} END(omap_auxcoreboot_addr) diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S index 89bb2b1..f61c777 100644 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -27,6 +27,6 @@ ENTRY(omap_smc1) mov r12, r0 mov r0, r1 dsb - smc + smc #0 ldmfd sp!, {r2-r12, pc} END(omap_smc1) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index c664947..e436dcb 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1511,6 +1511,9 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) c = oh->slaves[oh->_mpu_port_index]->_clk; } + if (!c->clkdm) + return NULL; + return c->clkdm->pwrdm.ptr; } diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 9a0fb38..ebfce7d 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -222,7 +222,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list) { struct powerdomain **p = NULL; - if (cpu_is_omap24xx() | cpu_is_omap34xx()) { + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL; pwrstst_reg_offs = OMAP2_PM_PWSTST; } else if (cpu_is_omap44xx()) { diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 9537f6f..07a60f1 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -123,7 +123,7 @@ struct omap3_prcm_regs prcm_context; u32 omap_prcm_get_reset_sources(void) { /* XXX This presumably needs modification for 34XX */ - if (cpu_is_omap24xx() | cpu_is_omap34xx()) + if (cpu_is_omap24xx() || cpu_is_omap34xx()) return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f; if (cpu_is_omap44xx()) return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f; @@ -157,7 +157,7 @@ void omap_prcm_arch_reset(char mode, const char *cmd) else WARN_ON(1); - if (cpu_is_omap24xx() | cpu_is_omap34xx()) + if (cpu_is_omap24xx() || cpu_is_omap34xx()) prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, OMAP2_RM_RSTCTRL); if (cpu_is_omap44xx()) diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index da77930..3771254 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -115,7 +115,6 @@ static struct plat_serial8250_port serial_platform_data2[] = { } }; -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) static struct plat_serial8250_port serial_platform_data3[] = { { .irq = 70, @@ -128,23 +127,12 @@ static struct plat_serial8250_port serial_platform_data3[] = { } }; -static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals) -{ - serial_platform_data3[0].mapbase = omap2_globals->uart4_phys; -} -#else -static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals) -{ -} -#endif - void __init omap2_set_globals_uart(struct omap_globals *omap2_globals) { serial_platform_data0[0].mapbase = omap2_globals->uart1_phys; serial_platform_data1[0].mapbase = omap2_globals->uart2_phys; serial_platform_data2[0].mapbase = omap2_globals->uart3_phys; - if (cpu_is_omap3630() || cpu_is_omap44xx()) - omap2_set_globals_uart4(omap2_globals); + serial_platform_data3[0].mapbase = omap2_globals->uart4_phys; } static inline unsigned int __serial_read_reg(struct uart_port *up, @@ -550,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev, unsigned int value; if (sscanf(buf, "%u", &value) != 1) { - printk(KERN_ERR "sleep_timeout_store: Invalid value\n"); + dev_err(dev, "sleep_timeout_store: Invalid value\n"); return -EINVAL; } @@ -664,27 +652,33 @@ void __init omap_serial_early_init(void) struct device *dev = &pdev->dev; struct plat_serial8250_port *p = dev->platform_data; + /* Don't map zero-based physical address */ + if (p->mapbase == 0) { + dev_warn(dev, "no physical address for uart#%d," + " so skipping early_init...\n", i); + continue; + } /* * Module 4KB + L4 interconnect 4KB * Static mapping, never released */ p->membase = ioremap(p->mapbase, SZ_8K); if (!p->membase) { - printk(KERN_ERR "ioremap failed for uart%i\n", i + 1); + dev_err(dev, "ioremap failed for uart%i\n", i + 1); continue; } sprintf(name, "uart%d_ick", i + 1); uart->ick = clk_get(NULL, name); if (IS_ERR(uart->ick)) { - printk(KERN_ERR "Could not get uart%d_ick\n", i + 1); + dev_err(dev, "Could not get uart%d_ick\n", i + 1); uart->ick = NULL; } sprintf(name, "uart%d_fck", i+1); uart->fck = clk_get(NULL, name); if (IS_ERR(uart->fck)) { - printk(KERN_ERR "Could not get uart%d_fck\n", i + 1); + dev_err(dev, "Could not get uart%d_fck\n", i + 1); uart->fck = NULL; } @@ -727,6 +721,13 @@ void __init omap_serial_init_port(int port) pdev = &uart->pdev; dev = &pdev->dev; + /* Don't proceed if there's no clocks available */ + if (unlikely(!uart->ick || !uart->fck)) { + WARN(1, "%s: can't init uart%d, no clocks available\n", + kobject_name(&dev->kobj), port); + return; + } + omap_uart_enable_clocks(uart); omap_uart_reset(uart); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 8bca4de..f55fa10 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, kfrom = kmap_atomic(from, KM_USER0); kto = kmap_atomic(to, KM_USER1); copy_page(kto, kfrom); -#ifdef CONFIG_HIGHMEM - /* - * kmap_atomic() doesn't set the page virtual address, and - * kunmap_atomic() takes care of cache flushing already. - */ - if (page_address(to) != NULL) -#endif - __cpuc_flush_dcache_area(kto, PAGE_SIZE); + __cpuc_flush_dcache_area(kto, PAGE_SIZE); kunmap_atomic(kto, KM_USER1); kunmap_atomic(kfrom, KM_USER0); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1351edc..13fa536 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, vaddr += offset; op(vaddr, len, dir); kunmap_high(page); + } else if (cache_is_vipt()) { + pte_t saved_pte; + vaddr = kmap_high_l1_vipt(page, &saved_pte); + op(vaddr + offset, len, dir); + kunmap_high_l1_vipt(page, saved_pte); } } else { vaddr = page_address(page) + offset; diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index e34f095..c6844cb 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -13,6 +13,7 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> +#include <asm/highmem.h> #include <asm/smp_plat.h> #include <asm/system.h> #include <asm/tlbflush.h> @@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, void __flush_dcache_page(struct address_space *mapping, struct page *page) { - void *addr = page_address(page); - /* * Writeback any data associated with the kernel mapping of this * page. This ensures that data in the physical page is mutually * coherent with the kernels mapping. */ -#ifdef CONFIG_HIGHMEM - /* - * kmap_atomic() doesn't set the page virtual address, and - * kunmap_atomic() takes care of cache flushing already. - */ - if (addr) -#endif - __cpuc_flush_dcache_area(addr, PAGE_SIZE); + if (!PageHighMem(page)) { + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); + } else { + void *addr = kmap_high_get(page); + if (addr) { + __cpuc_flush_dcache_area(addr, PAGE_SIZE); + kunmap_high(page); + } else if (cache_is_vipt()) { + pte_t saved_pte; + addr = kmap_high_l1_vipt(page, &saved_pte); + __cpuc_flush_dcache_area(addr, PAGE_SIZE); + kunmap_high_l1_vipt(page, saved_pte); + } + } /* * If this is a page cache page, and we have an aliasing VIPT cache, diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 2be1ec7..77b030f 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); if (kvaddr >= (void *)FIXADDR_START) { - __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); + if (cache_is_vivt()) + __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); @@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr) pte = TOP_PTE(vaddr); return pte_page(*pte); } + +#ifdef CONFIG_CPU_CACHE_VIPT + +#include <linux/percpu.h> + +/* + * The VIVT cache of a highmem page is always flushed before the page + * is unmapped. Hence unmapped highmem pages need no cache maintenance + * in that case. + * + * However unmapped pages may still be cached with a VIPT cache, and + * it is not possible to perform cache maintenance on them using physical + * addresses unfortunately. So we have no choice but to set up a temporary + * virtual mapping for that purpose. + * + * Yet this VIPT cache maintenance may be triggered from DMA support + * functions which are possibly called from interrupt context. As we don't + * want to keep interrupt disabled all the time when such maintenance is + * taking place, we therefore allow for some reentrancy by preserving and + * restoring the previous fixmap entry before the interrupted context is + * resumed. If the reentrancy depth is 0 then there is no need to restore + * the previous fixmap, and leaving the current one in place allow it to + * be reused the next time without a TLB flush (common with DMA). + */ + +static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth); + +void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte) +{ + unsigned int idx, cpu = smp_processor_id(); + int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); + unsigned long vaddr, flags; + pte_t pte, *ptep; + + idx = KM_L1_CACHE + KM_TYPE_NR * cpu; + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + ptep = TOP_PTE(vaddr); + pte = mk_pte(page, kmap_prot); + + if (!in_interrupt()) + preempt_disable(); + + raw_local_irq_save(flags); + (*depth)++; + if (pte_val(*ptep) == pte_val(pte)) { + *saved_pte = pte; + } else { + *saved_pte = *ptep; + set_pte_ext(ptep, pte, 0); + local_flush_tlb_kernel_page(vaddr); + } + raw_local_irq_restore(flags); + + return (void *)vaddr; +} + +void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte) +{ + unsigned int idx, cpu = smp_processor_id(); + int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); + unsigned long vaddr, flags; + pte_t pte, *ptep; + + idx = KM_L1_CACHE + KM_TYPE_NR * cpu; + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + ptep = TOP_PTE(vaddr); + pte = mk_pte(page, kmap_prot); + + BUG_ON(pte_val(*ptep) != pte_val(pte)); + BUG_ON(*depth <= 0); + + raw_local_irq_save(flags); + (*depth)--; + if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) { + set_pte_ext(ptep, saved_pte, 0); + local_flush_tlb_kernel_page(vaddr); + } + raw_local_irq_restore(flags); + + if (!in_interrupt()) + preempt_enable(); +} + +#endif /* CONFIG_CPU_CACHE_VIPT */ diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4223d08..241c24a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1054,10 +1054,12 @@ void setup_mm_for_reboot(char mode) pgd_t *pgd; int i; - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; + /* + * We need to access to user-mode page tables here. For kernel threads + * we don't have any user-mode mappings so we use the context that we + * "borrowed". + */ + pgd = current->active_mm->pgd; base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 088c1a0..f12f0e3 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -44,9 +44,6 @@ #define NO_LENGTH_CHECK 0xffffffff -unsigned char omap_bootloader_tag[512]; -int omap_bootloader_tag_len; - struct omap_board_config_kernel *omap_board_config; int omap_board_config_size; @@ -100,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config); #include <linux/clocksource.h> +/* + * offset_32k holds the init time counter value. It is then subtracted + * from every counter read to achieve a counter that counts time from the + * kernel boot (needed for sched_clock()). + */ +static u32 offset_32k __read_mostly; + #ifdef CONFIG_ARCH_OMAP16XX static cycle_t omap16xx_32k_read(struct clocksource *cs) { - return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED); + return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k; } #else #define omap16xx_32k_read NULL @@ -112,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs) #ifdef CONFIG_ARCH_OMAP2420 static cycle_t omap2420_32k_read(struct clocksource *cs) { - return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10); + return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k; } #else #define omap2420_32k_read NULL @@ -121,7 +125,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs) #ifdef CONFIG_ARCH_OMAP2430 static cycle_t omap2430_32k_read(struct clocksource *cs) { - return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10); + return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k; } #else #define omap2430_32k_read NULL @@ -130,7 +134,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs) #ifdef CONFIG_ARCH_OMAP3 static cycle_t omap34xx_32k_read(struct clocksource *cs) { - return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10); + return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k; } #else #define omap34xx_32k_read NULL @@ -139,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs) #ifdef CONFIG_ARCH_OMAP4 static cycle_t omap44xx_32k_read(struct clocksource *cs) { - return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10); + return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k; } #else #define omap44xx_32k_read NULL @@ -227,6 +231,8 @@ static int __init omap_init_clocksource_32k(void) clocksource_32k.mult = clocksource_hz2mult(32768, clocksource_32k.shift); + offset_32k = clocksource_32k.read(&clocksource_32k); + if (clocksource_register(&clocksource_32k)) printk(err, clocksource_32k.name); } diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 5c6c342..1d95996 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -937,6 +937,15 @@ void omap_start_dma(int lch) { u32 l; + /* + * The CPC/CDAC register needs to be initialized to zero + * before starting dma transfer. + */ + if (cpu_is_omap15xx()) + dma_write(0, CPC(lch)); + else + dma_write(0, CDAC(lch)); + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch; char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 76a347b..45a225d 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); - if (trigger & IRQ_TYPE_EDGE_BOTH) + if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; @@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & IRQ_TYPE_EDGE_BOTH) + if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; @@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_7XX: reg += OMAP7XX_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & IRQ_TYPE_EDGE_BOTH) + if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index b65088a..4017019 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -345,8 +345,6 @@ #define INT_34XX_MMC3_IRQ 94 #define INT_34XX_GPT12_IRQ 95 -#define INT_34XX_BENCH_MPU_EMUL 3 - #define INT_35XX_HECC0_IRQ 24 #define INT_35XX_HECC1_IRQ 28 #define INT_35XX_EMAC_C0_RXTHRESH_IRQ 67 diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 3974835..7de903d 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -59,7 +59,7 @@ #define OMAP44XX_MCBSP1_BASE 0x49022000 #define OMAP44XX_MCBSP2_BASE 0x49024000 #define OMAP44XX_MCBSP3_BASE 0x49026000 -#define OMAP44XX_MCBSP4_BASE 0x48074000 +#define OMAP44XX_MCBSP4_BASE 0x48096000 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index 6ba88d2..f8efd546 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -29,4 +29,11 @@ struct omap_nand_platform_data { /* size (4 KiB) for IO mapping */ #define NAND_IO_SIZE SZ_4K +#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) extern int gpmc_nand_init(struct omap_nand_platform_data *d); +#else +static inline int gpmc_nand_init(struct omap_nand_platform_data *d) +{ + return 0; +} +#endif diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index 2302474..b3ef1a7 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -32,7 +32,7 @@ #define OMAP4430_PRM_BASE 0x4a306000 #define OMAP44XX_GPMC_BASE 0x50000000 #define OMAP443X_SCM_BASE 0x4a002000 -#define OMAP443X_CTRL_BASE OMAP443X_SCM_BASE +#define OMAP443X_CTRL_BASE 0x4a100000 #define OMAP44XX_IC_BASE 0x48200000 #define OMAP44XX_IVA_INTC_BASE 0x40000000 #define IRQ_SIR_IRQ 0x0040 diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 440b416..36d6ea5 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -294,8 +294,8 @@ struct omap_hwmod_class_sysconfig { u16 rev_offs; u16 sysc_offs; u16 syss_offs; + u16 sysc_flags; u8 idlemodes; - u8 sysc_flags; u8 clockact; struct omap_hwmod_sysc_fields *sysc_fields; }; diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index a420cb9..315a540 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -428,26 +428,6 @@ static void vfp_pm_init(void) static inline void vfp_pm_init(void) { } #endif /* CONFIG_PM */ -/* - * Synchronise the hardware VFP state of a thread other than current with the - * saved one. This function is used by the ptrace mechanism. - */ -#ifdef CONFIG_SMP -void vfp_sync_hwstate(struct thread_info *thread) -{ -} - -void vfp_flush_hwstate(struct thread_info *thread) -{ - /* - * On SMP systems, the VFP state is automatically saved at every - * context switch. We mark the thread VFP state as belonging to a - * non-existent CPU so that the saved one will be reloaded when - * needed. - */ - thread->vfpstate.hard.cpu = NR_CPUS; -} -#else void vfp_sync_hwstate(struct thread_info *thread) { unsigned int cpu = get_cpu(); @@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread) last_VFP_context[cpu] = NULL; } +#ifdef CONFIG_SMP + /* + * For SMP we still have to take care of the case where the thread + * migrates to another CPU and then back to the original CPU on which + * the last VFP user is still the same thread. Mark the thread VFP + * state as belonging to a non-existent CPU so that the saved one will + * be reloaded in the above case. + */ + thread->vfpstate.hard.cpu = NR_CPUS; +#endif put_cpu(); } -#endif #include <linux/smp.h> |