diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-08-04 11:58:28 (GMT) |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-04 11:58:28 (GMT) |
commit | e16852cfc5580b88cb327413ab8c89375f380592 (patch) | |
tree | 67e7d5b84e2602986f2da689625e5a25d7af7bb4 /arch | |
parent | bdff78707f3ce47e891f3201c9666122a70556ce (diff) | |
parent | 74e7ff8c50b6b022e6ffaa736b16a4dc161d3eaf (diff) | |
download | linux-fsl-qoriq-e16852cfc5580b88cb327413ab8c89375f380592.tar.xz |
Merge branch 'tracing/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into tracing/urgent
Diffstat (limited to 'arch')
114 files changed, 1153 insertions, 555 deletions
diff --git a/arch/alpha/include/asm/tlb.h b/arch/alpha/include/asm/tlb.h index c136365..4286675 100644 --- a/arch/alpha/include/asm/tlb.h +++ b/arch/alpha/include/asm/tlb.h @@ -9,7 +9,7 @@ #include <asm-generic/tlb.h> -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte) -#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd) +#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) +#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd) #endif diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 4762d90..7d61ae6 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc1 -# Thu Jul 2 00:16:59 2009 +# Linux kernel version: 2.6.31-rc3 +# Thu Jul 16 23:36:10 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_MMU=y -CONFIG_HAVE_TCM=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -113,7 +112,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -CONFIG_LBDAF=y +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -542,13 +541,14 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set @@ -911,7 +911,6 @@ CONFIG_REGULATOR=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set CONFIG_FILE_LOCKING=y @@ -1122,7 +1121,6 @@ CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC32 is not set # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set -CONFIG_GENERIC_ALLOCATOR=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 321c83e..f41a6f5 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -102,8 +102,8 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) } #define tlb_remove_page(tlb,page) free_page_and_swap_cache(page) -#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep) -#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp) +#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep) +#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp) #define tlb_migrate_finish(mm) do { } while (0) diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c index a2df5bb..dbcac9c 100644 --- a/arch/arm/mach-ep93xx/dma-m2p.c +++ b/arch/arm/mach-ep93xx/dma-m2p.c @@ -33,6 +33,7 @@ #include <linux/err.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/io.h> #include <mach/dma.h> #include <mach/hardware.h> diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h index e021a80..bc74278 100644 --- a/arch/arm/mach-kirkwood/mpp.h +++ b/arch/arm/mach-kirkwood/mpp.h @@ -289,7 +289,7 @@ #define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 ) #define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP48_TDM_DTX MPP( 48. 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 1, 0, 0, 0, 1 ) #define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 ) #define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 ) diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 17a21a2..851f245 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -36,6 +36,14 @@ config MACH_PCM037 Include support for Phytec pcm037 platform. This includes specific configurations for the board and its peripherals. +config MACH_PCM037_EET + bool "Support pcm037 EET board extensions" + depends on MACH_PCM037 + help + Add support for PCM037 EET baseboard extensions. If you are using the + OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel + command-line parameter. + config MACH_MX31LITE bool "Support MX31 LITEKIT (LogicPD)" select ARCH_MX31 diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 0322696..6b97754 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o +obj-$(CONFIG_MACH_PCM037_EET) += pcm037_eet.o obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ mx31moboard-marxbot.o diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c index 54118109..ee331fd 100644 --- a/arch/arm/mach-mx3/armadillo5x0.c +++ b/arch/arm/mach-mx3/armadillo5x0.c @@ -31,6 +31,8 @@ #include <linux/smsc911x.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/mtd/physmap.h> +#include <linux/io.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -46,8 +48,10 @@ #include <mach/mmc.h> #include <mach/ipu.h> #include <mach/mx3fb.h> +#include <mach/mxc_nand.h> #include "devices.h" +#include "crm_regs.h" static int armadillo5x0_pins[] = { /* UART1 */ @@ -93,7 +97,56 @@ static int armadillo5x0_pins[] = { MX31_PIN_FPSHIFT__FPSHIFT, MX31_PIN_DRDY0__DRDY0, IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ +}; +/* + * NAND Flash + */ +static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = { + .width = 1, + .hw_ecc = 1, +}; + +/* + * MTD NOR Flash + */ +static struct mtd_partition armadillo5x0_nor_flash_partitions[] = { + { + .name = "nor.bootloader", + .offset = 0x00000000, + .size = 4*32*1024, + }, { + .name = "nor.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 16*128*1024, + }, { + .name = "nor.userland", + .offset = MTDPART_OFS_APPEND, + .size = 110*128*1024, + }, { + .name = "nor.config", + .offset = MTDPART_OFS_APPEND, + .size = 1*128*1024, + }, +}; + +static struct physmap_flash_data armadillo5x0_nor_flash_pdata = { + .width = 2, + .parts = armadillo5x0_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions), +}; + +static struct resource armadillo5x0_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = CS0_BASE_ADDR, + .end = CS0_BASE_ADDR + SZ_64M - 1, +}; + +static struct platform_device armadillo5x0_nor_flash = { + .name = "physmap-flash", + .id = -1, + .num_resources = 1, + .resource = &armadillo5x0_nor_flash_resource, }; /* @@ -272,6 +325,16 @@ static void __init armadillo5x0_init(void) /* Register FB */ mxc_register_device(&mx3_ipu, &mx3_ipu_data); mxc_register_device(&mx3_fb, &mx3fb_pdata); + + /* Register NOR Flash */ + mxc_register_device(&armadillo5x0_nor_flash, + &armadillo5x0_nor_flash_pdata); + + /* Register NAND Flash */ + mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata); + + /* set NAND page size to 2k if not configured via boot mode pins */ + __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); } static void __init armadillo5x0_timer_init(void) diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index d927edd..9e87e08 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -22,7 +22,6 @@ #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/gpio.h> -#include <linux/dma-mapping.h> #include <mach/hardware.h> #include <mach/irqs.h> #include <mach/common.h> diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index c6f61a1..840cfda3 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c @@ -18,7 +18,7 @@ #include <linux/types.h> #include <linux/init.h> - +#include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/mtd/plat-ram.h> @@ -33,29 +33,67 @@ #include <linux/irq.h> #include <linux/fsl_devices.h> -#include <mach/hardware.h> +#include <media/soc_camera.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/map.h> +#include <mach/board-pcm037.h> #include <mach/common.h> +#include <mach/hardware.h> +#include <mach/i2c.h> #include <mach/imx-uart.h> #include <mach/iomux-mx3.h> #include <mach/ipu.h> -#include <mach/board-pcm037.h> +#include <mach/mmc.h> +#include <mach/mx3_camera.h> #include <mach/mx3fb.h> #include <mach/mxc_nand.h> -#include <mach/mmc.h> -#ifdef CONFIG_I2C_IMX -#include <mach/i2c.h> -#endif #include "devices.h" +#include "pcm037.h" + +static enum pcm037_board_variant pcm037_instance = PCM037_PCM970; + +static int __init pcm037_variant_setup(char *str) +{ + if (!strcmp("eet", str)) + pcm037_instance = PCM037_EET; + else if (strcmp("pcm970", str)) + pr_warning("Unknown pcm037 baseboard variant %s\n", str); + + return 1; +} + +/* Supported values: "pcm970" (default) and "eet" */ +__setup("pcm037_variant=", pcm037_variant_setup); + +enum pcm037_board_variant pcm037_variant(void) +{ + return pcm037_instance; +} + +/* UART1 with RTS/CTS handshake signals */ +static unsigned int pcm037_uart1_handshake_pins[] = { + MX31_PIN_CTS1__CTS1, + MX31_PIN_RTS1__RTS1, + MX31_PIN_TXD1__TXD1, + MX31_PIN_RXD1__RXD1, +}; + +/* UART1 without RTS/CTS handshake signals */ +static unsigned int pcm037_uart1_pins[] = { + MX31_PIN_TXD1__TXD1, + MX31_PIN_RXD1__RXD1, +}; static unsigned int pcm037_pins[] = { /* I2C */ MX31_PIN_CSPI2_MOSI__SCL, MX31_PIN_CSPI2_MISO__SDA, + MX31_PIN_CSPI2_SS2__I2C3_SDA, + MX31_PIN_CSPI2_SCLK__I2C3_SCL, /* SDHC1 */ MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2, @@ -73,11 +111,6 @@ static unsigned int pcm037_pins[] = { MX31_PIN_CSPI1_SS0__SS0, MX31_PIN_CSPI1_SS1__SS1, MX31_PIN_CSPI1_SS2__SS2, - /* UART1 */ - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, /* UART2 */ MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, @@ -120,6 +153,22 @@ static unsigned int pcm037_pins[] = { MX31_PIN_D3_SPL__D3_SPL, MX31_PIN_D3_CLS__D3_CLS, MX31_PIN_LCS0__GPI03_23, + /* CSI */ + IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO), + MX31_PIN_CSI_D6__CSI_D6, + MX31_PIN_CSI_D7__CSI_D7, + MX31_PIN_CSI_D8__CSI_D8, + MX31_PIN_CSI_D9__CSI_D9, + MX31_PIN_CSI_D10__CSI_D10, + MX31_PIN_CSI_D11__CSI_D11, + MX31_PIN_CSI_D12__CSI_D12, + MX31_PIN_CSI_D13__CSI_D13, + MX31_PIN_CSI_D14__CSI_D14, + MX31_PIN_CSI_D15__CSI_D15, + MX31_PIN_CSI_HSYNC__CSI_HSYNC, + MX31_PIN_CSI_MCLK__CSI_MCLK, + MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, + MX31_PIN_CSI_VSYNC__CSI_VSYNC, }; static struct physmap_flash_data pcm037_flash_data = { @@ -250,19 +299,43 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = { .hw_ecc = 1, }; -#ifdef CONFIG_I2C_IMX static struct imxi2c_platform_data pcm037_i2c_1_data = { .bitrate = 100000, }; +static struct imxi2c_platform_data pcm037_i2c_2_data = { + .bitrate = 20000, +}; + static struct at24_platform_data board_eeprom = { .byte_len = 4096, .page_size = 32, .flags = AT24_FLAG_ADDR16, }; +static int pcm037_camera_power(struct device *dev, int on) +{ + /* disable or enable the camera in X7 or X8 PCM970 connector */ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on); + return 0; +} + +static struct i2c_board_info pcm037_i2c_2_devices[] = { + { + I2C_BOARD_INFO("mt9t031", 0x5d), + }, +}; + +static struct soc_camera_link iclink = { + .bus_id = 0, /* Must match with the camera ID */ + .power = pcm037_camera_power, + .board_info = &pcm037_i2c_2_devices[0], + .i2c_adapter_id = 2, + .module_name = "mt9t031", +}; + static struct i2c_board_info pcm037_i2c_devices[] = { - { + { I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ .platform_data = &board_eeprom, }, { @@ -270,7 +343,14 @@ static struct i2c_board_info pcm037_i2c_devices[] = { .type = "pcf8563", } }; -#endif + +static struct platform_device pcm037_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink, + }, +}; /* Not connected by default */ #ifdef PCM970_SDHC_RW_SWITCH @@ -334,9 +414,41 @@ static struct imxmmc_platform_data sdhc_pdata = { .exit = pcm970_sdhc1_exit, }; +struct mx3_camera_pdata camera_pdata = { + .dma_dev = &mx3_ipu.dev, + .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, + .mclk_10khz = 2000, +}; + +static int __init pcm037_camera_alloc_dma(const size_t buf_size) +{ + dma_addr_t dma_handle; + void *buf; + int dma; + + if (buf_size < 2 * 1024 * 1024) + return -EINVAL; + + buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL); + if (!buf) { + pr_err("%s: cannot allocate camera buffer-memory\n", __func__); + return -ENOMEM; + } + + memset(buf, 0, buf_size); + + dma = dma_declare_coherent_memory(&mx3_camera.dev, + dma_handle, dma_handle, buf_size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); + + /* The way we call dma_declare_coherent_memory only a malloc can fail */ + return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM; +} + static struct platform_device *devices[] __initdata = { &pcm037_flash, &pcm037_sram_device, + &pcm037_camera, }; static struct ipu_platform_data mx3_ipu_data = { @@ -377,6 +489,22 @@ static const struct fb_videomode fb_modedb[] = { .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, .vmode = FB_VMODE_NONINTERLACED, .flag = 0, + }, { + /* 240x320 @ 60 Hz */ + .name = "CMEL-OLED", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 185925, + .left_margin = 9, + .right_margin = 16, + .upper_margin = 7, + .lower_margin = 9, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, }, }; @@ -397,6 +525,14 @@ static void __init mxc_board_init(void) mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), "pcm037"); + if (pcm037_variant() == PCM037_EET) + mxc_iomux_setup_multiple_pins(pcm037_uart1_pins, + ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1"); + else + mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins, + ARRAY_SIZE(pcm037_uart1_handshake_pins), + "pcm037_uart1"); + platform_add_devices(devices, ARRAY_SIZE(devices)); mxc_register_device(&mxc_uart_device0, &uart_pdata); @@ -415,18 +551,30 @@ static void __init mxc_board_init(void) } -#ifdef CONFIG_I2C_IMX + /* I2C adapters and devices */ i2c_register_board_info(1, pcm037_i2c_devices, ARRAY_SIZE(pcm037_i2c_devices)); mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data); -#endif + mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data); + mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); mxc_register_device(&mxcsdhc_device0, &sdhc_pdata); mxc_register_device(&mx3_ipu, &mx3_ipu_data); mxc_register_device(&mx3_fb, &mx3fb_pdata); if (!gpio_usbotg_hs_activate()) mxc_register_device(&mxc_otg_udc_device, &usb_pdata); + + /* CSI */ + /* Camera power: default - off */ + ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power"); + if (!ret) + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); + else + iclink.power = NULL; + + if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) + mxc_register_device(&mx3_camera, &camera_pdata); } static void __init pcm037_timer_init(void) @@ -448,4 +596,3 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037") .init_machine = mxc_board_init, .timer = &pcm037_timer, MACHINE_END - diff --git a/arch/arm/mach-mx3/pcm037.h b/arch/arm/mach-mx3/pcm037.h new file mode 100644 index 0000000..d692972 --- /dev/null +++ b/arch/arm/mach-mx3/pcm037.h @@ -0,0 +1,11 @@ +#ifndef __PCM037_H__ +#define __PCM037_H__ + +enum pcm037_board_variant { + PCM037_PCM970, + PCM037_EET, +}; + +extern enum pcm037_board_variant pcm037_variant(void); + +#endif diff --git a/arch/arm/mach-mx3/pcm037_eet.c b/arch/arm/mach-mx3/pcm037_eet.c new file mode 100644 index 0000000..fe52fb1 --- /dev/null +++ b/arch/arm/mach-mx3/pcm037_eet.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2009 + * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> + * + * 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/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> + +#include <mach/common.h> +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) +#include <mach/spi.h> +#endif +#include <mach/iomux-mx3.h> + +#include <asm/mach-types.h> + +#include "pcm037.h" +#include "devices.h" + +static unsigned int pcm037_eet_pins[] = { + /* SPI #1 */ + MX31_PIN_CSPI1_MISO__MISO, + MX31_PIN_CSPI1_MOSI__MOSI, + MX31_PIN_CSPI1_SCLK__SCLK, + MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI1_SS0__SS0, + MX31_PIN_CSPI1_SS1__SS1, + MX31_PIN_CSPI1_SS2__SS2, + + /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ + IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), + /* GPIO keys */ + IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), /* 0 */ + IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), /* 1 */ + IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO), /* 2 */ + IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), /* 3 */ + IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO), /* 32 */ + IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO), /* 33 */ + IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO), /* 34 */ + IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO), /* 35 */ + IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO), /* 38 */ + IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO), /* 39 */ + IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO), /* 50 */ + IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_GPIO), /* 51 */ + IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_GPIO), /* 52 */ + IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_GPIO), /* 53 */ + + /* LEDs */ + IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_CONFIG_GPIO), /* 44 */ + IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_GPIO), /* 45 */ + IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_GPIO), /* 55 */ + IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_GPIO), /* 56 */ +}; + +/* SPI */ +static struct spi_board_info pcm037_spi_dev[] = { + { + .modalias = "dac124s085", + .max_speed_hz = 400000, + .bus_num = 0, + .chip_select = 0, /* Index in pcm037_spi1_cs[] */ + .mode = SPI_CPHA, + }, +}; + +/* Platform Data for MXC CSPI */ +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) +static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; + +struct spi_imx_master pcm037_spi1_master = { + .chipselect = pcm037_spi1_cs, + .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs), +}; +#endif + +/* GPIO-keys input device */ +static struct gpio_keys_button pcm037_gpio_keys[] = { + { + .type = EV_KEY, + .code = KEY_L, + .gpio = 0, + .desc = "Wheel Manual", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_A, + .gpio = 1, + .desc = "Wheel AF", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_V, + .gpio = 2, + .desc = "Wheel View", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_M, + .gpio = 3, + .desc = "Wheel Menu", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_UP, + .gpio = 32, + .desc = "Nav Pad Up", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_RIGHT, + .gpio = 33, + .desc = "Nav Pad Right", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_DOWN, + .gpio = 34, + .desc = "Nav Pad Down", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_LEFT, + .gpio = 35, + .desc = "Nav Pad Left", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_ENTER, + .gpio = 38, + .desc = "Nav Pad Ok", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = KEY_O, + .gpio = 39, + .desc = "Wheel Off", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = BTN_FORWARD, + .gpio = 50, + .desc = "Focus Forward", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = BTN_BACK, + .gpio = 51, + .desc = "Focus Backward", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = BTN_MIDDLE, + .gpio = 52, + .desc = "Release Half", + .wakeup = 0, + }, { + .type = EV_KEY, + .code = BTN_EXTRA, + .gpio = 53, + .desc = "Release Full", + .wakeup = 0, + }, +}; + +static struct gpio_keys_platform_data pcm037_gpio_keys_platform_data = { + .buttons = pcm037_gpio_keys, + .nbuttons = ARRAY_SIZE(pcm037_gpio_keys), + .rep = 0, /* No auto-repeat */ +}; + +static struct platform_device pcm037_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &pcm037_gpio_keys_platform_data, + }, +}; + +static int eet_init_devices(void) +{ + if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) + return 0; + + mxc_iomux_setup_multiple_pins(pcm037_eet_pins, + ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet"); + + /* SPI */ + spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev)); +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) + mxc_register_device(&mxc_spi_device0, &pcm037_spi1_master); +#endif + + platform_device_register(&pcm037_gpio_keys_device); + + return 0; +} + +late_initcall(eet_init_devices); diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h index ae84411..7139e0d 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h @@ -567,9 +567,9 @@ #define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3) #define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1) -#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, MFP_AF0, MFP_DS01X) -#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, MFP_AF0, MFP_DS01X) -#define ULPI_STP MFP_CFG_DRV(ULPI_STP, MFP_AF0, MFP_DS01X) +#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, AF0, DS01X) +#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, AF0, DS01X) +#define ULPI_STP MFP_CFG_DRV(ULPI_STP, AF0, DS01X) #endif /* CONFIG_CPU_PXA310 */ #endif /* __ASM_ARCH_MFP_PXA300_H */ diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 6f678d9..09b7b1a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -250,7 +250,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ - INIT_CLKREG(&clk_dummy, "pxa2xx-i2c.1", NULL), + INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 9ea9c05..facbd49 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -208,8 +208,7 @@ struct platform_device realview_i2c_device = { static struct i2c_board_info realview_i2c_board_info[] = { { - I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1), - .type = "ds1338", + I2C_BOARD_INFO("ds1338", 0xd0 >> 1), }, }; diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 89b3ccf..7936085 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -455,8 +455,8 @@ void __init u300_init_irq(void) for (i = 0; i < NR_IRQS; i++) set_bit(i, (unsigned long *) &mask[0]); u300_enable_intcon_clock(); - vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], 0); - vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], 0); + vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); + vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]); } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 69214fc..31093af 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -342,8 +342,7 @@ static struct platform_device versatile_i2c_device = { static struct i2c_board_info versatile_i2c_board_info[] = { { - I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1), - .type = "ds1338", + I2C_BOARD_INFO("ds1338", 0xd0 >> 1), }, }; diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 27f8d1b..2eb182f 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -602,6 +602,8 @@ enum iomux_pins { #define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) #define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) #define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) +#define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1) +#define MX31_PIN_CSPI2_SCLK__I2C3_SCL IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT1) #define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC) diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c index abc79d4..98548c6 100644 --- a/arch/arm/plat-pxa/gpio.c +++ b/arch/arm/plat-pxa/gpio.c @@ -16,7 +16,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/sysdev.h> -#include <linux/bootmem.h> +#include <linux/slab.h> #include <mach/gpio.h> @@ -112,17 +112,12 @@ static int __init pxa_init_gpio_chip(int gpio_end) int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; struct pxa_gpio_chip *chips; - /* this is early, we have to use bootmem allocator, and we really - * want this to be allocated dynamically for different 'gpio_end' - */ - chips = alloc_bootmem_low(nbanks * sizeof(struct pxa_gpio_chip)); + chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); if (chips == NULL) { pr_err("%s: failed to allocate GPIO chips\n", __func__); return -ENOMEM; } - memset(chips, 0, nbanks * sizeof(struct pxa_gpio_chip)); - for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { struct gpio_chip *c = &chips[i].chip; diff --git a/arch/avr32/include/asm/pgalloc.h b/arch/avr32/include/asm/pgalloc.h index 6408213..92ecd84 100644 --- a/arch/avr32/include/asm/pgalloc.h +++ b/arch/avr32/include/asm/pgalloc.h @@ -83,7 +83,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) quicklist_free_page(QUICK_PT, NULL, pte); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,addr) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb), pte); \ diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S index 16561ab..f8a664f 100644 --- a/arch/blackfin/include/asm/context.S +++ b/arch/blackfin/include/asm/context.S @@ -223,9 +223,10 @@ [--sp] = RETN; [--sp] = RETE; [--sp] = SEQSTAT; -#ifdef CONFIG_KGDB - r1.l = lo(IPEND); - r1.h = hi(IPEND); +#ifdef CONFIG_DEBUG_KERNEL + p1.l = lo(IPEND); + p1.h = hi(IPEND); + r1 = [p1]; [--sp] = r1; #else [--sp] = r0; /* Skip IPEND as well. */ diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h index 565b813..fadfa82 100644 --- a/arch/blackfin/include/asm/cpu.h +++ b/arch/blackfin/include/asm/cpu.h @@ -32,7 +32,6 @@ struct blackfin_cpudata { struct task_struct *idle; unsigned int imemctl; unsigned int dmemctl; - unsigned long loops_per_jiffy; unsigned long dcache_invld_count; unsigned long icache_invld_count; }; diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h index cbd52f8..0b78b87 100644 --- a/arch/blackfin/include/asm/hardirq.h +++ b/arch/blackfin/include/asm/hardirq.h @@ -6,6 +6,9 @@ extern void ack_bad_irq(unsigned int irq); #define ack_bad_irq ack_bad_irq +/* Define until common code gets sane defaults */ +#define HARDIRQ_BITS 9 + #include <asm-generic/hardirq.h> #endif diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h index d0be99b..a36ad8d 100644 --- a/arch/blackfin/include/asm/processor.h +++ b/arch/blackfin/include/asm/processor.h @@ -105,23 +105,16 @@ static inline uint32_t __pure bfin_revid(void) /* Always use CHIPID, to work around ANOMALY_05000234 */ uint32_t revid = (bfin_read_CHIPID() & CHIPID_VERSION) >> 28; -#ifdef CONFIG_BF52x - /* ANOMALY_05000357 +#ifdef _BOOTROM_GET_DXE_ADDRESS_TWI + /* + * ANOMALY_05000364 * Incorrect Revision Number in DSPID Register */ - if (revid == 0) - switch (bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI)) { - case 0x0010: - revid = 0; - break; - case 0x2796: - revid = 1; - break; - default: - revid = 0xFFFF; - break; - } + if (ANOMALY_05000364 && + bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI) == 0x2796) + revid = 1; #endif + return revid; } diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index e0bf8cc..9f9b828 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -253,32 +253,31 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) BUG_ON(src % 4); BUG_ON(size % 4); - /* Force a sync in case a previous config reset on this channel - * occurred. This is needed so subsequent writes to DMA registers - * are not spuriously lost/corrupted. - */ - __builtin_bfin_ssync(); - src_ch = 0; /* Find an avalible memDMA channel */ while (1) { - if (!src_ch || src_ch == (struct dma_register *)MDMA_S1_NEXT_DESC_PTR) { - dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR; - src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; - } else { + if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) { dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR; src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR; + } else { + dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR; + src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; } - if (!bfin_read16(&src_ch->cfg)) { + if (!bfin_read16(&src_ch->cfg)) + break; + else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) { + bfin_write16(&src_ch->cfg, 0); break; - } else { - if (bfin_read16(&src_ch->irq_status) & DMA_DONE) - bfin_write16(&src_ch->cfg, 0); } - } + /* Force a sync in case a previous config reset on this channel + * occurred. This is needed so subsequent writes to DMA registers + * are not spuriously lost/corrupted. + */ + __builtin_bfin_ssync(); + /* Destination */ bfin_write32(&dst_ch->start_addr, dst); bfin_write16(&dst_ch->x_count, size >> 2); diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index beffa00..6b94462 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -686,14 +686,12 @@ void bfin_gpio_pm_hibernate_restore(void) *port_fer[bank] = gpio_bank_saved[bank].fer; #endif gpio_array[bank]->inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->data_set = gpio_bank_saved[bank].data + & gpio_bank_saved[bank].dir; gpio_array[bank]->dir = gpio_bank_saved[bank].dir; gpio_array[bank]->polar = gpio_bank_saved[bank].polar; gpio_array[bank]->edge = gpio_bank_saved[bank].edge; gpio_array[bank]->both = gpio_bank_saved[bank].both; - - gpio_array[bank]->data_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; - gpio_array[bank]->maska = gpio_bank_saved[bank].maska; } AWA_DUMMY_READ(maska); diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index d6c0677..685f160 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -72,13 +72,24 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) } /* Cover L1 memory. One 4M area for code and data each is enough. */ - if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { - d_tbl[i_d].addr = L1_DATA_A_START; - d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + if (cpu == 0) { + if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { + d_tbl[i_d].addr = L1_DATA_A_START; + d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + } + i_tbl[i_i].addr = L1_CODE_START; + i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; } - i_tbl[i_i].addr = L1_CODE_START; - i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; - +#ifdef CONFIG_SMP + else { + if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { + d_tbl[i_d].addr = COREB_L1_DATA_A_START; + d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; + } + i_tbl[i_i].addr = COREB_L1_CODE_START; + i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; + } +#endif first_switched_dcplb = i_d; first_switched_icplb = i_i; diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 79cad0a..9da36ba 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -361,7 +361,7 @@ static inline int in_mem_const(unsigned long addr, unsigned long size, unsigned long const_addr, unsigned long const_size) { - return in_mem_const_off(addr, 0, size, const_addr, const_size); + return in_mem_const_off(addr, size, 0, const_addr, const_size); } #define IN_ASYNC(bnum, bctlnum) \ ({ \ @@ -390,13 +390,13 @@ int bfin_mem_access_type(unsigned long addr, unsigned long size) if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; #ifdef COREB_L1_CODE_START - if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; - if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; - if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; #endif if (in_mem_const(addr, size, L2_START, L2_LENGTH)) @@ -472,13 +472,13 @@ int _access_ok(unsigned long addr, unsigned long size) if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH)) return 1; #ifdef COREB_L1_CODE_START - if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) return 1; if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) return 1; - if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) return 1; - if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) + if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) return 1; #endif if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 6136c33..6225eda 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -168,7 +168,6 @@ void __cpuinit bfin_setup_cpudata(unsigned int cpu) struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu); cpudata->idle = current; - cpudata->loops_per_jiffy = loops_per_jiffy; cpudata->imemctl = bfin_read_IMEM_CONTROL(); cpudata->dmemctl = bfin_read_DMEM_CONTROL(); } @@ -568,17 +567,23 @@ static __init void memory_setup(void) # endif /* ANOMALY_05000263 */ # endif /* CONFIG_ROMFS_FS */ - memory_end -= mtd_size; - - if (mtd_size == 0) { - console_init(); - panic("Don't boot kernel without rootfs attached."); + /* Since the default MTD_UCLINUX has no magic number, we just blindly + * read 8 past the end of the kernel's image, and look at it. + * When no image is attached, mtd_size is set to a random number + * Do some basic sanity checks before operating on things + */ + if (mtd_size == 0 || memory_end <= mtd_size) { + pr_emerg("Could not find valid ram mtd attached.\n"); + } else { + memory_end -= mtd_size; + + /* Relocate MTD image to the top of memory after the uncached memory area */ + uclinux_ram_map.phys = memory_mtd_start = memory_end; + uclinux_ram_map.size = mtd_size; + pr_info("Found mtd parition at 0x%p, (len=0x%lx), moving to 0x%p\n", + _end, mtd_size, (void *)memory_mtd_start); + dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size); } - - /* Relocate MTD image to the top of memory after the uncached memory area */ - uclinux_ram_map.phys = memory_mtd_start = memory_end; - uclinux_ram_map.size = mtd_size; - dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size); #endif /* CONFIG_MTD_UCLINUX */ #if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) @@ -868,13 +873,6 @@ void __init setup_arch(char **cmdline_p) else printk(KERN_CONT "and Disabled\n"); -#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) - /* we need to initialize the Flashrom device here since we might - * do things with flash early on in the boot - */ - flash_probe(); -#endif - printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); /* Newer parts mirror SWRST bits in SYSCR */ @@ -938,10 +936,6 @@ void __init setup_arch(char **cmdline_p) CPU, bfin_revid()); } - /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ - if (bfin_cpuid() == 0x27de && bfin_revid() == 1) - panic("You can't run on this processor due to 05000448"); - printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", @@ -1164,9 +1158,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) sclk/1000000, sclk%1000000); seq_printf(m, "bogomips\t: %lu.%02lu\n" "Calibration\t: %lu loops\n", - (cpudata->loops_per_jiffy * HZ) / 500000, - ((cpudata->loops_per_jiffy * HZ) / 5000) % 100, - (cpudata->loops_per_jiffy * HZ)); + (loops_per_jiffy * HZ) / 500000, + ((loops_per_jiffy * HZ) / 5000) % 100, + (loops_per_jiffy * HZ)); /* Check Cache configutation */ switch (cpudata->dmemctl & (1 << DMC0_P | 1 << DMC1_P)) { diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 8a1caf2..bf2b2d1 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -570,11 +570,12 @@ asmlinkage void trap_c(struct pt_regs *fp) if (kernel_mode_regs(fp) || (current && !current->mm)) { console_verbose(); oops_in_progress = 1; - if (strerror) - verbose_printk(strerror); } if (sig != SIGTRAP) { + if (strerror) + verbose_printk(strerror); + dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); @@ -619,7 +620,9 @@ asmlinkage void trap_c(struct pt_regs *fp) force_sig_info(sig, &info, current); } - if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) + if ((ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) || + (ANOMALY_05000281 && trapnr == VEC_HWERR) || + (ANOMALY_05000189 && (trapnr == VEC_CPLB_I_VL || trapnr == VEC_CPLB_VL))) fp->pc = SAFE_USER_INSTRUCTION; traps_done: diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c index 84b9c55..e57bf6f 100644 --- a/arch/blackfin/lib/lshrdi3.c +++ b/arch/blackfin/lib/lshrdi3.c @@ -27,21 +27,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define BITS_PER_UNIT 8 - -typedef int SItype __attribute__ ((mode(SI))); -typedef unsigned int USItype __attribute__ ((mode(SI))); -typedef int DItype __attribute__ ((mode(DI))); -typedef int word_type __attribute__ ((mode(__word__))); - -struct DIstruct { - SItype high, low; -}; - -typedef union { - struct DIstruct s; - DItype ll; -} DIunion; +#include "gcclib.h" #ifdef CONFIG_ARITHMETIC_OPS_L1 DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text)); diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index d979110..809be26 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -534,7 +534,7 @@ static struct platform_device i2c_bfin_twi_device = { #endif static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h index 426e064..753ed81 100644 --- a/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h @@ -82,6 +82,7 @@ #define ANOMALY_05000179 (0) #define ANOMALY_05000182 (0) #define ANOMALY_05000183 (0) +#define ANOMALY_05000189 (0) #define ANOMALY_05000198 (0) #define ANOMALY_05000202 (0) #define ANOMALY_05000215 (0) @@ -117,6 +118,7 @@ #define ANOMALY_05000357 (0) #define ANOMALY_05000362 (1) #define ANOMALY_05000363 (0) +#define ANOMALY_05000364 (0) #define ANOMALY_05000371 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000386 (0) diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h index 0fb2ce5..dbade93 100644 --- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index f4867ce..b09484f 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -793,7 +793,7 @@ static struct platform_device i2c_bfin_twi_device = { #endif static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), .type = "pcf8574_lcd", diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index b2f30f0..2ad68cd 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -591,7 +591,7 @@ static struct platform_device i2c_bfin_twi_device = { #endif static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 799a1d1..75e563d 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -858,7 +858,7 @@ static struct platform_device i2c_bfin_twi_device = { #endif static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h index 0d63f74..c438ca8 100644 --- a/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h @@ -176,6 +176,8 @@ #define ANOMALY_05000443 (1) /* The WURESET Bit in the SYSCR Register is not Functional */ #define ANOMALY_05000445 (1) +/* USB DMA Short Packet Data Corruption */ +#define ANOMALY_05000450 (1) /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */ #define ANOMALY_05000451 (1) /* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */ @@ -201,6 +203,7 @@ #define ANOMALY_05000179 (0) #define ANOMALY_05000182 (0) #define ANOMALY_05000183 (0) +#define ANOMALY_05000189 (0) #define ANOMALY_05000198 (0) #define ANOMALY_05000202 (0) #define ANOMALY_05000215 (0) @@ -238,6 +241,5 @@ #define ANOMALY_05000412 (0) #define ANOMALY_05000447 (0) #define ANOMALY_05000448 (0) -#define ANOMALY_05000450 (0) #endif diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index a625659..ebd6ceb 100644 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index a68ade8..3d743cc 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -453,7 +453,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .irq = 39, }, #endif -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf533/include/mach/anomaly.h b/arch/blackfin/mach-bf533/include/mach/anomaly.h index 70a0ad6..cd83db2 100644 --- a/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf533/include/mach/anomaly.h @@ -335,6 +335,7 @@ #define ANOMALY_05000323 (0) #define ANOMALY_05000353 (1) #define ANOMALY_05000362 (1) +#define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000386 (1) #define ANOMALY_05000389 (0) diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index a3789d7..4062e24 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index c1f76dd..bd65690 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1313,10 +1313,10 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) { I2C_BOARD_INFO("ad7142_joystick", 0x2C), - .irq = IRQ_PF5, + .irq = IRQ_PG5, }, #endif -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h index 57c128c..e66aa13 100644 --- a/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h @@ -167,6 +167,7 @@ #define ANOMALY_05000179 (0) #define ANOMALY_05000182 (0) #define ANOMALY_05000183 (0) +#define ANOMALY_05000189 (0) #define ANOMALY_05000198 (0) #define ANOMALY_05000202 (0) #define ANOMALY_05000215 (0) @@ -186,6 +187,7 @@ #define ANOMALY_05000353 (1) #define ANOMALY_05000362 (1) #define ANOMALY_05000363 (0) +#define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000386 (1) #define ANOMALY_05000389 (0) diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index b86662f..e95d54f 100644 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h index c97acdf..451cf8a 100644 --- a/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h @@ -137,6 +137,7 @@ #define ANOMALY_05000158 (0) #define ANOMALY_05000171 (0) #define ANOMALY_05000182 (0) +#define ANOMALY_05000189 (0) #define ANOMALY_05000198 (0) #define ANOMALY_05000202 (0) #define ANOMALY_05000215 (0) @@ -160,6 +161,7 @@ #define ANOMALY_05000353 (1) #define ANOMALY_05000362 (1) #define ANOMALY_05000363 (0) +#define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000386 (1) #define ANOMALY_05000389 (0) diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h index c536551..999f239 100644 --- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 81f5b95..dc0dd9b 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -864,7 +864,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { -#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h index 18a4cd24..cd040fe 100644 --- a/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h @@ -195,6 +195,7 @@ #define ANOMALY_05000179 (0) #define ANOMALY_05000182 (0) #define ANOMALY_05000183 (0) +#define ANOMALY_05000189 (0) #define ANOMALY_05000198 (0) #define ANOMALY_05000202 (0) #define ANOMALY_05000215 (0) @@ -226,6 +227,7 @@ #define ANOMALY_05000323 (0) #define ANOMALY_05000362 (1) #define ANOMALY_05000363 (0) +#define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000400 (0) #define ANOMALY_05000412 (0) diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h index 94b8e27..a5312b2 100644 --- a/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h @@ -288,6 +288,7 @@ #define ANOMALY_05000273 (0) #define ANOMALY_05000311 (0) #define ANOMALY_05000353 (1) +#define ANOMALY_05000364 (0) #define ANOMALY_05000380 (0) #define ANOMALY_05000386 (1) #define ANOMALY_05000389 (0) diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index a1b5087..fd5e887 100644 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h @@ -53,7 +53,7 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) +#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) diff --git a/arch/blackfin/mach-bf561/include/mach/mem_map.h b/arch/blackfin/mach-bf561/include/mach/mem_map.h index a63e15c..5b96ea5 100644 --- a/arch/blackfin/mach-bf561/include/mach/mem_map.h +++ b/arch/blackfin/mach-bf561/include/mach/mem_map.h @@ -37,7 +37,6 @@ /* Memory Map for ADSP-BF561 processors */ -#ifdef CONFIG_BF561 #define COREA_L1_CODE_START 0xFFA00000 #define COREA_L1_DATA_A_START 0xFF800000 #define COREA_L1_DATA_B_START 0xFF900000 @@ -74,6 +73,28 @@ #define BFIN_DCACHESIZE (0*1024) #define BFIN_DSUPBANKS 0 #endif /*CONFIG_BFIN_DCACHE*/ + +/* + * If we are in SMP mode, then the cache settings of Core B will match + * the settings of Core A. If we aren't, then we assume Core B is not + * using any cache. This allows the rest of the kernel to work with + * the core in either mode as we are only loading user code into it and + * it is the user's problem to make sure they aren't doing something + * stupid there. + * + * Note that we treat the L1 code region as a contiguous blob to make + * the rest of the kernel simpler. Easier to check one region than a + * bunch of small ones. Again, possible misbehavior here is the fault + * of the user -- don't try to use memory that doesn't exist. + */ +#ifdef CONFIG_SMP +# define COREB_L1_CODE_LENGTH L1_CODE_LENGTH +# define COREB_L1_DATA_A_LENGTH L1_DATA_A_LENGTH +# define COREB_L1_DATA_B_LENGTH L1_DATA_B_LENGTH +#else +# define COREB_L1_CODE_LENGTH 0x14000 +# define COREB_L1_DATA_A_LENGTH 0x8000 +# define COREB_L1_DATA_B_LENGTH 0x8000 #endif /* Level 2 Memory */ diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 5a4e7c7..fb1795d 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -218,7 +218,7 @@ ENTRY(_ex_single_step) /* Single stepping only a single instruction, so clear the trace * bit here. */ r7 = syscfg; - bitclr (r7, 0); + bitclr (r7, SYSCFG_SSSTEP_P); syscfg = R7; jump _ex_trap_c; @@ -251,7 +251,7 @@ ENTRY(_ex_single_step) if !cc jump _bfin_return_from_exception; r7 = syscfg; - bitclr (r7, 0); + bitclr (r7, SYSCFG_SSSTEP_P); /* Turn off single step */ syscfg = R7; /* Fall through to _bfin_return_from_exception. */ @@ -342,9 +342,11 @@ ENTRY(_ex_trap_c) r6 = retx; [p5 + PDA_RETX] = r6; #endif + /* Save the state of single stepping */ r6 = SYSCFG; [p5 + PDA_SYSCFG] = r6; - BITCLR(r6, 0); + /* Clear it while we handle the exception in IRQ5 mode */ + BITCLR(r6, SYSCFG_SSSTEP_P); SYSCFG = r6; /* Disable all interrupts, but make sure level 5 is enabled so @@ -367,7 +369,7 @@ ENDPROC(_ex_trap_c) * exception. This is a unrecoverable event, so crash. * Note: this cannot be ENTRY() as we jump here with "if cc jump" ... */ -_double_fault: +ENTRY(_double_fault) /* Turn caches & protection off, to ensure we don't get any more * double exceptions */ @@ -872,7 +874,7 @@ ENTRY(_ret_from_exception) raise 15; /* raise evt15 to do signal or reschedule */ 4: r0 = syscfg; - bitclr(r0, 0); + bitclr(r0, SYSCFG_SSSTEP_P); /* Turn off single step */ syscfg = r0; 5: rts; diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 6184005..349ee3f 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -211,6 +211,8 @@ int smp_call_function(void (*func)(void *info), void *info, int wait) return 0; msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + if (!msg) + return -ENOMEM; INIT_LIST_HEAD(&msg->list); msg->call_struct.func = func; msg->call_struct.info = info; @@ -252,6 +254,8 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, cpu_set(cpu, callmap); msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + if (!msg) + return -ENOMEM; INIT_LIST_HEAD(&msg->list); msg->call_struct.func = func; msg->call_struct.info = info; @@ -287,6 +291,8 @@ void smp_send_reschedule(int cpu) return; msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + if (!msg) + return; memset(msg, 0, sizeof(msg)); INIT_LIST_HEAD(&msg->list); msg->type = BFIN_IPI_RESCHEDULE; @@ -314,6 +320,8 @@ void smp_send_stop(void) return; msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + if (!msg) + return; memset(msg, 0, sizeof(msg)); INIT_LIST_HEAD(&msg->list); msg->type = BFIN_IPI_CPU_STOP; @@ -450,7 +458,7 @@ void __init smp_cpus_done(unsigned int max_cpus) unsigned int cpu; for_each_online_cpu(cpu) - bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; + bogosum += loops_per_jiffy; printk(KERN_INFO "SMP: Total of %d processors activated " "(%lu.%02lu BogoMIPS).\n", diff --git a/arch/cris/include/asm/pgalloc.h b/arch/cris/include/asm/pgalloc.h index a1ba761..6da975d 100644 --- a/arch/cris/include/asm/pgalloc.h +++ b/arch/cris/include/asm/pgalloc.h @@ -47,7 +47,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) __free_page(pte); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,address) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb), pte); \ diff --git a/arch/frv/include/asm/pgalloc.h b/arch/frv/include/asm/pgalloc.h index 971e6ad..416d19a 100644 --- a/arch/frv/include/asm/pgalloc.h +++ b/arch/frv/include/asm/pgalloc.h @@ -49,7 +49,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) __free_page(pte); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,address) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb),(pte)); \ @@ -62,7 +62,7 @@ do { \ */ #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *) 2); }) #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb,x) do { } while (0) +#define __pmd_free_tlb(tlb,x,a) do { } while (0) #endif /* CONFIG_MMU */ diff --git a/arch/frv/include/asm/pgtable.h b/arch/frv/include/asm/pgtable.h index 3323301..22c6069 100644 --- a/arch/frv/include/asm/pgtable.h +++ b/arch/frv/include/asm/pgtable.h @@ -225,7 +225,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) */ #define pud_alloc_one(mm, address) NULL #define pud_free(mm, x) do { } while (0) -#define __pud_free_tlb(tlb, x) do { } while (0) +#define __pud_free_tlb(tlb, x, address) do { } while (0) /* * The "pud_xxx()" functions here are trivial for a folded two-level diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h index b9ac1a6..96a8d92 100644 --- a/arch/ia64/include/asm/pgalloc.h +++ b/arch/ia64/include/asm/pgalloc.h @@ -48,7 +48,7 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud) { quicklist_free(0, NULL, pud); } -#define __pud_free_tlb(tlb, pud) pud_free((tlb)->mm, pud) +#define __pud_free_tlb(tlb, pud, address) pud_free((tlb)->mm, pud) #endif /* CONFIG_PGTABLE_4 */ static inline void @@ -67,7 +67,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) quicklist_free(0, NULL, pmd); } -#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd) +#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd) static inline void pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, pgtable_t pte) @@ -117,6 +117,6 @@ static inline void check_pgt_cache(void) quicklist_trim(0, NULL, 25, 16); } -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte) +#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) #endif /* _ASM_IA64_PGALLOC_H */ diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index 20d8a39..85d965c 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -236,22 +236,22 @@ do { \ __tlb_remove_tlb_entry(tlb, ptep, addr); \ } while (0) -#define pte_free_tlb(tlb, ptep) \ +#define pte_free_tlb(tlb, ptep, address) \ do { \ tlb->need_flush = 1; \ - __pte_free_tlb(tlb, ptep); \ + __pte_free_tlb(tlb, ptep, address); \ } while (0) -#define pmd_free_tlb(tlb, ptep) \ +#define pmd_free_tlb(tlb, ptep, address) \ do { \ tlb->need_flush = 1; \ - __pmd_free_tlb(tlb, ptep); \ + __pmd_free_tlb(tlb, ptep, address); \ } while (0) -#define pud_free_tlb(tlb, pudp) \ +#define pud_free_tlb(tlb, pudp, address) \ do { \ tlb->need_flush = 1; \ - __pud_free_tlb(tlb, pudp); \ + __pud_free_tlb(tlb, pudp, address); \ } while (0) #endif /* _ASM_IA64_TLB_H */ diff --git a/arch/m32r/include/asm/pgalloc.h b/arch/m32r/include/asm/pgalloc.h index f11a2b9..0fc7361 100644 --- a/arch/m32r/include/asm/pgalloc.h +++ b/arch/m32r/include/asm/pgalloc.h @@ -58,7 +58,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) __free_page(pte); } -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte)) +#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte)) /* * allocating and freeing a pmd is trivial: the 1-entry pmd is @@ -68,7 +68,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb, x) do { } while (0) +#define __pmd_free_tlb(tlb, x, addr) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() #define check_pgt_cache() do { } while (0) diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h index d08bf62..15ee4c7 100644 --- a/arch/m68k/include/asm/motorola_pgalloc.h +++ b/arch/m68k/include/asm/motorola_pgalloc.h @@ -54,7 +54,8 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t page) __free_page(page); } -static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page) +static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page, + unsigned long address) { pgtable_page_dtor(page); cache_page(kmap(page)); @@ -73,7 +74,8 @@ static inline int pmd_free(struct mm_struct *mm, pmd_t *pmd) return free_pointer_table(pmd); } -static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, + unsigned long address) { return free_pointer_table(pmd); } diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h index d4c83f1..48d80d5 100644 --- a/arch/m68k/include/asm/sun3_pgalloc.h +++ b/arch/m68k/include/asm/sun3_pgalloc.h @@ -32,7 +32,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t page) __free_page(page); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,addr) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb), pte); \ @@ -80,7 +80,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page * inside the pgd, so has no extra memory associated with it. */ #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb, x) do { } while (0) +#define __pmd_free_tlb(tlb, x, addr) do { } while (0) static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index d0bcf80..8439598 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -6,14 +6,16 @@ endif # What CPU vesion are we building for, and crack it open # as major.minor.rev -CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) ) -CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1) -CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2) -CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3) +CPU_VER := $(shell echo $(CONFIG_XILINX_MICROBLAZE0_HW_VER)) +CPU_MAJOR := $(shell echo $(CPU_VER) | cut -d '.' -f 1) +CPU_MINOR := $(shell echo $(CPU_VER) | cut -d '.' -f 2) +CPU_REV := $(shell echo $(CPU_VER) | cut -d '.' -f 3) export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV # Use cpu-related CONFIG_ vars to set compile options. +# The various CONFIG_XILINX cpu features options are integers 0/1/2... +# rather than bools y/n # Work out HW multipler support. This is icky. # 1. Spartan2 has no HW multiplers. @@ -34,30 +36,29 @@ CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) -# The various CONFIG_XILINX cpu features options are integers 0/1/2... -# rather than bools y/n - # r31 holds current when in kernel mode -CFLAGS_KERNEL += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2) +KBUILD_KERNEL += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2) LDFLAGS := LDFLAGS_vmlinux := -LDFLAGS_BLOB := --format binary --oformat elf32-microblaze -LIBGCC := $(shell $(CC) $(CFLAGS_KERNEL) -print-libgcc-file-name) +LIBGCC := $(shell $(CC) $(KBUILD_KERNEL) -print-libgcc-file-name) -head-y := arch/microblaze/kernel/head.o -libs-y += arch/microblaze/lib/ $(LIBGCC) -core-y += arch/microblaze/kernel/ arch/microblaze/mm/ \ - arch/microblaze/platform/ +head-y := arch/microblaze/kernel/head.o +libs-y += arch/microblaze/lib/ +libs-y += $(LIBGCC) +core-y += arch/microblaze/kernel/ +core-y += arch/microblaze/mm/ +core-y += arch/microblaze/platform/ -boot := arch/$(ARCH)/boot +boot := arch/microblaze/boot # defines filename extension depending memory management type ifeq ($(CONFIG_MMU),) -MMUEXT := -nommu +MMU := -nommu endif -export MMUEXT + +export MMU all: linux.bin diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 5c17342..7c3ec13 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -14,7 +14,6 @@ #include <asm/byteorder.h> #include <asm/page.h> #include <linux/types.h> -#include <asm/byteorder.h> #include <linux/mm.h> /* Get struct page {...} */ diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index 59a757e..b0131da 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h @@ -180,7 +180,7 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage) __free_page(ptepage); } -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte)) +#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte)) #define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte)) @@ -193,7 +193,7 @@ extern inline void pte_free(struct mm_struct *mm, struct page *ptepage) */ #define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) /*#define pmd_free(mm, x) do { } while (0)*/ -#define __pmd_free_tlb(tlb, x) do { } while (0) +#define __pmd_free_tlb(tlb, x, addr) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() extern int do_check_pgt_cache(int, int); diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index 4c57a58..cc3a4df 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -185,6 +185,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } /* Definitions for MicroBlaze. */ #define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ +#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */ #define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ #define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ #define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ @@ -320,8 +321,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -/* FIXME */ -static inline int pte_file(pte_t pte) { return 0; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } @@ -488,7 +488,7 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) /* Encode and decode a nonlinear file mapping entry */ #define PTE_FILE_MAX_BITS 29 #define pte_to_pgoff(pte) (pte_val(pte) >> 3) -#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) }) +#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE }) extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 20f7b3a..37e6f30 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -16,6 +16,18 @@ #define _ASM_MICROBLAZE_PROM_H #ifdef __KERNEL__ +/* Definitions used by the flattened device tree */ +#define OF_DT_HEADER 0xd00dfeed /* marker */ +#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ +#define OF_DT_END_NODE 0x2 /* End node */ +#define OF_DT_PROP 0x3 /* Property: name off, size, content */ +#define OF_DT_NOP 0x4 /* nop */ +#define OF_DT_END 0x9 + +#define OF_DT_VERSION 0x10 + +#ifndef __ASSEMBLY__ + #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/platform_device.h> @@ -29,16 +41,6 @@ #define of_prop_cmp(s1, s2) strcmp((s1), (s2)) #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) -/* Definitions used by the flattened device tree */ -#define OF_DT_HEADER 0xd00dfeed /* marker */ -#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ -#define OF_DT_END_NODE 0x2 /* End node */ -#define OF_DT_PROP 0x3 /* Property: name off, size, content */ -#define OF_DT_NOP 0x4 /* nop */ -#define OF_DT_END 0x9 - -#define OF_DT_VERSION 0x10 - /* * This is what gets passed to the kernel by prom_init or kexec * @@ -309,5 +311,6 @@ extern void __iomem *of_iomap(struct device_node *device, int index); */ #include <linux/of.h> +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h index c472d28..e8abd4a 100644 --- a/arch/microblaze/include/asm/tlb.h +++ b/arch/microblaze/include/asm/tlb.h @@ -11,7 +11,7 @@ #ifndef _ASM_MICROBLAZE_TLB_H #define _ASM_MICROBLAZE_TLB_H -#define tlb_flush(tlb) do {} while (0) +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) #include <asm-generic/tlb.h> diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 65adad6..5431b46 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h @@ -189,7 +189,7 @@ extern long strnlen_user(const char *src, long count); #define __put_user(x, ptr) \ ({ \ - __typeof__(*(ptr)) __gu_val = x; \ + __typeof__(*(ptr)) volatile __gu_val = (x); \ long __gu_err = 0; \ switch (sizeof(__gu_val)) { \ case 1: \ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index f4a5e19..d487729 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -17,4 +17,4 @@ obj-$(CONFIG_HEART_BEAT) += heartbeat.o obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o obj-$(CONFIG_MMU) += misc.o -obj-y += entry$(MMUEXT).o +obj-y += entry$(MMU).o diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c index 153f57c..c259786 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -22,7 +22,7 @@ #define CI(c, p) { ci->c = PVR_##p(pvr); } #define err_printk(x) \ - early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n"); + early_printk("ERROR: Microblaze " x "-different for PVR and DTS\n"); void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) { diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c index 450ca6b..adb448f 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -18,7 +18,7 @@ static const char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY; static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; #define err_printk(x) \ - early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n"); + early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n"); void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) { diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index a10bea1..c411c67 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -26,6 +26,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = { {"7.10.b", 0x09}, {"7.10.c", 0x0a}, {"7.10.d", 0x0b}, + {"7.20.a", 0x0c}, + {"7.20.b", 0x0d}, /* FIXME There is no keycode defined in MBV for these versions */ {"2.10.a", 0x10}, {"3.00.a", 0x20}, diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index e568d6e..e41c6ce 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S @@ -31,6 +31,7 @@ #include <linux/linkage.h> #include <asm/thread_info.h> #include <asm/page.h> +#include <asm/prom.h> /* for OF_DT_HEADER */ #ifdef CONFIG_MMU #include <asm/setup.h> /* COMMAND_LINE_SIZE */ @@ -54,11 +55,19 @@ ENTRY(_start) andi r1, r1, ~2 mts rmsr, r1 -/* save fdt to kernel location */ -/* r7 stores pointer to fdt blob */ - beqi r7, no_fdt_arg +/* r7 may point to an FDT, or there may be one linked in. + if it's in r7, we've got to save it away ASAP. + We ensure r7 points to a valid FDT, just in case the bootloader + is broken or non-existent */ + beqi r7, no_fdt_arg /* NULL pointer? don't copy */ + lw r11, r0, r7 /* Does r7 point to a */ + rsubi r11, r11, OF_DT_HEADER /* valid FDT? */ + beqi r11, _prepare_copy_fdt + or r7, r0, r0 /* clear R7 when not valid DTB */ + bnei r11, no_fdt_arg /* No - get out of here */ +_prepare_copy_fdt: or r11, r0, r0 /* incremment */ - ori r4, r0, TOPHYS(_fdt_start) /* save bram context */ + ori r4, r0, TOPHYS(_fdt_start) ori r3, r0, (0x4000 - 4) _copy_fdt: lw r12, r7, r11 /* r12 = r7 + r11 */ diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 9d591cd..3288c97 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -74,6 +74,7 @@ #include <asm/mmu.h> #include <asm/pgtable.h> +#include <asm/signal.h> #include <asm/asm-offsets.h> /* Helpful Macros */ @@ -428,19 +429,9 @@ handle_unaligned_ex: mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ nop _no_delayslot: -#endif - -#ifdef CONFIG_MMU - /* Check if unaligned address is last on a 4k page */ - andi r5, r4, 0xffc - xori r5, r5, 0xffc - bnei r5, _unaligned_ex2 - _unaligned_ex1: - RESTORE_STATE; -/* Another page must be accessed or physical address not in page table */ - bri unaligned_data_trap - - _unaligned_ex2: + /* jump to high level unaligned handler */ + RESTORE_STATE; + bri unaligned_data_trap #endif andi r6, r3, 0x3E0; /* Mask and extract the register operand */ srl r6, r6; /* r6 >> 5 */ @@ -450,45 +441,6 @@ _no_delayslot: srl r6, r6; /* Store the register operand in a temporary location */ sbi r6, r0, TOPHYS(ex_reg_op); -#ifdef CONFIG_MMU - /* Get physical address */ - /* If we are faulting a kernel address, we have to use the - * kernel page tables. - */ - ori r5, r0, CONFIG_KERNEL_START - cmpu r5, r4, r5 - bgti r5, _unaligned_ex3 - ori r5, r0, swapper_pg_dir - bri _unaligned_ex4 - - /* Get the PGD for the current thread. */ -_unaligned_ex3: /* user thread */ - addi r5 ,CURRENT_TASK, TOPHYS(0); /* get current task address */ - lwi r5, r5, TASK_THREAD + PGDIR -_unaligned_ex4: - tophys(r5,r5) - BSRLI(r6,r4,20) /* Create L1 (pgdir/pmd) address */ - andi r6, r6, 0xffc -/* Assume pgdir aligned on 4K boundary, no need for "andi r5,r5,0xfffff003" */ - or r5, r5, r6 - lwi r6, r5, 0 /* Get L1 entry */ - andi r5, r6, 0xfffff000 /* Extract L2 (pte) base address. */ - beqi r5, _unaligned_ex1 /* Bail if no table */ - - tophys(r5,r5) - BSRLI(r6,r4,10) /* Compute PTE address */ - andi r6, r6, 0xffc - andi r5, r5, 0xfffff003 - or r5, r5, r6 - lwi r5, r5, 0 /* Get Linux PTE */ - - andi r6, r5, _PAGE_PRESENT - beqi r6, _unaligned_ex1 /* Bail if no page */ - - andi r5, r5, 0xfffff000 /* Extract RPN */ - andi r4, r4, 0x00000fff /* Extract offset */ - or r4, r4, r5 /* Create physical address */ -#endif /* CONFIG_MMU */ andi r6, r3, 0x400; /* Extract ESR[S] */ bnei r6, ex_sw; @@ -959,15 +911,15 @@ _unaligned_data_exception: andi r6, r3, 0x800; /* Extract ESR[W] - delay slot */ ex_lw_vm: beqid r6, ex_lhw_vm; - lbui r5, r4, 0; /* Exception address in r4 - delay slot */ +load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */ /* Load a word, byte-by-byte from destination address and save it in tmp space*/ la r6, r0, ex_tmp_data_loc_0; sbi r5, r6, 0; - lbui r5, r4, 1; +load2: lbui r5, r4, 1; sbi r5, r6, 1; - lbui r5, r4, 2; +load3: lbui r5, r4, 2; sbi r5, r6, 2; - lbui r5, r4, 3; +load4: lbui r5, r4, 3; sbi r5, r6, 3; brid ex_lw_tail_vm; /* Get the destination register value into r3 - delay slot */ @@ -977,7 +929,7 @@ ex_lhw_vm: * save it in tmp space */ la r6, r0, ex_tmp_data_loc_0; sbi r5, r6, 0; - lbui r5, r4, 1; +load5: lbui r5, r4, 1; sbi r5, r6, 1; lhui r3, r6, 0; /* Get the destination register value into r3 */ ex_lw_tail_vm: @@ -996,22 +948,53 @@ ex_sw_tail_vm: swi r3, r5, 0; /* Get the word - delay slot */ /* Store the word, byte-by-byte into destination address */ lbui r3, r5, 0; - sbi r3, r4, 0; +store1: sbi r3, r4, 0; lbui r3, r5, 1; - sbi r3, r4, 1; +store2: sbi r3, r4, 1; lbui r3, r5, 2; - sbi r3, r4, 2; +store3: sbi r3, r4, 2; lbui r3, r5, 3; brid ret_from_exc; - sbi r3, r4, 3; /* Delay slot */ +store4: sbi r3, r4, 3; /* Delay slot */ ex_shw_vm: /* Store the lower half-word, byte-by-byte into destination address */ lbui r3, r5, 2; - sbi r3, r4, 0; +store5: sbi r3, r4, 0; lbui r3, r5, 3; brid ret_from_exc; - sbi r3, r4, 1; /* Delay slot */ +store6: sbi r3, r4, 1; /* Delay slot */ ex_sw_end_vm: /* Exception handling of store word, ends. */ + +/* We have to prevent cases that get/put_user macros get unaligned pointer + * to bad page area. We have to find out which origin instruction caused it + * and called fixup for that origin instruction not instruction in unaligned + * handler */ +ex_unaligned_fixup: + ori r5, r7, 0 /* setup pointer to pt_regs */ + lwi r6, r7, PT_PC; /* faulting address is one instruction above */ + addik r6, r6, -4 /* for finding proper fixup */ + swi r6, r7, PT_PC; /* a save back it to PT_PC */ + addik r7, r0, SIGSEGV + /* call bad_page_fault for finding aligned fixup, fixup address is saved + * in PT_PC which is used as return address from exception */ + la r15, r0, ret_from_exc-8 /* setup return address */ + brid bad_page_fault + nop + +/* We prevent all load/store because it could failed any attempt to access */ +.section __ex_table,"a"; + .word load1,ex_unaligned_fixup; + .word load2,ex_unaligned_fixup; + .word load3,ex_unaligned_fixup; + .word load4,ex_unaligned_fixup; + .word load5,ex_unaligned_fixup; + .word store1,ex_unaligned_fixup; + .word store2,ex_unaligned_fixup; + .word store3,ex_unaligned_fixup; + .word store4,ex_unaligned_fixup; + .word store5,ex_unaligned_fixup; + .word store6,ex_unaligned_fixup; +.previous; .end _unaligned_data_exception #endif /* CONFIG_MMU */ diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c index 5141417..5a45b1a 100644 --- a/arch/microblaze/kernel/module.c +++ b/arch/microblaze/kernel/module.c @@ -57,7 +57,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; unsigned long int *location; - unsigned long int locoffs; unsigned long int value; #if __GNUC__ < 4 unsigned long int old_value; @@ -113,10 +112,12 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, break; case R_MICROBLAZE_64_PCREL: - locoffs = (location[0] & 0xFFFF) << 16 | +#if __GNUC__ < 4 + old_value = (location[0] & 0xFFFF) << 16 | (location[1] & 0xFFFF); - value -= (unsigned long int)(location) + 4 + - locoffs; + value -= old_value; +#endif + value -= (unsigned long int)(location) + 4; location[0] = (location[0] & 0xFFFF0000) | (value >> 16); location[1] = (location[1] & 0xFFFF0000) | @@ -125,6 +126,14 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, value); break; + case R_MICROBLAZE_32_PCREL_LO: + pr_debug("R_MICROBLAZE_32_PCREL_LO\n"); + break; + + case R_MICROBLAZE_64_NONE: + pr_debug("R_MICROBLAZE_NONE\n"); + break; + case R_MICROBLAZE_NONE: pr_debug("R_MICROBLAZE_NONE\n"); break; @@ -133,7 +142,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, printk(KERN_ERR "module %s: " "Unknown relocation: %u\n", module->name, - ELF32_R_TYPE(rela->r_info)); + ELF32_R_TYPE(rela[i].r_info)); return -ENOEXEC; } } diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 8709bea..2a97bf5 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -138,8 +138,12 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, setup_early_printk(NULL); #endif - early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt); - printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt); + early_printk("Ramdisk addr 0x%08x, ", ram); + if (fdt) + early_printk("FDT at 0x%08x\n", fdt); + else + early_printk("Compiled-in FDT at 0x%08x\n", + (unsigned int)_fdt_start); #ifdef CONFIG_MTD_UCLINUX early_printk("Found romfs @ 0x%08x (0x%08x)\n", diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index e000bce..b96f168 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -33,105 +33,6 @@ #include <linux/unistd.h> #include <asm/syscalls.h> -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. This will be remove with new toolchain. - */ -asmlinkage long -sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - ret = -EINVAL; - switch (call) { - case SEMOP: - ret = sys_semop(first, (struct sembuf *)ptr, second); - break; - case SEMGET: - ret = sys_semget(first, second, third); - break; - case SEMCTL: - { - union semun fourth; - - if (!ptr) - break; - ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT) - || (get_user(fourth.__pad, (void **)ptr)) ; - if (ret) - break; - ret = sys_semctl(first, second, third, fourth); - break; - } - case MSGSND: - ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); - break; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - - if (!ptr) - break; - ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp)) - ? 0 : -EFAULT) || copy_from_user(&tmp, - (struct ipc_kludge *) ptr, sizeof(tmp)); - if (ret) - break; - ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, - third); - break; - } - default: - ret = sys_msgrcv(first, (struct msgbuf *) ptr, - second, fifth, third); - break; - } - break; - case MSGGET: - ret = sys_msgget((key_t) first, second); - break; - case MSGCTL: - ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); - break; - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = access_ok(VERIFY_WRITE, (ulong *) third, - sizeof(ulong)) ? 0 : -EFAULT; - if (ret) - break; - ret = do_shmat(first, (char *) ptr, second, &raddr); - if (ret) - break; - ret = put_user(raddr, (ulong *) third); - break; - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - break; - ret = do_shmat(first, (char *) ptr, second, - (ulong *) third); - break; - } - break; - case SHMDT: - ret = sys_shmdt((char *)ptr); - break; - case SHMGET: - ret = sys_shmget(first, second, third); - break; - case SHMCTL: - ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); - break; - } - return ret; -} asmlinkage long microblaze_vfork(struct pt_regs *regs) { diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 31b32a6..216db81 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -121,7 +121,7 @@ ENTRY(sys_call_table) .long sys_wait4 .long sys_swapoff /* 115 */ .long sys_sysinfo - .long sys_ipc + .long sys_ni_syscall /* old sys_ipc */ .long sys_fsync .long sys_ni_syscall /* sys_sigreturn_wrapper */ .long sys_clone /* 120 */ diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c index 956607a..d9d249a 100644 --- a/arch/microblaze/mm/fault.c +++ b/arch/microblaze/mm/fault.c @@ -69,7 +69,7 @@ static int store_updates_sp(struct pt_regs *regs) * It is called from do_page_fault above and from some of the procedures * in traps.c. */ -static void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) { const struct exception_table_entry *fixup; /* MS: no context */ @@ -122,15 +122,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, } #endif /* CONFIG_KGDB */ - if (in_atomic() || mm == NULL) { - /* FIXME */ - if (kernel_mode(regs)) { - printk(KERN_EMERG - "Page fault in kernel mode - Oooou!!! pid %d\n", - current->pid); - _exception(SIGSEGV, regs, code, address); - return; - } + if (in_atomic() || !mm) { + if (kernel_mode(regs)) + goto bad_area_nosemaphore; + /* in_atomic() in user mode is really bad, as is current->mm == NULL. */ printk(KERN_EMERG "Page fault in user mode with " diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 1275831..3738f4b 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -98,23 +98,12 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) __free_pages(pte, PTE_ORDER); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,address) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb), pte); \ } while (0) -#ifdef CONFIG_32BIT - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb, x) do { } while (0) - -#endif - #ifdef CONFIG_64BIT static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) @@ -132,7 +121,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) free_pages((unsigned long)pmd, PMD_ORDER); } -#define __pmd_free_tlb(tlb, x) pmd_free((tlb)->mm, x) +#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x) #endif diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h index ec057e1..a19f113 100644 --- a/arch/mn10300/include/asm/pgalloc.h +++ b/arch/mn10300/include/asm/pgalloc.h @@ -51,6 +51,6 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte) } -#define __pte_free_tlb(tlb, pte) tlb_remove_page((tlb), (pte)) +#define __pte_free_tlb(tlb, pte, addr) tlb_remove_page((tlb), (pte)) #endif /* _ASM_PGALLOC_H */ diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S index c96ba3d..f4aa079 100644 --- a/arch/mn10300/kernel/vmlinux.lds.S +++ b/arch/mn10300/kernel/vmlinux.lds.S @@ -107,7 +107,7 @@ SECTIONS __init_end = .; /* freed after init ends here */ - BSS(4) + BSS_SECTION(0, PAGE_SIZE, 4) _end = . ; diff --git a/arch/parisc/include/asm/tlb.h b/arch/parisc/include/asm/tlb.h index 383b1db..0792490 100644 --- a/arch/parisc/include/asm/tlb.h +++ b/arch/parisc/include/asm/tlb.h @@ -21,7 +21,7 @@ do { if (!(tlb)->fullmm) \ #include <asm-generic/tlb.h> -#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd) -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte) +#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) +#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) #endif diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h index 0815eb4..c9500d6 100644 --- a/arch/powerpc/include/asm/pgalloc-32.h +++ b/arch/powerpc/include/asm/pgalloc-32.h @@ -16,7 +16,7 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); */ /* #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) */ #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb,x) do { } while (0) +#define __pmd_free_tlb(tlb,x,a) do { } while (0) /* #define pgd_populate(mm, pmd, pte) BUG() */ #ifndef CONFIG_BOOKE diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index afda2bd..e6f069c 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -118,11 +118,11 @@ static inline void pgtable_free(pgtable_free_t pgf) kmem_cache_free(pgtable_cache[cachenum], p); } -#define __pmd_free_tlb(tlb, pmd) \ +#define __pmd_free_tlb(tlb, pmd,addr) \ pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) #ifndef CONFIG_PPC_64K_PAGES -#define __pud_free_tlb(tlb, pud) \ +#define __pud_free_tlb(tlb, pud, addr) \ pgtable_free_tlb(tlb, pgtable_free_cache(pud, \ PUD_CACHE_NUM, PUD_TABLE_SIZE-1)) #endif /* CONFIG_PPC_64K_PAGES */ diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h index 5d84802..1730e5e 100644 --- a/arch/powerpc/include/asm/pgalloc.h +++ b/arch/powerpc/include/asm/pgalloc.h @@ -38,14 +38,14 @@ static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum, extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); #ifdef CONFIG_SMP -#define __pte_free_tlb(tlb,ptepage) \ +#define __pte_free_tlb(tlb,ptepage,address) \ do { \ pgtable_page_dtor(ptepage); \ pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ - PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \ + PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \ } while (0) #else -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte)) +#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, (pte)) #endif diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 9920d6a..c46ef2f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -305,7 +305,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, pmd = pmd_offset(pud, start); pud_clear(pud); - pmd_free_tlb(tlb, pmd); + pmd_free_tlb(tlb, pmd, start); } static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, @@ -348,7 +348,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, pud = pud_offset(pgd, start); pgd_clear(pgd); - pud_free_tlb(tlb, pud); + pud_free_tlb(tlb, pud, start); } /* diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 3d8a96d..81150b0 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -96,7 +96,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) * pte_free_tlb frees a pte table and clears the CRSTE for the * page table from the tlb. */ -static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) +static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, + unsigned long address) { if (!tlb->fullmm) { tlb->array[tlb->nr_ptes++] = pte; @@ -113,7 +114,8 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) * as the pgd. pmd_free_tlb checks the asce_limit against 2GB * to avoid the double free of the pmd in this case. */ -static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, + unsigned long address) { #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) @@ -134,7 +136,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) * as the pgd. pud_free_tlb checks the asce_limit against 4TB * to avoid the double free of the pud in this case. */ -static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) +static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, + unsigned long address) { #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index f9b1440..8d15314 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -210,7 +210,7 @@ static noinline __init void detect_machine_type(void) machine_flags |= MACHINE_FLAG_VM; } -static void early_pgm_check_handler(void) +static __init void early_pgm_check_handler(void) { unsigned long addr; const struct exception_table_entry *fixup; @@ -222,7 +222,7 @@ static void early_pgm_check_handler(void) S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE; } -void setup_lowcore_early(void) +static noinline __init void setup_lowcore_early(void) { psw_t psw; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 2270730..be2cae0 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -687,13 +687,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) lowcore->extended_save_area_addr = (u32) save_area; -#else - if (vdso_alloc_per_cpu(smp_processor_id(), lowcore)) - BUG(); #endif set_prefix((u32)(unsigned long) lowcore); local_mcck_enable(); local_irq_enable(); +#ifdef CONFIG_64BIT + if (vdso_alloc_per_cpu(smp_processor_id(), &S390_lowcore)) + BUG(); +#endif for_each_possible_cpu(cpu) if (cpu != smp_processor_id()) smp_create_idle(cpu); diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index 79dbfee..49106c6 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S @@ -88,10 +88,17 @@ __kernel_clock_gettime: llilh %r4,0x0100 sar %a4,%r4 lghi %r4,0 + epsw %r5,0 sacf 512 /* Magic ectg instruction */ .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 - sacf 0 - sar %a4,%r2 + tml %r5,0x4000 + jo 11f + tml %r5,0x8000 + jno 10f + sacf 256 + j 11f +10: sacf 0 +11: sar %a4,%r2 algr %r1,%r0 /* r1 = cputime as TOD value */ mghi %r1,1000 /* convert to nanoseconds */ srlg %r1,%r1,12 /* r1 = cputime in nanosec */ diff --git a/arch/s390/power/swsusp.c b/arch/s390/power/swsusp.c index e6a4fe9..bd1f5c6 100644 --- a/arch/s390/power/swsusp.c +++ b/arch/s390/power/swsusp.c @@ -7,24 +7,36 @@ * */ +#include <asm/system.h> -/* - * save CPU registers before creating a hibernation image and before - * restoring the memory state from it - */ void save_processor_state(void) { - /* implentation contained in the - * swsusp_arch_suspend function + /* swsusp_arch_suspend() actually saves all cpu register contents. + * Machine checks must be disabled since swsusp_arch_suspend() stores + * register contents to their lowcore save areas. That's the same + * place where register contents on machine checks would be saved. + * To avoid register corruption disable machine checks. + * We must also disable machine checks in the new psw mask for + * program checks, since swsusp_arch_suspend() may generate program + * checks. Disabling machine checks for all other new psw masks is + * just paranoia. */ + local_mcck_disable(); + /* Disable lowcore protection */ + __ctl_clear_bit(0,28); + S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK; + S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK; + S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK; + S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK; } -/* - * restore the contents of CPU registers - */ void restore_processor_state(void) { - /* implentation contained in the - * swsusp_arch_resume function - */ + S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK; + S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK; + S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK; + S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK; + /* Enable lowcore protection */ + __ctl_set_bit(0,28); + local_mcck_enable(); } diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/power/swsusp_asm64.S index 76d688d..b26df5c 100644 --- a/arch/s390/power/swsusp_asm64.S +++ b/arch/s390/power/swsusp_asm64.S @@ -32,19 +32,14 @@ swsusp_arch_suspend: /* Deactivate DAT */ stnsm __SF_EMPTY(%r15),0xfb - /* Switch off lowcore protection */ - stctg %c0,%c0,__SF_EMPTY(%r15) - ni __SF_EMPTY+4(%r15),0xef - lctlg %c0,%c0,__SF_EMPTY(%r15) - /* Store prefix register on stack */ stpx __SF_EMPTY(%r15) - /* Setup base register for lowcore (absolute 0) */ - llgf %r1,__SF_EMPTY(%r15) + /* Save prefix register contents for lowcore */ + llgf %r4,__SF_EMPTY(%r15) /* Get pointer to save area */ - aghi %r1,0x1000 + lghi %r1,0x1000 /* Store registers */ mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ @@ -79,17 +74,15 @@ swsusp_arch_suspend: xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) spx __SF_EMPTY(%r15) - /* Setup lowcore */ - brasl %r14,setup_lowcore_early + lghi %r2,0 + lghi %r3,2*PAGE_SIZE + lghi %r5,2*PAGE_SIZE +1: mvcle %r2,%r4,0 + jo 1b /* Save image */ brasl %r14,swsusp_save - /* Switch on lowcore protection */ - stctg %c0,%c0,__SF_EMPTY(%r15) - oi __SF_EMPTY+4(%r15),0x10 - lctlg %c0,%c0,__SF_EMPTY(%r15) - /* Restore prefix register and return */ lghi %r1,0x1000 spx 0x318(%r1) @@ -117,11 +110,6 @@ swsusp_arch_resume: /* Deactivate DAT */ stnsm __SF_EMPTY(%r15),0xfb - /* Switch off lowcore protection */ - stctg %c0,%c0,__SF_EMPTY(%r15) - ni __SF_EMPTY+4(%r15),0xef - lctlg %c0,%c0,__SF_EMPTY(%r15) - /* Set prefix page to zero */ xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) spx __SF_EMPTY(%r15) @@ -175,7 +163,7 @@ swsusp_arch_resume: /* Load old stack */ lg %r15,0x2f8(%r13) - /* Pointer to save arae */ + /* Pointer to save area */ lghi %r13,0x1000 #ifdef CONFIG_SMP @@ -187,11 +175,6 @@ swsusp_arch_resume: /* Restore prefix register */ spx 0x318(%r13) - /* Switch on lowcore protection */ - stctg %c0,%c0,__SF_EMPTY(%r15) - oi __SF_EMPTY+4(%r15),0x10 - lctlg %c0,%c0,__SF_EMPTY(%r15) - /* Activate DAT */ stosm __SF_EMPTY(%r15),0x04 diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 84dd2db..63ca37b 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -73,20 +73,12 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) quicklist_free_page(QUICK_PT, NULL, pte); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte,addr) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb), (pte)); \ } while (0) -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ - -#define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb,x) do { } while (0) - static inline void check_pgt_cache(void) { quicklist_trim(QUICK_PGD, NULL, 25, 16); diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 9c16f73..da8fe7a 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -91,9 +91,9 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) } #define tlb_remove_page(tlb,page) free_page_and_swap_cache(page) -#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep) -#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp) -#define pud_free_tlb(tlb, pudp) pud_free((tlb)->mm, pudp) +#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep) +#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp) +#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp) #define tlb_migrate_finish(mm) do { } while (0) diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h index 681582d..ca2b344 100644 --- a/arch/sparc/include/asm/pgalloc_32.h +++ b/arch/sparc/include/asm/pgalloc_32.h @@ -44,8 +44,8 @@ BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long) BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *) #define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd) -#define pmd_free(mm, pmd) free_pmd_fast(pmd) -#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd) +#define pmd_free(mm, pmd) free_pmd_fast(pmd) +#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *) #define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE) @@ -62,7 +62,7 @@ BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *) #define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte) BTFIXUPDEF_CALL(void, pte_free, pgtable_t ) -#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte) -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte) +#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte) +#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) #endif /* _SPARC_PGALLOC_H */ diff --git a/arch/sparc/include/asm/tlb_64.h b/arch/sparc/include/asm/tlb_64.h index ee38e73..dca406b 100644 --- a/arch/sparc/include/asm/tlb_64.h +++ b/arch/sparc/include/asm/tlb_64.h @@ -100,9 +100,9 @@ static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) } #define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0) -#define pte_free_tlb(mp, ptepage) pte_free((mp)->mm, ptepage) -#define pmd_free_tlb(mp, pmdp) pmd_free((mp)->mm, pmdp) -#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp) +#define pte_free_tlb(mp, ptepage, addr) pte_free((mp)->mm, ptepage) +#define pmd_free_tlb(mp, pmdp, addr) pmd_free((mp)->mm, pmdp) +#define pud_free_tlb(tlb,pudp, addr) __pud_free_tlb(tlb,pudp,addr) #define tlb_migrate_finish(mm) do { } while (0) #define tlb_start_vma(tlb, vma) do { } while (0) diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h index 7189843..32c8ce4 100644 --- a/arch/um/include/asm/pgalloc.h +++ b/arch/um/include/asm/pgalloc.h @@ -40,7 +40,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) __free_page(pte); } -#define __pte_free_tlb(tlb,pte) \ +#define __pte_free_tlb(tlb,pte, address) \ do { \ pgtable_page_dtor(pte); \ tlb_remove_page((tlb),(pte)); \ @@ -53,7 +53,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) free_page((unsigned long)pmd); } -#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) +#define __pmd_free_tlb(tlb,x, address) tlb_remove_page((tlb),virt_to_page(x)) #endif #define check_pgt_cache() do { } while (0) diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h index 5240fa1..660caed 100644 --- a/arch/um/include/asm/tlb.h +++ b/arch/um/include/asm/tlb.h @@ -116,11 +116,11 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) __tlb_remove_tlb_entry(tlb, ptep, address); \ } while (0) -#define pte_free_tlb(tlb, ptep) __pte_free_tlb(tlb, ptep) +#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) -#define pud_free_tlb(tlb, pudp) __pud_free_tlb(tlb, pudp) +#define pud_free_tlb(tlb, pudp, addr) __pud_free_tlb(tlb, pudp, addr) -#define pmd_free_tlb(tlb, pmdp) __pmd_free_tlb(tlb, pmdp) +#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) #define tlb_migrate_finish(mm) do {} while (0) diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index dd14c54..0e8c2a0 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -46,7 +46,13 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte) __free_page(pte); } -extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte); +extern void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte); + +static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte, + unsigned long address) +{ + ___pte_free_tlb(tlb, pte); +} static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) @@ -78,7 +84,13 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) free_page((unsigned long)pmd); } -extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); +extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); + +static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, + unsigned long adddress) +{ + ___pmd_free_tlb(tlb, pmd); +} #ifdef CONFIG_X86_PAE extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); @@ -108,7 +120,14 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud) free_page((unsigned long)pud); } -extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud); +extern void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud); + +static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, + unsigned long address) +{ + ___pud_free_tlb(tlb, pud); +} + #endif /* PAGETABLE_LEVELS > 3 */ #endif /* PAGETABLE_LEVELS > 2 */ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 20e6a79..d2c6c93 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -212,9 +212,9 @@ extern int __get_user_bad(void); : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #else #define __put_user_asm_u64(x, ptr, retval, errret) \ - __put_user_asm(x, ptr, retval, "q", "", "Zr", errret) + __put_user_asm(x, ptr, retval, "q", "", "er", errret) #define __put_user_asm_ex_u64(x, addr) \ - __put_user_asm_ex(x, addr, "q", "", "Zr") + __put_user_asm_ex(x, addr, "q", "", "er") #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) #endif diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 8cc6873..db24b21 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -88,11 +88,11 @@ int __copy_to_user(void __user *dst, const void *src, unsigned size) ret, "l", "k", "ir", 4); return ret; case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "ir", 8); + ret, "q", "", "er", 8); return ret; case 10: __put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "ir", 10); + ret, "q", "", "er", 10); if (unlikely(ret)) return ret; asm("":::"memory"); @@ -101,12 +101,12 @@ int __copy_to_user(void __user *dst, const void *src, unsigned size) return ret; case 16: __put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "ir", 16); + ret, "q", "", "er", 16); if (unlikely(ret)) return ret; asm("":::"memory"); __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst, - ret, "q", "", "ir", 8); + ret, "q", "", "er", 8); return ret; default: return copy_user_generic((__force void *)dst, src, size); @@ -157,7 +157,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) ret, "q", "", "=r", 8); if (likely(!ret)) __put_user_asm(tmp, (u64 __user *)dst, - ret, "q", "", "ir", 8); + ret, "q", "", "er", 8); return ret; } default: diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 28e5f59..e2485b0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -356,7 +356,7 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) #endif #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI) /* check CPU config space for extended APIC ID */ - if (c->x86 >= 0xf) { + if (cpu_has_apic && c->x86 >= 0xf) { unsigned int val; val = read_pci_config(0, 24, 0, 0x68); if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18))) diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 484c1e5..1cfb623 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1692,17 +1692,15 @@ static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr, const char *buf, size_t siz) { char *p; - int len; strncpy(mce_helper, buf, sizeof(mce_helper)); mce_helper[sizeof(mce_helper)-1] = 0; - len = strlen(mce_helper); p = strchr(mce_helper, '\n'); - if (*p) + if (p) *p = 0; - return len; + return strlen(mce_helper) + !!p; } static ssize_t set_ignore_ce(struct sys_device *s, diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 36c3dc7..a7aa8f9 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -66,6 +66,52 @@ static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { }; /* + * Not sure about some of these + */ +static const u64 p6_perfmon_event_map[] = +{ + [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0000, + [PERF_COUNT_HW_CACHE_MISSES] = 0x0000, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, + [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, +}; + +static u64 p6_pmu_event_map(int event) +{ + return p6_perfmon_event_map[event]; +} + +/* + * Counter setting that is specified not to count anything. + * We use this to effectively disable a counter. + * + * L2_RQSTS with 0 MESI unit mask. + */ +#define P6_NOP_COUNTER 0x0000002EULL + +static u64 p6_pmu_raw_event(u64 event) +{ +#define P6_EVNTSEL_EVENT_MASK 0x000000FFULL +#define P6_EVNTSEL_UNIT_MASK 0x0000FF00ULL +#define P6_EVNTSEL_EDGE_MASK 0x00040000ULL +#define P6_EVNTSEL_INV_MASK 0x00800000ULL +#define P6_EVNTSEL_COUNTER_MASK 0xFF000000ULL + +#define P6_EVNTSEL_MASK \ + (P6_EVNTSEL_EVENT_MASK | \ + P6_EVNTSEL_UNIT_MASK | \ + P6_EVNTSEL_EDGE_MASK | \ + P6_EVNTSEL_INV_MASK | \ + P6_EVNTSEL_COUNTER_MASK) + + return event & P6_EVNTSEL_MASK; +} + + +/* * Intel PerfMon v3. Used on Core2 and later. */ static const u64 intel_perfmon_event_map[] = @@ -666,6 +712,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter) { struct perf_counter_attr *attr = &counter->attr; struct hw_perf_counter *hwc = &counter->hw; + u64 config; int err; if (!x86_pmu_initialized()) @@ -718,14 +765,40 @@ static int __hw_perf_counter_init(struct perf_counter *counter) if (attr->config >= x86_pmu.max_events) return -EINVAL; + /* * The generic map: */ - hwc->config |= x86_pmu.event_map(attr->config); + config = x86_pmu.event_map(attr->config); + + if (config == 0) + return -ENOENT; + + if (config == -1LL) + return -EINVAL; + + hwc->config |= config; return 0; } +static void p6_pmu_disable_all(void) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + u64 val; + + if (!cpuc->enabled) + return; + + cpuc->enabled = 0; + barrier(); + + /* p6 only has one enable register */ + rdmsrl(MSR_P6_EVNTSEL0, val); + val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_P6_EVNTSEL0, val); +} + static void intel_pmu_disable_all(void) { wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); @@ -767,6 +840,23 @@ void hw_perf_disable(void) return x86_pmu.disable_all(); } +static void p6_pmu_enable_all(void) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + unsigned long val; + + if (cpuc->enabled) + return; + + cpuc->enabled = 1; + barrier(); + + /* p6 only has one enable register */ + rdmsrl(MSR_P6_EVNTSEL0, val); + val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_P6_EVNTSEL0, val); +} + static void intel_pmu_enable_all(void) { wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); @@ -784,13 +874,13 @@ static void amd_pmu_enable_all(void) barrier(); for (idx = 0; idx < x86_pmu.num_counters; idx++) { + struct perf_counter *counter = cpuc->counters[idx]; u64 val; if (!test_bit(idx, cpuc->active_mask)) continue; - rdmsrl(MSR_K7_EVNTSEL0 + idx, val); - if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) - continue; + + val = counter->hw.config; val |= ARCH_PERFMON_EVENTSEL0_ENABLE; wrmsrl(MSR_K7_EVNTSEL0 + idx, val); } @@ -819,16 +909,13 @@ static inline void intel_pmu_ack_status(u64 ack) static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) { - int err; - err = checking_wrmsrl(hwc->config_base + idx, + (void)checking_wrmsrl(hwc->config_base + idx, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE); } static inline void x86_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) { - int err; - err = checking_wrmsrl(hwc->config_base + idx, - hwc->config); + (void)checking_wrmsrl(hwc->config_base + idx, hwc->config); } static inline void @@ -836,13 +923,24 @@ intel_pmu_disable_fixed(struct hw_perf_counter *hwc, int __idx) { int idx = __idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; - int err; mask = 0xfULL << (idx * 4); rdmsrl(hwc->config_base, ctrl_val); ctrl_val &= ~mask; - err = checking_wrmsrl(hwc->config_base, ctrl_val); + (void)checking_wrmsrl(hwc->config_base, ctrl_val); +} + +static inline void +p6_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + u64 val = P6_NOP_COUNTER; + + if (cpuc->enabled) + val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + + (void)checking_wrmsrl(hwc->config_base + idx, val); } static inline void @@ -943,6 +1041,19 @@ intel_pmu_enable_fixed(struct hw_perf_counter *hwc, int __idx) err = checking_wrmsrl(hwc->config_base, ctrl_val); } +static void p6_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + u64 val; + + val = hwc->config; + if (cpuc->enabled) + val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + + (void)checking_wrmsrl(hwc->config_base + idx, val); +} + + static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) { if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { @@ -959,8 +1070,6 @@ static void amd_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) if (cpuc->enabled) x86_pmu_enable_counter(hwc, idx); - else - x86_pmu_disable_counter(hwc, idx); } static int @@ -1176,6 +1285,49 @@ static void intel_pmu_reset(void) local_irq_restore(flags); } +static int p6_pmu_handle_irq(struct pt_regs *regs) +{ + struct perf_sample_data data; + struct cpu_hw_counters *cpuc; + struct perf_counter *counter; + struct hw_perf_counter *hwc; + int idx, handled = 0; + u64 val; + + data.regs = regs; + data.addr = 0; + + cpuc = &__get_cpu_var(cpu_hw_counters); + + for (idx = 0; idx < x86_pmu.num_counters; idx++) { + if (!test_bit(idx, cpuc->active_mask)) + continue; + + counter = cpuc->counters[idx]; + hwc = &counter->hw; + + val = x86_perf_counter_update(counter, hwc, idx); + if (val & (1ULL << (x86_pmu.counter_bits - 1))) + continue; + + /* + * counter overflow + */ + handled = 1; + data.period = counter->hw.last_period; + + if (!x86_perf_counter_set_period(counter, hwc, idx)) + continue; + + if (perf_counter_overflow(counter, 1, &data)) + p6_pmu_disable_counter(hwc, idx); + } + + if (handled) + inc_irq_stat(apic_perf_irqs); + + return handled; +} /* * This handler is triggered by the local APIC, so the APIC IRQ handling @@ -1185,14 +1337,13 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) { struct perf_sample_data data; struct cpu_hw_counters *cpuc; - int bit, cpu, loops; + int bit, loops; u64 ack, status; data.regs = regs; data.addr = 0; - cpu = smp_processor_id(); - cpuc = &per_cpu(cpu_hw_counters, cpu); + cpuc = &__get_cpu_var(cpu_hw_counters); perf_disable(); status = intel_pmu_get_status(); @@ -1249,14 +1400,13 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) struct cpu_hw_counters *cpuc; struct perf_counter *counter; struct hw_perf_counter *hwc; - int cpu, idx, handled = 0; + int idx, handled = 0; u64 val; data.regs = regs; data.addr = 0; - cpu = smp_processor_id(); - cpuc = &per_cpu(cpu_hw_counters, cpu); + cpuc = &__get_cpu_var(cpu_hw_counters); for (idx = 0; idx < x86_pmu.num_counters; idx++) { if (!test_bit(idx, cpuc->active_mask)) @@ -1353,6 +1503,32 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { .priority = 1 }; +static struct x86_pmu p6_pmu = { + .name = "p6", + .handle_irq = p6_pmu_handle_irq, + .disable_all = p6_pmu_disable_all, + .enable_all = p6_pmu_enable_all, + .enable = p6_pmu_enable_counter, + .disable = p6_pmu_disable_counter, + .eventsel = MSR_P6_EVNTSEL0, + .perfctr = MSR_P6_PERFCTR0, + .event_map = p6_pmu_event_map, + .raw_event = p6_pmu_raw_event, + .max_events = ARRAY_SIZE(p6_perfmon_event_map), + .max_period = (1ULL << 31) - 1, + .version = 0, + .num_counters = 2, + /* + * Counters have 40 bits implemented. However they are designed such + * that bits [32-39] are sign extensions of bit 31. As such the + * effective width of a counter for P6-like PMU is 32 bits only. + * + * See IA-32 Intel Architecture Software developer manual Vol 3B + */ + .counter_bits = 32, + .counter_mask = (1ULL << 32) - 1, +}; + static struct x86_pmu intel_pmu = { .name = "Intel", .handle_irq = intel_pmu_handle_irq, @@ -1392,6 +1568,37 @@ static struct x86_pmu amd_pmu = { .max_period = (1ULL << 47) - 1, }; +static int p6_pmu_init(void) +{ + switch (boot_cpu_data.x86_model) { + case 1: + case 3: /* Pentium Pro */ + case 5: + case 6: /* Pentium II */ + case 7: + case 8: + case 11: /* Pentium III */ + break; + case 9: + case 13: + /* Pentium M */ + break; + default: + pr_cont("unsupported p6 CPU model %d ", + boot_cpu_data.x86_model); + return -ENODEV; + } + + if (!cpu_has_apic) { + pr_info("no Local APIC, try rebooting with lapic"); + return -ENODEV; + } + + x86_pmu = p6_pmu; + + return 0; +} + static int intel_pmu_init(void) { union cpuid10_edx edx; @@ -1400,8 +1607,14 @@ static int intel_pmu_init(void) unsigned int ebx; int version; - if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + /* check for P6 processor family */ + if (boot_cpu_data.x86 == 6) { + return p6_pmu_init(); + } else { return -ENODEV; + } + } /* * Check whether the Architectural PerfMon supports diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 696f0e4..92b7703 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -187,7 +187,7 @@ static void __init apic_intr_init(void) #ifdef CONFIG_X86_THERMAL_VECTOR alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); #endif -#ifdef CONFIG_X86_THRESHOLD +#ifdef CONFIG_X86_MCE_THRESHOLD alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); #endif #if defined(CONFIG_X86_NEW_MCE) && defined(CONFIG_X86_LOCAL_APIC) diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index 846510b..2a62d84 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c @@ -347,7 +347,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) static struct irqaction mfgptirq = { .handler = mfgpt_tick, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, .name = "mfgpt-timer" }; diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index d2d1ce8..508e982 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -249,6 +249,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), }, }, + { /* Handle problems with rebooting on CompuLab SBC-FITPC2 */ + .callback = set_bios_reboot, + .ident = "CompuLab SBC-FITPC2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CompuLab"), + DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), + }, + }, { } }; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index de2cab1..63f32d2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -672,6 +672,19 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"), }, }, + { + /* + * AMI BIOS with low memory corruption was found on Intel DG45ID board. + * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will + * match only DMI_BOARD_NAME and see if there is more bad products + * with this vendor. + */ + .callback = dmi_low_memory_corruption, + .ident = "AMI BIOS", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "DG45ID"), + }, + }, #endif {} }; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 367e878..59f31d2 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -112,11 +112,6 @@ SECTIONS _sdata = .; DATA_DATA CONSTRUCTORS - -#ifdef CONFIG_X86_64 - /* End of data section */ - _edata = .; -#endif } :data #ifdef CONFIG_X86_32 @@ -156,10 +151,8 @@ SECTIONS .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) -#ifdef CONFIG_X86_32 /* End of data section */ _edata = .; -#endif } #ifdef CONFIG_X86_64 diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 8e43bdd..af8f965 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -25,7 +25,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) return pte; } -void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) +void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) { pgtable_page_dtor(pte); paravirt_release_pte(page_to_pfn(pte)); @@ -33,14 +33,14 @@ void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) } #if PAGETABLE_LEVELS > 2 -void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); tlb_remove_page(tlb, virt_to_page(pmd)); } #if PAGETABLE_LEVELS > 3 -void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) +void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) { paravirt_release_pud(__pa(pud) >> PAGE_SHIFT); tlb_remove_page(tlb, virt_to_page(pud)); diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 2dfcbf9..dbb5381 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -79,8 +79,10 @@ static __init void bad_srat(void) acpi_numa = -1; for (i = 0; i < MAX_LOCAL_APIC; i++) apicid_to_node[i] = NUMA_NO_NODE; - for (i = 0; i < MAX_NUMNODES; i++) - nodes_add[i].start = nodes[i].end = 0; + for (i = 0; i < MAX_NUMNODES; i++) { + nodes[i].start = nodes[i].end = 0; + nodes_add[i].start = nodes_add[i].end = 0; + } remove_all_active_ranges(); } diff --git a/arch/xtensa/include/asm/tlb.h b/arch/xtensa/include/asm/tlb.h index 31c220f..0d766f9 100644 --- a/arch/xtensa/include/asm/tlb.h +++ b/arch/xtensa/include/asm/tlb.h @@ -42,6 +42,6 @@ #include <asm-generic/tlb.h> -#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte) +#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) #endif /* _XTENSA_TLB_H */ |