diff options
Diffstat (limited to 'arch')
47 files changed, 980 insertions, 146 deletions
diff --git a/arch/arm/configs/n770_defconfig b/arch/arm/configs/n770_defconfig index 672f6db06a5..a1657b73683 100644 --- a/arch/arm/configs/n770_defconfig +++ b/arch/arm/configs/n770_defconfig @@ -875,7 +875,7 @@ CONFIG_FB_OMAP_LCDC_EXTERNAL=y CONFIG_FB_OMAP_LCDC_HWA742=y # CONFIG_FB_OMAP_LCDC_BLIZZARD is not set CONFIG_FB_OMAP_MANUAL_UPDATE=y -# CONFIG_FB_OMAP_LCD_MIPID is not set +CONFIG_FB_OMAP_LCD_MIPID=y # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # CONFIG_FB_OMAP_DMA_TUNE is not set diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig index 51c0fa8897c..357d4021e2d 100644 --- a/arch/arm/configs/omap3_beagle_defconfig +++ b/arch/arm/configs/omap3_beagle_defconfig @@ -778,7 +778,33 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -791,6 +817,25 @@ CONFIG_DAB=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set + +# +# Sound +# # CONFIG_SOUND is not set # CONFIG_HID_SUPPORT is not set CONFIG_USB_SUPPORT=y diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig index 9a510eab75a..8a4a7e2ba87 100644 --- a/arch/arm/configs/omap_3430sdp_defconfig +++ b/arch/arm/configs/omap_3430sdp_defconfig @@ -1313,8 +1313,33 @@ CONFIG_DVB_ISL6421=m # Graphics support # # CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1331,6 +1356,16 @@ CONFIG_DISPLAY_SUPPORT=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y CONFIG_SND=y diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig index 679a4a3e265..b9c48919a68 100644 --- a/arch/arm/configs/omap_ldp_defconfig +++ b/arch/arm/configs/omap_ldp_defconfig @@ -690,6 +690,7 @@ CONFIG_GPIOLIB=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y # # PCI GPIO expanders: @@ -742,6 +743,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +CONFIG_TWL4030_CORE=y # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set @@ -767,8 +769,46 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +CONFIG_FB_OMAP=y +CONFIG_FB_OMAP_LCD_VGA=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=4 +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +CONFIG_LCD_PLATFORM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set +# CONFIG_BACKLIGHT_GENERIC is not set # # Display device support @@ -780,6 +820,16 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=y CONFIG_SND=y # CONFIG_SND_SEQUENCER is not set diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index a24d824c428..e35d54d43e7 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -289,6 +289,13 @@ config MACH_NEOCORE926 help Select this if you are using the Adeneo Neocore 926 board. +config MACH_AT91SAM9G20EK_2MMC + bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit + Rev A or B modified for 2 MMC Slots. + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index a6ed015d82e..ada440aab0c 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o # AT91SAM9G20 board-specific support obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o +obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o # AT91SAM9G45 board-specific support diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index ee4ea0e720c..07eb7b07e44 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -278,6 +278,102 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} #endif +/* -------------------------------------------------------------------- + * MMC / SD Slot for Atmel MCI Driver + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static u64 mmc_dmamask = DMA_BIT_MASK(32); +static struct mci_platform_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "atmel_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) +{ + unsigned int i; + unsigned int slot_count = 0; + + if (!data) + return; + + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { + if (data->slot[i].bus_width) { + /* input/irq */ + if (data->slot[i].detect_pin) { + at91_set_gpio_input(data->slot[i].detect_pin, 1); + at91_set_deglitch(data->slot[i].detect_pin, 1); + } + if (data->slot[i].wp_pin) + at91_set_gpio_input(data->slot[i].wp_pin, 1); + + switch (i) { + case 0: + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->slot[i].bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + slot_count++; + break; + case 1: + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->slot[i].bus_width == 4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + slot_count++; + break; + default: + printk(KERN_ERR + "AT91: SD/MMC slot %d not available\n", i); + break; + } + } + } + + if (slot_count) { + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); + } +} +#else +void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} +#endif + /* -------------------------------------------------------------------- * NAND / SmartMedia diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c new file mode 100644 index 00000000000..a28e53faf71 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * Copyright (C) 2009 Rob Emanuele + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/spi/at73c213.h> +#include <linux/clk.h> + +#include <mach/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <mach/board.h> +#include <mach/gpio.h> +#include <mach/at91sam9_smc.h> + +#include "sam9_smc.h" +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_ATMELMCI) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PC12, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * SZ_1M, + }, + { + .name = "Partition 1", + .offset = MTDPART_OFS_NXTBLK, + .size = 60 * SZ_1M, + }, + { + .name = "Partition 2", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct atmel_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +static struct sam9_smc_config __initdata ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void __init ek_add_device_nand(void) +{ + /* setup bus-width (8 or 16) */ + if (ek_nand_data.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &ek_nand_smc_config); + + at91_add_device_nand(&ek_nand_data); +} + + +/* + * MCI (SD/MMC) + * det_pin and wp_pin are not connected + */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata ek_mmc_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + .slot[1] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, + +}; +#else +static struct amci_platform_data __initdata ek_mmc_data = { +}; +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PB12, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PB13, + .default_trigger = "heartbeat", + } +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + }, +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + ek_add_device_nand(); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mci(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* PCK0 provides MCLK to the WM8731 */ + at91_set_B_periph(AT91_PIN_PC1, 0); + /* SSC (for WM8731) */ + at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); +} + +MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") + /* Maintainer: Rob Emanuele */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 13f27a4b882..583f38a38df 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -37,6 +37,7 @@ #include <linux/leds.h> #include <linux/spi/spi.h> #include <linux/usb/atmel_usba_udc.h> +#include <linux/atmel-mci.h> #include <sound/atmel-ac97c.h> /* USB Device */ @@ -64,6 +65,7 @@ struct at91_cf_data { extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ + /* at91_mci platform config */ struct at91_mmc_data { u8 det_pin; /* card detect IRQ */ unsigned slot_b:1; /* uses Slot B */ @@ -73,6 +75,9 @@ struct at91_mmc_data { }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); + /* atmel-mci platform config */ +extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); + /* Ethernet (EMAC & MACB) */ struct at91_eth_data { u32 phy_mask; diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 3dd0e2a2309..dda19cd7619 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -37,7 +37,7 @@ struct clk { static unsigned long get_uart_rate(struct clk *clk); static int set_keytchclk_rate(struct clk *clk, unsigned long rate); - +static int set_div_rate(struct clk *clk, unsigned long rate); static struct clk clk_uart1 = { .sw_locked = 1, @@ -76,6 +76,13 @@ static struct clk clk_pwm = { .rate = EP93XX_EXT_CLK_RATE, }; +static struct clk clk_video = { + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_VIDCLKDIV, + .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE, + .set_rate = set_div_rate, +}; + /* DMA Clocks */ static struct clk clk_m2p0 = { .enable_reg = EP93XX_SYSCON_PWRCNT, @@ -140,6 +147,7 @@ static struct clk_lookup clocks[] = { INIT_CK(NULL, "pll2", &clk_pll2), INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), + INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK(NULL, "pwm_clk", &clk_pwm), INIT_CK(NULL, "m2p0", &clk_m2p0), INIT_CK(NULL, "m2p1", &clk_m2p1), @@ -236,6 +244,84 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate) return 0; } +static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, + int *pdiv, int *div) +{ + unsigned long max_rate, best_rate = 0, + actual_rate = 0, mclk_rate = 0, rate_err = -1; + int i, found = 0, __div = 0, __pdiv = 0; + + /* Don't exceed the maximum rate */ + max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4), + (unsigned long)EP93XX_EXT_CLK_RATE / 4); + rate = min(rate, max_rate); + + /* + * Try the two pll's and the external clock + * Because the valid predividers are 2, 2.5 and 3, we multiply + * all the clocks by 2 to avoid floating point math. + * + * This is based on the algorithm in the ep93xx raster guide: + * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf + * + */ + for (i = 0; i < 3; i++) { + if (i == 0) + mclk_rate = EP93XX_EXT_CLK_RATE * 2; + else if (i == 1) + mclk_rate = clk_pll1.rate * 2; + else if (i == 2) + mclk_rate = clk_pll2.rate * 2; + + /* Try each predivider value */ + for (__pdiv = 4; __pdiv <= 6; __pdiv++) { + __div = mclk_rate / (rate * __pdiv); + if (__div < 2 || __div > 127) + continue; + + actual_rate = mclk_rate / (__pdiv * __div); + + if (!found || abs(actual_rate - rate) < rate_err) { + *pdiv = __pdiv - 3; + *div = __div; + *psel = (i == 2); + *esel = (i != 0); + best_rate = actual_rate; + rate_err = abs(actual_rate - rate); + found = 1; + } + } + } + + if (!found) + return 0; + + return best_rate; +} + +static int set_div_rate(struct clk *clk, unsigned long rate) +{ + unsigned long actual_rate; + int psel = 0, esel = 0, pdiv = 0, div = 0; + u32 val; + + actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div); + if (actual_rate == 0) + return -EINVAL; + clk->rate = actual_rate; + + /* Clear the esel, psel, pdiv and div bits */ + val = __raw_readl(clk->enable_reg); + val &= ~0x7fff; + + /* Set the new esel, psel, pdiv and div bits for the new clock rate */ + val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) | + (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) | + (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div; + ep93xx_syscon_swlocked_write(val, clk->enable_reg); + return 0; +} + int clk_set_rate(struct clk *clk, unsigned long rate) { if (clk->set_rate) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 16b92c37ec9..f7ebed942f6 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -30,6 +30,7 @@ #include <linux/i2c-gpio.h> #include <mach/hardware.h> +#include <mach/fb.h> #include <asm/mach/map.h> #include <asm/mach/time.h> @@ -682,6 +683,37 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev) EXPORT_SYMBOL(ep93xx_pwm_release_gpio); +/************************************************************************* + * EP93xx video peripheral handling + *************************************************************************/ +static struct ep93xxfb_mach_info ep93xxfb_data; + +static struct resource ep93xx_fb_resource[] = { + { + .start = EP93XX_RASTER_PHYS_BASE, + .end = EP93XX_RASTER_PHYS_BASE + 0x800 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ep93xx_fb_device = { + .name = "ep93xx-fb", + .id = -1, + .dev = { + .platform_data = &ep93xxfb_data, + .coherent_dma_mask = DMA_BIT_MASK(32), + .dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask, + }, + .num_resources = ARRAY_SIZE(ep93xx_fb_resource), + .resource = ep93xx_fb_resource, +}; + +void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) +{ + ep93xxfb_data = *data; + platform_device_register(&ep93xx_fb_device); +} + extern void ep93xx_gpio_init(void); void __init ep93xx_init_devices(void) diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index ea78e908fc8..0fbf87b1633 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -70,6 +70,7 @@ #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) #define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) +#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000) #define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) #define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) @@ -207,6 +208,11 @@ #define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) #define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) #define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) +#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84) +#define EP93XX_SYSCON_CLKDIV_ENABLE (1<<15) +#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14) +#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13) +#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 #define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) diff --git a/arch/arm/mach-ep93xx/include/mach/fb.h b/arch/arm/mach-ep93xx/include/mach/fb.h new file mode 100644 index 00000000000..d5ae11d7c45 --- /dev/null +++ b/arch/arm/mach-ep93xx/include/mach/fb.h @@ -0,0 +1,56 @@ +/* + * arch/arm/mach-ep93xx/include/mach/fb.h + */ + +#ifndef __ASM_ARCH_EP93XXFB_H +#define __ASM_ARCH_EP93XXFB_H + +struct platform_device; +struct fb_videomode; +struct fb_info; + +#define EP93XXFB_USE_MODEDB 0 + +/* VideoAttributes flags */ +#define EP93XXFB_STATE_MACHINE_ENABLE (1 << 0) +#define EP93XXFB_PIXEL_CLOCK_ENABLE (1 << 1) +#define EP93XXFB_VSYNC_ENABLE (1 << 2) +#define EP93XXFB_PIXEL_DATA_ENABLE (1 << 3) +#define EP93XXFB_COMPOSITE_SYNC (1 << 4) +#define EP93XXFB_SYNC_VERT_HIGH (1 << 5) +#define EP93XXFB_SYNC_HORIZ_HIGH (1 << 6) +#define EP93XXFB_SYNC_BLANK_HIGH (1 << 7) +#define EP93XXFB_PCLK_FALLING (1 << 8) +#define EP93XXFB_ENABLE_AC (1 << 9) +#define EP93XXFB_ENABLE_LCD (1 << 10) +#define EP93XXFB_ENABLE_CCIR (1 << 12) +#define EP93XXFB_USE_PARALLEL_INTERFACE (1 << 13) +#define EP93XXFB_ENABLE_INTERRUPT (1 << 14) +#define EP93XXFB_USB_INTERLACE (1 << 16) +#define EP93XXFB_USE_EQUALIZATION (1 << 17) +#define EP93XXFB_USE_DOUBLE_HORZ (1 << 18) +#define EP93XXFB_USE_DOUBLE_VERT (1 << 19) +#define EP93XXFB_USE_BLANK_PIXEL (1 << 20) +#define EP93XXFB_USE_SDCSN0 (0 << 21) +#define EP93XXFB_USE_SDCSN1 (1 << 21) +#define EP93XXFB_USE_SDCSN2 (2 << 21) +#define EP93XXFB_USE_SDCSN3 (3 << 21) + +#define EP93XXFB_ENABLE (EP93XXFB_STATE_MACHINE_ENABLE | \ + EP93XXFB_PIXEL_CLOCK_ENABLE | \ + EP93XXFB_VSYNC_ENABLE | \ + EP93XXFB_PIXEL_DATA_ENABLE) + +struct ep93xxfb_mach_info { + unsigned int num_modes; + const struct fb_videomode *modes; + const struct fb_videomode *default_mode; + int bpp; + unsigned int flags; + + int (*setup)(struct platform_device *pdev); + void (*teardown)(struct platform_device *pdev); + void (*blank)(int blank_mode, struct fb_info *info); +}; + +#endif /* __ASM_ARCH_EP93XXFB_H */ diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 5f5fa6574d3..01a0f0838e5 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -6,6 +6,7 @@ struct i2c_board_info; struct platform_device; +struct ep93xxfb_mach_info; struct ep93xx_eth_data { @@ -33,6 +34,7 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits) void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_board_info *devices, int num); +void ep93xx_register_fb(struct ep93xxfb_mach_info *data); void ep93xx_register_pwm(int pwm0, int pwm1); int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); void ep93xx_pwm_release_gpio(struct platform_device *pdev); diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index e70baa79901..e6e8290b782 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <linux/regulator/machine.h> #include <linux/gpio.h> +#include <linux/mmc/host.h> #include <mach/mcspi.h> #include <mach/mux.h> @@ -102,6 +103,7 @@ static struct twl4030_hsmmc_info mmc[] = { .cover_only = true, .gpio_cd = 160, .gpio_wp = -EINVAL, + .power_saving = true, }, { .name = "internal", @@ -109,6 +111,8 @@ static struct twl4030_hsmmc_info mmc[] = { .wires = 8, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, + .nonremovable = true, + .power_saving = true, }, {} /* Terminator */ }; diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index a2e915639b7..bcfcfc7fdb9 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -257,6 +257,11 @@ static inline void omap_init_sti(void) {} #define OMAP2_MCSPI3_BASE 0x480b8000 #define OMAP2_MCSPI4_BASE 0x480ba000 +#define OMAP4_MCSPI1_BASE 0x48098100 +#define OMAP4_MCSPI2_BASE 0x4809a100 +#define OMAP4_MCSPI3_BASE 0x480b8100 +#define OMAP4_MCSPI4_BASE 0x480ba100 + static struct omap2_mcspi_platform_config omap2_mcspi1_config = { .num_cs = 4, }; @@ -301,7 +306,8 @@ static struct platform_device omap2_mcspi2 = { }, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ + defined(CONFIG_ARCH_OMAP4) static struct omap2_mcspi_platform_config omap2_mcspi3_config = { .num_cs = 2, }; @@ -325,7 +331,7 @@ static struct platform_device omap2_mcspi3 = { }; #endif -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) static struct omap2_mcspi_platform_config omap2_mcspi4_config = { .num_cs = 1, }; @@ -351,14 +357,25 @@ static struct platform_device omap2_mcspi4 = { static void omap_init_mcspi(void) { + if (cpu_is_omap44xx()) { + omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; + omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; + omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; + omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; + omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; + omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; + omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; + omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; + } platform_device_register(&omap2_mcspi1); platform_device_register(&omap2_mcspi2); -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) - if (cpu_is_omap2430() || cpu_is_omap343x()) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ + defined(CONFIG_ARCH_OMAP4) + if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) platform_device_register(&omap2_mcspi3); #endif -#ifdef CONFIG_ARCH_OMAP3 - if (cpu_is_omap343x()) +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) + if (cpu_is_omap343x() || cpu_is_omap44xx()) platform_device_register(&omap2_mcspi4); #endif } @@ -397,7 +414,7 @@ static inline void omap_init_sha1_md5(void) { } /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) #define MMCHS_SYSCONFIG 0x0010 #define MMCHS_SYSCONFIG_SWRESET (1 << 1) @@ -424,8 +441,8 @@ static struct platform_device dummy_pdev = { **/ static void __init omap_hsmmc_reset(void) { - u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : - OMAP24XX_NR_MMC; + u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : + (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); for (i = 0; i < nr_controllers; i++) { u32 v, base = 0; @@ -442,8 +459,21 @@ static void __init omap_hsmmc_reset(void) case 2: base = OMAP3_MMC3_BASE; break; + case 3: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC4_BASE; + break; + case 4: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC5_BASE; + break; } + if (cpu_is_omap44xx()) + base += OMAP4_MMC_REG_OFFSET; + dummy_pdev.id = i; dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i); iclk = clk_get(dev, "ick"); @@ -581,11 +611,23 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, irq = INT_24XX_MMC2_IRQ; break; case 2: - if (!cpu_is_omap34xx()) + if (!cpu_is_omap44xx() && !cpu_is_omap34xx()) return; base = OMAP3_MMC3_BASE; irq = INT_34XX_MMC3_IRQ; break; + case 3: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET; + irq = INT_44XX_MMC4_IRQ; + break; + case 4: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET; + irq = INT_44XX_MMC5_IRQ; + break; default: continue; } @@ -593,8 +635,15 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, if (cpu_is_omap2420()) { size = OMAP2420_MMC_SIZE; name = "mmci-omap"; + } else if (cpu_is_omap44xx()) { + if (i < 3) { + base += OMAP4_MMC_REG_OFFSET; + irq += IRQ_GIC_START; + } + size = OMAP4_HSMMC_SIZE; + name = "mmci-omap-hs"; } else { - size = HSMMC_SIZE; + size = OMAP3_HSMMC_SIZE; name = "mmci-omap-hs"; } omap_mmc_add(name, i, base, size, irq, mmc_data[i]); diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 3c04c2f1b23..c9c59a2db4e 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c @@ -198,6 +198,18 @@ static int twl_mmc_resume(struct device *dev, int slot) #define twl_mmc_resume NULL #endif +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) + +static int twl4030_mmc_get_context_loss(struct device *dev) +{ + /* FIXME: PM DPS not implemented yet */ + return 0; +} + +#else +#define twl4030_mmc_get_context_loss NULL +#endif + static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, int vdd) { @@ -328,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v return ret; } +static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd, + int cardsleep) +{ + struct twl_mmc_controller *c = &hsmmc[0]; + int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; + + return regulator_set_mode(c->vcc, mode); +} + +static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd, + int cardsleep) +{ + struct twl_mmc_controller *c = NULL; + struct omap_mmc_platform_data *mmc = dev->platform_data; + int i, err, mode; + + for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { + if (mmc == hsmmc[i].mmc) { + c = &hsmmc[i]; + break; + } + } + + if (c == NULL) + return -ENODEV; + + /* + * If we don't see a Vcc regulator, assume it's a fixed + * voltage always-on regulator. + */ + if (!c->vcc) + return 0; + + mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; + + if (!c->vcc_aux) + return regulator_set_mode(c->vcc, mode); + + if (cardsleep) { + /* VCC can be turned off if card is asleep */ + struct regulator *vcc_aux = c->vcc_aux; + + c->vcc_aux = NULL; + if (sleep) + err = twl_mmc23_set_power(dev, slot, 0, 0); + else + err = twl_mmc23_set_power(dev, slot, 1, vdd); + c->vcc_aux = vcc_aux; + } else + err = regulator_set_mode(c->vcc, mode); + if (err) + return err; + return regulator_set_mode(c->vcc_aux, mode); +} + static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) @@ -390,6 +457,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) } else mmc->slots[0].switch_pin = -EINVAL; + mmc->get_context_loss_count = + twl4030_mmc_get_context_loss; + /* write protect normally uses an OMAP gpio */ if (gpio_is_valid(c->gpio_wp)) { gpio_request(c->gpio_wp, "mmc_wp"); @@ -400,6 +470,12 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) } else mmc->slots[0].gpio_wp = -EINVAL; + if (c->nonremovable) + mmc->slots[0].nonremovable = 1; + + if (c->power_saving) + mmc->slots[0].power_saving = 1; + /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. @@ -412,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) case 1: /* on-chip level shifting via PBIAS0/PBIAS1 */ mmc->slots[0].set_power = twl_mmc1_set_power; + mmc->slots[0].set_sleep = twl_mmc1_set_sleep; break; case 2: if (c->ext_clock) @@ -422,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) case 3: /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc23_set_power; + mmc->slots[0].set_sleep = twl_mmc23_set_sleep; break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h index 3807c45c9a6..a47e68563fb 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.h +++ b/arch/arm/mach-omap2/mmc-twl4030.h @@ -12,6 +12,8 @@ struct twl4030_hsmmc_info { bool transceiver; /* MMC-2 option */ bool ext_clock; /* use external pin for input clock */ bool cover_only; /* No card detect - just cover switch */ + bool nonremovable; /* Nonremovable e.g. eMMC */ + bool power_saving; /* Try to sleep or power off when possible */ int gpio_cd; /* or -EINVAL */ int gpio_wp; /* or -EINVAL */ char *name; /* or NULL for default */ diff --git a/arch/arm/plat-mxc/include/mach/spi.h b/arch/arm/plat-mxc/include/mach/spi.h new file mode 100644 index 00000000000..08be445e8eb --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/spi.h @@ -0,0 +1,27 @@ + +#ifndef __MACH_SPI_H_ +#define __MACH_SPI_H_ + +/* + * struct spi_imx_master - device.platform_data for SPI controller devices. + * @chipselect: Array of chipselects for this master. Numbers >= 0 mean gpio + * pins, numbers < 0 mean internal CSPI chipselects according + * to MXC_SPI_CS(). Normally you want to use gpio based chip + * selects as the CSPI module tries to be intelligent about + * when to assert the chipselect: The CSPI module deasserts the + * chipselect once it runs out of input data. The other problem + * is that it is not possible to mix between high active and low + * active chipselects on one single bus using the internal + * chipselects. Unfortunately Freescale decided to put some + * chipselects on dedicated pins which are not usable as gpios, + * so we have to support the internal chipselects. + * @num_chipselect: ARRAY_SIZE(chipselect) + */ +struct spi_imx_master { + int *chipselect; + int num_chipselect; +}; + +#define MXC_SPI_CS(no) ((no) - 32) + +#endif /* __MACH_SPI_H_*/ diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h index fb7cb772399..28a165058b6 100644 --- a/arch/arm/plat-omap/include/mach/irqs.h +++ b/arch/arm/plat-omap/include/mach/irqs.h @@ -503,6 +503,7 @@ #define INT_44XX_FPKA_READY_IRQ (50 + IRQ_GIC_START) #define INT_44XX_SHA1MD51_IRQ (51 + IRQ_GIC_START) #define INT_44XX_RNG_IRQ (52 + IRQ_GIC_START) +#define INT_44XX_MMC5_IRQ (59 + IRQ_GIC_START) #define INT_44XX_I2C3_IRQ (61 + IRQ_GIC_START) #define INT_44XX_FPKA_ERROR_IRQ (64 + IRQ_GIC_START) #define INT_44XX_PBIAS_IRQ (75 + IRQ_GIC_START) @@ -511,6 +512,7 @@ #define INT_44XX_TLL_IRQ (78 + IRQ_GIC_START) #define INT_44XX_PARTHASH_IRQ (79 + IRQ_GIC_START) #define INT_44XX_MMC3_IRQ (94 + IRQ_GIC_START) +#define INT_44XX_MMC4_IRQ (96 + IRQ_GIC_START) /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and diff --git a/arch/arm/plat-omap/include/mach/lcd_mipid.h b/arch/arm/plat-omap/include/mach/lcd_mipid.h index f8fbc4801e5..8e52c657228 100644 --- a/arch/arm/plat-omap/include/mach/lcd_mipid.h +++ b/arch/arm/plat-omap/include/mach/lcd_mipid.h @@ -16,7 +16,12 @@ enum mipid_test_result { struct mipid_platform_data { int nreset_gpio; int data_lines; + void (*shutdown)(struct mipid_platform_data *pdata); + void (*set_bklight_level)(struct mipid_platform_data *pdata, + int level); + int (*get_bklight_level)(struct mipid_platform_data *pdata); + int (*get_bklight_max)(struct mipid_platform_data *pdata); }; #endif diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index 81d5b36534b..7229b959330 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h @@ -25,11 +25,18 @@ #define OMAP24XX_NR_MMC 2 #define OMAP34XX_NR_MMC 3 +#define OMAP44XX_NR_MMC 5 #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE -#define HSMMC_SIZE 0x200 +#define OMAP3_HSMMC_SIZE 0x200 +#define OMAP4_HSMMC_SIZE 0x1000 #define OMAP2_MMC1_BASE 0x4809c000 #define OMAP2_MMC2_BASE 0x480b4000 #define OMAP3_MMC3_BASE 0x480ad000 +#define OMAP4_MMC4_BASE 0x480d1000 +#define OMAP4_MMC5_BASE 0x480d5000 +#define OMAP4_MMC_REG_OFFSET 0x100 +#define HSMMC5 (1 << 4) +#define HSMMC4 (1 << 3) #define HSMMC3 (1 << 2) #define HSMMC2 (1 << 1) #define HSMMC1 (1 << 0) @@ -59,6 +66,9 @@ struct omap_mmc_platform_data { int (*suspend)(struct device *dev, int slot); int (*resume)(struct device *dev, int slot); + /* Return context loss count due to PM states changing */ + int (*get_context_loss_count)(struct device *dev); + u64 dma_mask; struct omap_mmc_slot_data { @@ -80,12 +90,20 @@ struct omap_mmc_platform_data { /* use the internal clock */ unsigned internal_clock:1; + /* nonremovable e.g. eMMC */ + unsigned nonremovable:1; + + /* Try to sleep or power off when possible */ + unsigned power_saving:1; + int switch_pin; /* gpio (card detect) */ int gpio_wp; /* gpio (write protect) */ int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); int (* set_power)(struct device *dev, int slot, int power_on, int vdd); int (* get_ro)(struct device *dev, int slot); + int (*set_sleep)(struct device *dev, int slot, int sleep, + int vdd, int cardsleep); /* return MMC cover switch state, can be NULL if not supported. * diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h index 7b74d1255e0..b226bdf4573 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/arch/arm/plat-omap/include/mach/omapfb.h @@ -276,8 +276,8 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, void *fbi); struct omapfb_mem_region { - dma_addr_t paddr; - void *vaddr; + u32 paddr; + void __iomem *vaddr; unsigned long size; u8 type; /* OMAPFB_PLANE_MEM_* */ unsigned alloc:1; /* allocated by the driver */ diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h index e7fd0ecd73f..ae4dae1e370 100644 --- a/arch/blackfin/include/asm/sections.h +++ b/arch/blackfin/include/asm/sections.h @@ -1,9 +1,6 @@ #ifndef _BLACKFIN_SECTIONS_H #define _BLACKFIN_SECTIONS_H -/* nothing to see, move along */ -#include <asm-generic/sections.h> - /* only used when MTD_UCLINUX */ extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; @@ -15,4 +12,39 @@ extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], _ebss_l2[], _l2_lma_start[]; +#include <asm/mem_map.h> + +/* Blackfin systems have discontinuous memory map and no virtualized memory */ +static inline int arch_is_kernel_text(unsigned long addr) +{ + return + (L1_CODE_LENGTH && + addr >= (unsigned long)_stext_l1 && + addr < (unsigned long)_etext_l1) + || + (L2_LENGTH && + addr >= (unsigned long)_stext_l2 && + addr < (unsigned long)_etext_l2); +} +#define arch_is_kernel_text(addr) arch_is_kernel_text(addr) + +static inline int arch_is_kernel_data(unsigned long addr) +{ + return + (L1_DATA_A_LENGTH && + addr >= (unsigned long)_sdata_l1 && + addr < (unsigned long)_ebss_l1) + || + (L1_DATA_B_LENGTH && + addr >= (unsigned long)_sdata_b_l1 && + addr < (unsigned long)_ebss_b_l1) + || + (L2_LENGTH && + addr >= (unsigned long)_sdata_l2 && + addr < (unsigned long)_ebss_l2); +} +#define arch_is_kernel_data(addr) arch_is_kernel_data(addr) + +#include <asm-generic/sections.h> + #endif diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 011a1cdf0eb..6851e52ed5a 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -500,6 +500,10 @@ config HAVE_ARCH_NODEDATA_EXTENSION def_bool y depends on NUMA +config ARCH_PROC_KCORE_TEXT + def_bool y + depends on PROC_KCORE + config IA32_SUPPORT bool "Support for Linux/x86 binaries" help diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 1d286244a56..1857766a63c 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -617,7 +617,6 @@ mem_init (void) long reserved_pages, codesize, datasize, initsize; pg_data_t *pgdat; int i; - static struct kcore_list kcore_mem, kcore_vmem, kcore_kernel; BUG_ON(PTRS_PER_PGD * sizeof(pgd_t) != PAGE_SIZE); BUG_ON(PTRS_PER_PMD * sizeof(pmd_t) != PAGE_SIZE); @@ -639,10 +638,6 @@ mem_init (void) high_memory = __va(max_low_pfn * PAGE_SIZE); - kclist_add(&kcore_mem, __va(0), max_low_pfn * PAGE_SIZE); - kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); - kclist_add(&kcore_kernel, _stext, _end - _stext); - for_each_online_pgdat(pgdat) if (pgdat->bdata->node_bootmem_map) totalram_pages += free_all_bootmem_node(pgdat); diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 1f4ee4797a6..15aa1902a78 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -352,7 +352,6 @@ void __init paging_init(void) free_area_init_nodes(max_zone_pfns); } -static struct kcore_list kcore_mem, kcore_vmalloc; #ifdef CONFIG_64BIT static struct kcore_list kcore_kseg0; #endif @@ -409,11 +408,9 @@ void __init mem_init(void) if ((unsigned long) &_text > (unsigned long) CKSEG0) /* The -4 is a hack so that user tools don't have to handle the overflow. */ - kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4); + kclist_add(&kcore_kseg0, (void *) CKSEG0, + 0x80000000 - 4, KCORE_TEXT); #endif - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, - VMALLOC_END-VMALLOC_START); printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index 79890edfd67..3f24c298a3a 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c @@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts index f32c2811c6d..855782c5e5e 100644 --- a/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -159,6 +159,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 28e022ac417..9e2264b1000 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -173,6 +173,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts index 3febc4e91b1..9a603695723 100644 --- a/arch/powerpc/boot/dts/mpc8377_wlan.dts +++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts @@ -150,6 +150,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; clock-frequency = <133333333>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts index f720ab9af30..f70cf600083 100644 --- a/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -159,6 +159,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index a11ead8214b..4e6a1a407bb 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -173,6 +173,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts index 4fa221fd9bd..645ec51cc6e 100644 --- a/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -157,6 +157,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index e35dfba587c..72336d50452 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -171,6 +171,7 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; + sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 02fed27af7f..1d5570a1e45 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start =c_start, .next = c_next, .stop = c_stop, diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 3ef5084b90c..9ddcfb4dc13 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -242,39 +242,3 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -#ifdef CONFIG_PROC_KCORE -static struct kcore_list kcore_vmem; - -static int __init setup_kcore(void) -{ - int i; - - for (i = 0; i < lmb.memory.cnt; i++) { - unsigned long base; - unsigned long size; - struct kcore_list *kcore_mem; - - base = lmb.memory.region[i].base; - size = lmb.memory.region[i].size; - - kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); - if (!kcore_mem) - panic("%s: kmalloc failed\n", __func__); - - /* must stay under 32 bits */ - if ( 0xfffffffful - (unsigned long)__va(base) < size) { - size = 0xfffffffful - (unsigned long)(__va(base)); - printk(KERN_DEBUG "setup_kcore: restrict size=%lx\n", - size); - } - - kclist_add(kcore_mem, __va(base), size); - } - - kclist_add(&kcore_vmem, (void *)VMALLOC_START, - VMALLOC_END-VMALLOC_START); - - return 0; -} -module_init(setup_kcore); -#endif diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 31582329cd6..335c578b9cc 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -109,35 +109,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -#ifdef CONFIG_PROC_KCORE -static struct kcore_list kcore_vmem; - -static int __init setup_kcore(void) -{ - int i; - - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long base, size; - struct kcore_list *kcore_mem; - - base = lmb.memory.region[i].base; - size = lmb.memory.region[i].size; - - /* GFP_ATOMIC to avoid might_sleep warnings during boot */ - kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); - if (!kcore_mem) - panic("%s: kmalloc failed\n", __func__); - - kclist_add(kcore_mem, __va(base), size); - } - - kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); - - return 0; -} -module_init(setup_kcore); -#endif - static void pgd_ctor(void *addr) { memset(addr, 0, PGD_TABLE_SIZE); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 0e5c59b995e..59736317bf0 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -143,8 +143,8 @@ int arch_add_memory(int nid, u64 start, u64 size) * memory regions, find holes and callback for contiguous regions. */ int -walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, - int (*func)(unsigned long, unsigned long, void *)) +walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, + void *arg, int (*func)(unsigned long, unsigned long, void *)) { struct lmb_property res; unsigned long pfn, len; @@ -166,7 +166,7 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, } return ret; } -EXPORT_SYMBOL_GPL(walk_memory_resource); +EXPORT_SYMBOL_GPL(walk_system_ram_range); /* * Initialize the bootmem system and give it all the memory we diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index eae51ef9af2..3631a4f277e 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, void *p) return 0; } -static struct seq_operations hcall_inst_seq_ops = { +static const struct seq_operations hcall_inst_seq_ops = { .start = hc_start, .next = hc_next, .stop = hc_stop, diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index fabb7c6f48d..8173e38afd3 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -186,8 +186,6 @@ void __init paging_init(void) set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start)); } -static struct kcore_list kcore_mem, kcore_vmalloc; - void __init mem_init(void) { int codesize, datasize, initsize; @@ -226,10 +224,6 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, - VMALLOC_END - VMALLOC_START); - printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " "%dk data, %dk init)\n", nr_free_pages() << (PAGE_SHIFT-10), diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index d4de32f0f8a..6cdbf7e7351 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -258,7 +258,7 @@ static inline void *vio_dring_entry(struct vio_dring_state *dr, static inline u32 vio_dring_avail(struct vio_dring_state *dr, unsigned int ring_size) { - BUILD_BUG_ON(!is_power_of_2(ring_size)); + MAYBE_BUILD_BUG_ON(!is_power_of_2(ring_size)); return (dr->pending - ((dr->prod - dr->cons) & (ring_size - 1))); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e4ff5d1280c..7c7a54bed4a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1204,6 +1204,10 @@ config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on NUMA && X86_32 +config ARCH_PROC_KCORE_TEXT + def_bool y + depends on X86_64 && PROC_KCORE + config ARCH_SPARSEMEM_DEFAULT def_bool y depends on X86_64 diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index d82f39bb790..8d33bc5462d 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h @@ -1,7 +1,7 @@ /* * Access to user system call parameters and results * - * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions @@ -16,13 +16,13 @@ #include <linux/sched.h> #include <linux/err.h> -static inline long syscall_get_nr(struct task_struct *task, - struct pt_regs *regs) +/* + * Only the low 32 bits of orig_ax are meaningful, so we return int. + * This importantly ignores the high bits on 64-bit, so comparisons + * sign-extend the low 32 bits. + */ +static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - /* - * We always sign-extend a -1 value being set here, - * so this is always either -1L or a syscall number. - */ return regs->orig_ax; } diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 8d7d5c9c1be..7b058a2dc66 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -325,16 +325,6 @@ static int putreg(struct task_struct *child, return set_flags(child, value); #ifdef CONFIG_X86_64 - /* - * Orig_ax is really just a flag with small positive and - * negative values, so make sure to always sign-extend it - * from 32 bits so that it works correctly regardless of - * whether we come from a 32-bit environment or not. - */ - case offsetof(struct user_regs_struct, orig_ax): - value = (long) (s32) value; - break; - case offsetof(struct user_regs_struct,fs_base): if (value >= TASK_SIZE_OF(child)) return -EIO; @@ -1126,10 +1116,15 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value) case offsetof(struct user32, regs.orig_eax): /* - * Sign-extend the value so that orig_eax = -1 - * causes (long)orig_ax < 0 tests to fire correctly. + * A 32-bit debugger setting orig_eax means to restore + * the state of the task restarting a 32-bit syscall. + * Make sure we interpret the -ERESTART* codes correctly + * in case the task is not actually still sitting at the + * exit from a 32-bit syscall with TS_COMPAT still set. */ - regs->orig_ax = (long) (s32) value; + regs->orig_ax = value; + if (syscall_get_nr(child, regs) >= 0) + task_thread_info(child)->status |= TS_COMPAT; break; case offsetof(struct user32, regs.eflags): diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index b49b4f67453..30938c1d8d5 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -857,8 +857,6 @@ static void __init test_wp_bit(void) } } -static struct kcore_list kcore_mem, kcore_vmalloc; - void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; @@ -886,10 +884,6 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, - VMALLOC_END-VMALLOC_START); - printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " "%dk reserved, %dk data, %dk init, %ldk highmem)\n", nr_free_pages() << (PAGE_SHIFT-10), diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 810bd31e7f5..5a4398a6006 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -647,8 +647,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif /* CONFIG_MEMORY_HOTPLUG */ -static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, - kcore_modules, kcore_vsyscall; +static struct kcore_list kcore_vsyscall; void __init mem_init(void) { @@ -677,13 +676,8 @@ void __init mem_init(void) initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; /* Register memory areas for /proc/kcore */ - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, - VMALLOC_END-VMALLOC_START); - kclist_add(&kcore_kernel, &_stext, _end - _stext); - kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN); kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, - VSYSCALL_END - VSYSCALL_START); + VSYSCALL_END - VSYSCALL_START, KCORE_OTHER); printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n", |