Merge branch 'pm-next' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
This commit is contained in:
commit
bb3613aa34
@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
reset_devices [KNL] Force drivers to reset the underlying device
|
||||
during initialization.
|
||||
|
||||
resource_alloc_from_bottom
|
||||
Allocate new resources from the beginning of available
|
||||
space, not the end. If you need to use this, please
|
||||
report a bug.
|
||||
|
||||
resume= [SWSUSP]
|
||||
Specify the partition device for software suspend
|
||||
|
||||
|
@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
||||
zero)
|
||||
|
||||
bool pm_runtime_suspended(struct device *dev);
|
||||
- return true if the device's runtime PM status is 'suspended', or false
|
||||
otherwise
|
||||
- return true if the device's runtime PM status is 'suspended' and its
|
||||
'power.disable_depth' field is equal to zero, or false otherwise
|
||||
|
||||
void pm_runtime_allow(struct device *dev);
|
||||
- set the power.runtime_auto flag for the device and decrease its usage
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 37
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Flesh-Eating Bats with Fangs
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
|
||||
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
|
||||
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
|
||||
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
|
||||
obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o
|
||||
obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
|
||||
|
||||
# AT91SAM9260/AT91SAM9G20 board-specific support
|
||||
obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/at91sam9_smc.h>
|
||||
#include <mach/stamp9g20.h>
|
||||
|
||||
#include "sam9_smc.h"
|
||||
#include "generic.h"
|
||||
@ -38,11 +39,7 @@
|
||||
|
||||
static void __init pcontrol_g20_map_io(void)
|
||||
{
|
||||
/* Initialize processor: 18.432 MHz crystal */
|
||||
at91sam9260_initialize(18432000);
|
||||
|
||||
/* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
|
||||
at91_register_uart(0, 0, 0);
|
||||
stamp9g20_map_io();
|
||||
|
||||
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */
|
||||
at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
|
||||
@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void)
|
||||
|
||||
/* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */
|
||||
at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
|
||||
@ -66,38 +60,6 @@ static void __init init_irq(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
|
||||
*/
|
||||
static struct atmel_nand_data __initdata nand_data = {
|
||||
.ale = 21,
|
||||
.cle = 22,
|
||||
.rdy_pin = AT91_PIN_PC13,
|
||||
.enable_pin = AT91_PIN_PC14,
|
||||
};
|
||||
|
||||
/*
|
||||
* Bus timings; unit = 7.57ns
|
||||
*/
|
||||
static struct sam9_smc_config __initdata 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 | AT91_SMC_DBW_8,
|
||||
.tdf_cycles = 3,
|
||||
};
|
||||
|
||||
static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
|
||||
.ncs_read_setup = 16,
|
||||
.nrd_setup = 18,
|
||||
@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
|
||||
.tdf_cycles = 1,
|
||||
} };
|
||||
|
||||
static void __init add_device_nand(void)
|
||||
{
|
||||
/* configure chip-select 3 (NAND) */
|
||||
sam9_smc_configure(3, &nand_smc_config);
|
||||
at91_add_device_nand(&nand_data);
|
||||
}
|
||||
|
||||
|
||||
static void __init add_device_pcontrol(void)
|
||||
{
|
||||
/* configure chip-select 4 (IO compatible to 8051 X4 ) */
|
||||
@ -155,23 +109,6 @@ static void __init add_device_pcontrol(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCI (SD/MMC)
|
||||
* det_pin, wp_pin and vcc_pin are not connected
|
||||
*/
|
||||
#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
|
||||
static struct mci_platform_data __initdata mmc_data = {
|
||||
.slot[0] = {
|
||||
.bus_width = 4,
|
||||
},
|
||||
};
|
||||
#else
|
||||
static struct at91_mmc_data __initdata mmc_data = {
|
||||
.wire4 = 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Host port
|
||||
*/
|
||||
@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Dallas 1-Wire DS2431
|
||||
*/
|
||||
static struct w1_gpio_platform_data w1_gpio_pdata = {
|
||||
.pin = AT91_PIN_PA29,
|
||||
.is_open_drain = 1,
|
||||
};
|
||||
|
||||
static struct platform_device w1_device = {
|
||||
.name = "w1-gpio",
|
||||
.id = -1,
|
||||
.dev.platform_data = &w1_gpio_pdata,
|
||||
};
|
||||
|
||||
static void add_wire1(void)
|
||||
{
|
||||
at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
|
||||
at91_set_multi_drive(w1_gpio_pdata.pin, 1);
|
||||
platform_device_register(&w1_device);
|
||||
}
|
||||
|
||||
|
||||
static void __init pcontrol_g20_board_init(void)
|
||||
{
|
||||
at91_add_device_serial();
|
||||
add_device_nand();
|
||||
#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
|
||||
at91_add_device_mci(0, &mmc_data);
|
||||
#else
|
||||
at91_add_device_mmc(0, &mmc_data);
|
||||
#endif
|
||||
stamp9g20_board_init();
|
||||
at91_add_device_usbh(&usbh_data);
|
||||
at91_add_device_eth(&macb_data);
|
||||
at91_add_device_i2c(pcontrol_g20_i2c_devices,
|
||||
ARRAY_SIZE(pcontrol_g20_i2c_devices));
|
||||
add_wire1();
|
||||
add_device_pcontrol();
|
||||
at91_add_device_spi(pcontrol_g20_spi_devices,
|
||||
ARRAY_SIZE(pcontrol_g20_spi_devices));
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "generic.h"
|
||||
|
||||
|
||||
static void __init portuxg20_map_io(void)
|
||||
void __init stamp9g20_map_io(void)
|
||||
{
|
||||
/* Initialize processor: 18.432 MHz crystal */
|
||||
at91sam9260_initialize(18432000);
|
||||
@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void)
|
||||
/* DGBU on ttyS0. (Rx & Tx only) */
|
||||
at91_register_uart(0, 0, 0);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init stamp9g20evb_map_io(void)
|
||||
{
|
||||
stamp9g20_map_io();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static void __init portuxg20_map_io(void)
|
||||
{
|
||||
stamp9g20_map_io();
|
||||
|
||||
/* 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
|
||||
@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void)
|
||||
|
||||
/* USART5 on ttyS6. (Rx, Tx only) */
|
||||
at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init stamp9g20_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);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init init_irq(void)
|
||||
@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = {
|
||||
.pullup_pin = 0, /* pull-up driven by UDC */
|
||||
};
|
||||
|
||||
static struct at91_udc_data __initdata stamp9g20_udc_data = {
|
||||
static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
|
||||
.vbus_pin = AT91_PIN_PA22,
|
||||
.pullup_pin = 0, /* pull-up driven by UDC */
|
||||
};
|
||||
@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_led stamp9g20_leds[] = {
|
||||
static struct gpio_led stamp9g20evb_leds[] = {
|
||||
{
|
||||
.name = "D8",
|
||||
.gpio = AT91_PIN_PB18,
|
||||
@ -250,7 +248,7 @@ void add_w1(void)
|
||||
}
|
||||
|
||||
|
||||
static void __init generic_board_init(void)
|
||||
void __init stamp9g20_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
at91_add_device_serial();
|
||||
@ -262,34 +260,40 @@ static void __init generic_board_init(void)
|
||||
#else
|
||||
at91_add_device_mmc(0, &mmc_data);
|
||||
#endif
|
||||
/* USB Host */
|
||||
at91_add_device_usbh(&usbh_data);
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&macb_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c(NULL, 0);
|
||||
/* W1 */
|
||||
add_w1();
|
||||
}
|
||||
|
||||
static void __init portuxg20_board_init(void)
|
||||
{
|
||||
generic_board_init();
|
||||
/* SPI */
|
||||
at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
|
||||
stamp9g20_board_init();
|
||||
/* USB Host */
|
||||
at91_add_device_usbh(&usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&portuxg20_udc_data);
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&macb_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c(NULL, 0);
|
||||
/* SPI */
|
||||
at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
|
||||
/* LEDs */
|
||||
at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
|
||||
}
|
||||
|
||||
static void __init stamp9g20_board_init(void)
|
||||
static void __init stamp9g20evb_board_init(void)
|
||||
{
|
||||
generic_board_init();
|
||||
stamp9g20_board_init();
|
||||
/* USB Host */
|
||||
at91_add_device_usbh(&usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&stamp9g20_udc_data);
|
||||
at91_add_device_udc(&stamp9g20evb_udc_data);
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&macb_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c(NULL, 0);
|
||||
/* LEDs */
|
||||
at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
|
||||
at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
|
||||
}
|
||||
|
||||
MACHINE_START(PORTUXG20, "taskit PortuxG20")
|
||||
@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20")
|
||||
/* Maintainer: taskit GmbH */
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
.timer = &at91sam926x_timer,
|
||||
.map_io = stamp9g20_map_io,
|
||||
.map_io = stamp9g20evb_map_io,
|
||||
.init_irq = init_irq,
|
||||
.init_machine = stamp9g20_board_init,
|
||||
.init_machine = stamp9g20evb_board_init,
|
||||
MACHINE_END
|
||||
|
@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
|
||||
/* Now set uhpck values */
|
||||
uhpck.parent = &utmi_clk;
|
||||
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
||||
uhpck.rate_hz = utmi_clk.parent->rate_hz;
|
||||
uhpck.rate_hz = utmi_clk.rate_hz;
|
||||
uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
|
||||
}
|
||||
|
||||
|
7
arch/arm/mach-at91/include/mach/stamp9g20.h
Normal file
7
arch/arm/mach-at91/include/mach/stamp9g20.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __MACH_STAMP9G20_H
|
||||
#define __MACH_STAMP9G20_H
|
||||
|
||||
void stamp9g20_map_io(void);
|
||||
void stamp9g20_board_init(void);
|
||||
|
||||
#endif
|
@ -239,9 +239,19 @@ void omap3_save_scratchpad_contents(void)
|
||||
struct omap3_scratchpad_prcm_block prcm_block_contents;
|
||||
struct omap3_scratchpad_sdrc_block sdrc_block_contents;
|
||||
|
||||
/* Populate the Scratchpad contents */
|
||||
/*
|
||||
* Populate the Scratchpad contents
|
||||
*
|
||||
* The "get_*restore_pointer" functions are used to provide a
|
||||
* physical restore address where the ROM code jumps while waking
|
||||
* up from MPU OFF/OSWR state.
|
||||
* The restore pointer is stored into the scratchpad.
|
||||
*/
|
||||
scratchpad_contents.boot_config_ptr = 0x0;
|
||||
if (omap_rev() != OMAP3430_REV_ES3_0 &&
|
||||
if (cpu_is_omap3630())
|
||||
scratchpad_contents.public_restore_ptr =
|
||||
virt_to_phys(get_omap3630_restore_pointer());
|
||||
else if (omap_rev() != OMAP3430_REV_ES3_0 &&
|
||||
omap_rev() != OMAP3430_REV_ES3_1)
|
||||
scratchpad_contents.public_restore_ptr =
|
||||
virt_to_phys(get_restore_pointer());
|
||||
@ -474,4 +484,12 @@ void omap3_control_restore_context(void)
|
||||
omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI);
|
||||
return;
|
||||
}
|
||||
|
||||
void omap3630_ctrl_disable_rta(void)
|
||||
{
|
||||
if (!cpu_is_omap3630())
|
||||
return;
|
||||
omap_ctrl_writel(OMAP36XX_RTA_DISABLE, OMAP36XX_CONTROL_MEM_RTA_CTRL);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
|
||||
|
@ -204,6 +204,10 @@
|
||||
#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
|
||||
#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
|
||||
|
||||
/* 36xx-only RTA - Retention till Accesss control registers and bits */
|
||||
#define OMAP36XX_CONTROL_MEM_RTA_CTRL 0x40C
|
||||
#define OMAP36XX_RTA_DISABLE 0x0
|
||||
|
||||
/* 34xx D2D idle-related pins, handled by PM core */
|
||||
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
|
||||
#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
|
||||
@ -270,6 +274,8 @@
|
||||
#define OMAP343X_SCRATCHPAD_ROM (OMAP343X_CTRL_BASE + 0x860)
|
||||
#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
|
||||
#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
|
||||
#define OMAP343X_SCRATCHPAD_REGADDR(reg) OMAP2_L4_IO_ADDRESS(\
|
||||
OMAP343X_SCRATCHPAD + reg)
|
||||
|
||||
/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */
|
||||
#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0
|
||||
@ -347,10 +353,11 @@ extern void omap3_save_scratchpad_contents(void);
|
||||
extern void omap3_clear_scratchpad_contents(void);
|
||||
extern u32 *get_restore_pointer(void);
|
||||
extern u32 *get_es3_restore_pointer(void);
|
||||
extern u32 *get_omap3630_restore_pointer(void);
|
||||
extern u32 omap3_arm_context[128];
|
||||
extern void omap3_control_save_context(void);
|
||||
extern void omap3_control_restore_context(void);
|
||||
|
||||
extern void omap3630_ctrl_disable_rta(void);
|
||||
#else
|
||||
#define omap_ctrl_base_get() 0
|
||||
#define omap_ctrl_readb(x) 0
|
||||
|
@ -293,25 +293,26 @@ select_state:
|
||||
DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||
|
||||
/**
|
||||
* omap3_cpuidle_update_states - Update the cpuidle states.
|
||||
* omap3_cpuidle_update_states() - Update the cpuidle states
|
||||
* @mpu_deepest_state: Enable states upto and including this for mpu domain
|
||||
* @core_deepest_state: Enable states upto and including this for core domain
|
||||
*
|
||||
* Currently, this function toggles the validity of idle states based upon
|
||||
* the flag 'enable_off_mode'. When the flag is set all states are valid.
|
||||
* Else, states leading to OFF state set to be invalid.
|
||||
* This goes through the list of states available and enables and disables the
|
||||
* validity of C states based on deepest state that can be achieved for the
|
||||
* variable domain
|
||||
*/
|
||||
void omap3_cpuidle_update_states(void)
|
||||
void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
|
||||
struct omap3_processor_cx *cx = &omap3_power_states[i];
|
||||
|
||||
if (enable_off_mode) {
|
||||
if ((cx->mpu_state >= mpu_deepest_state) &&
|
||||
(cx->core_state >= core_deepest_state)) {
|
||||
cx->valid = 1;
|
||||
} else {
|
||||
if ((cx->mpu_state == PWRDM_POWER_OFF) ||
|
||||
(cx->core_state == PWRDM_POWER_OFF))
|
||||
cx->valid = 0;
|
||||
cx->valid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -452,6 +453,18 @@ void omap_init_power_states(void)
|
||||
omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
|
||||
omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_CHECK_BM;
|
||||
|
||||
/*
|
||||
* Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
|
||||
* enable OFF mode in a stable form for previous revisions.
|
||||
* we disable C7 state as a result.
|
||||
*/
|
||||
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
|
||||
omap3_power_states[OMAP3_STATE_C7].valid = 0;
|
||||
cpuidle_params_table[OMAP3_STATE_C7].valid = 0;
|
||||
WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
struct cpuidle_driver omap3_idle_driver = {
|
||||
@ -504,7 +517,10 @@ int __init omap3_idle_init(void)
|
||||
return -EINVAL;
|
||||
dev->state_count = count;
|
||||
|
||||
omap3_cpuidle_update_states();
|
||||
if (enable_off_mode)
|
||||
omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
|
||||
else
|
||||
omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
|
||||
|
||||
if (cpuidle_register_device(dev)) {
|
||||
printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||
|
@ -143,5 +143,5 @@ static int __init omap2_common_pm_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(omap2_common_pm_init);
|
||||
postcore_initcall(omap2_common_pm_init);
|
||||
|
||||
|
@ -58,7 +58,7 @@ extern u32 sleep_while_idle;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_IDLE)
|
||||
extern void omap3_cpuidle_update_states(void);
|
||||
extern void omap3_cpuidle_update_states(u32, u32);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
@ -80,9 +80,20 @@ extern void save_secure_ram_context(u32 *addr);
|
||||
extern void omap3_save_scratchpad_contents(void);
|
||||
|
||||
extern unsigned int omap24xx_idle_loop_suspend_sz;
|
||||
extern unsigned int omap34xx_suspend_sz;
|
||||
extern unsigned int save_secure_ram_context_sz;
|
||||
extern unsigned int omap24xx_cpu_suspend_sz;
|
||||
extern unsigned int omap34xx_cpu_suspend_sz;
|
||||
|
||||
#define PM_RTA_ERRATUM_i608 (1 << 0)
|
||||
#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1)
|
||||
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
|
||||
extern u16 pm34xx_errata;
|
||||
#define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id))
|
||||
extern void enable_omap3630_toggle_l2_on_restore(void);
|
||||
#else
|
||||
#define IS_PM34XX_ERRATUM(id) 0
|
||||
static inline void enable_omap3630_toggle_l2_on_restore(void) { }
|
||||
#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
|
||||
|
||||
#endif
|
||||
|
@ -301,14 +301,8 @@ out:
|
||||
|
||||
static int omap2_pm_begin(suspend_state_t state)
|
||||
{
|
||||
suspend_state = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_pm_prepare(void)
|
||||
{
|
||||
/* We cannot sleep in idle until we have resumed */
|
||||
disable_hlt();
|
||||
suspend_state = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -349,21 +343,15 @@ static int omap2_pm_enter(suspend_state_t state)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void omap2_pm_finish(void)
|
||||
{
|
||||
enable_hlt();
|
||||
}
|
||||
|
||||
static void omap2_pm_end(void)
|
||||
{
|
||||
suspend_state = PM_SUSPEND_ON;
|
||||
enable_hlt();
|
||||
}
|
||||
|
||||
static struct platform_suspend_ops omap_pm_ops = {
|
||||
.begin = omap2_pm_begin,
|
||||
.prepare = omap2_pm_prepare,
|
||||
.enter = omap2_pm_enter,
|
||||
.finish = omap2_pm_finish,
|
||||
.end = omap2_pm_end,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
@ -68,6 +68,9 @@ static inline bool is_suspending(void)
|
||||
#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
|
||||
#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8
|
||||
|
||||
/* pm34xx errata defined in pm.h */
|
||||
u16 pm34xx_errata;
|
||||
|
||||
struct power_state {
|
||||
struct powerdomain *pwrdm;
|
||||
u32 next_state;
|
||||
@ -143,7 +146,7 @@ static void omap3_core_save_context(void)
|
||||
|
||||
/*
|
||||
* Force write last pad into memory, as this can fail in some
|
||||
* cases according to erratas 1.157, 1.185
|
||||
* cases according to errata 1.157, 1.185
|
||||
*/
|
||||
omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
|
||||
OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
|
||||
@ -430,7 +433,7 @@ void omap_sram_idle(void)
|
||||
/*
|
||||
* On EMU/HS devices ROM code restores a SRDC value
|
||||
* from scratchpad which has automatic self refresh on timeout
|
||||
* of AUTO_CNT = 1 enabled. This takes care of errata 1.142.
|
||||
* of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
|
||||
* Hence store/restore the SDRC_POWER register here.
|
||||
*/
|
||||
if (omap_rev() >= OMAP3430_REV_ES3_0 &&
|
||||
@ -529,12 +532,6 @@ out:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int omap3_pm_prepare(void)
|
||||
{
|
||||
disable_hlt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_pm_suspend(void)
|
||||
{
|
||||
struct power_state *pwrst;
|
||||
@ -597,14 +594,10 @@ static int omap3_pm_enter(suspend_state_t unused)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void omap3_pm_finish(void)
|
||||
{
|
||||
enable_hlt();
|
||||
}
|
||||
|
||||
/* Hooks to enable / disable UART interrupts during suspend */
|
||||
static int omap3_pm_begin(suspend_state_t state)
|
||||
{
|
||||
disable_hlt();
|
||||
suspend_state = state;
|
||||
omap_uart_enable_irqs(0);
|
||||
return 0;
|
||||
@ -614,15 +607,14 @@ static void omap3_pm_end(void)
|
||||
{
|
||||
suspend_state = PM_SUSPEND_ON;
|
||||
omap_uart_enable_irqs(1);
|
||||
enable_hlt();
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_suspend_ops omap_pm_ops = {
|
||||
.begin = omap3_pm_begin,
|
||||
.end = omap3_pm_end,
|
||||
.prepare = omap3_pm_prepare,
|
||||
.enter = omap3_pm_enter,
|
||||
.finish = omap3_pm_finish,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
@ -925,12 +917,29 @@ void omap3_pm_off_mode_enable(int enable)
|
||||
state = PWRDM_POWER_RET;
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
omap3_cpuidle_update_states();
|
||||
/*
|
||||
* Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
|
||||
* enable OFF mode in a stable form for previous revisions, restrict
|
||||
* instead to RET
|
||||
*/
|
||||
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
|
||||
omap3_cpuidle_update_states(state, PWRDM_POWER_RET);
|
||||
else
|
||||
omap3_cpuidle_update_states(state, state);
|
||||
#endif
|
||||
|
||||
list_for_each_entry(pwrst, &pwrst_list, node) {
|
||||
pwrst->next_state = state;
|
||||
omap_set_pwrdm_state(pwrst->pwrdm, state);
|
||||
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
|
||||
pwrst->pwrdm == core_pwrdm &&
|
||||
state == PWRDM_POWER_OFF) {
|
||||
pwrst->next_state = PWRDM_POWER_RET;
|
||||
WARN_ONCE(1,
|
||||
"%s: Core OFF disabled due to errata i583\n",
|
||||
__func__);
|
||||
} else {
|
||||
pwrst->next_state = state;
|
||||
}
|
||||
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1002,6 +1011,17 @@ void omap_push_sram_idle(void)
|
||||
save_secure_ram_context_sz);
|
||||
}
|
||||
|
||||
static void __init pm_errata_configure(void)
|
||||
{
|
||||
if (cpu_is_omap3630()) {
|
||||
pm34xx_errata |= PM_RTA_ERRATUM_i608;
|
||||
/* Enable the l2 cache toggling in sleep logic */
|
||||
enable_omap3630_toggle_l2_on_restore();
|
||||
if (omap_rev() < OMAP3630_REV_ES1_2)
|
||||
pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init omap3_pm_init(void)
|
||||
{
|
||||
struct power_state *pwrst, *tmp;
|
||||
@ -1011,6 +1031,8 @@ static int __init omap3_pm_init(void)
|
||||
if (!cpu_is_omap34xx())
|
||||
return -ENODEV;
|
||||
|
||||
pm_errata_configure();
|
||||
|
||||
printk(KERN_ERR "Power Management for TI OMAP3.\n");
|
||||
|
||||
/* XXX prcm_setup_regs needs to be before enabling hw
|
||||
@ -1058,6 +1080,14 @@ static int __init omap3_pm_init(void)
|
||||
pm_idle = omap3_pm_idle;
|
||||
omap3_idle_init();
|
||||
|
||||
/*
|
||||
* RTA is disabled during initialization as per erratum i608
|
||||
* it is safer to disable RTA by the bootloader, but we would like
|
||||
* to be doubly sure here and prevent any mishaps.
|
||||
*/
|
||||
if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608))
|
||||
omap3630_ctrl_disable_rta();
|
||||
|
||||
clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
|
||||
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
|
||||
omap3_secure_ram_storage =
|
||||
|
@ -31,12 +31,6 @@ struct power_state {
|
||||
static LIST_HEAD(pwrst_list);
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int omap4_pm_prepare(void)
|
||||
{
|
||||
disable_hlt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_pm_suspend(void)
|
||||
{
|
||||
do_wfi();
|
||||
@ -59,28 +53,22 @@ static int omap4_pm_enter(suspend_state_t suspend_state)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void omap4_pm_finish(void)
|
||||
{
|
||||
enable_hlt();
|
||||
return;
|
||||
}
|
||||
|
||||
static int omap4_pm_begin(suspend_state_t state)
|
||||
{
|
||||
disable_hlt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap4_pm_end(void)
|
||||
{
|
||||
enable_hlt();
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_suspend_ops omap_pm_ops = {
|
||||
.begin = omap4_pm_begin,
|
||||
.end = omap4_pm_end,
|
||||
.prepare = omap4_pm_prepare,
|
||||
.enter = omap4_pm_enter,
|
||||
.finish = omap4_pm_finish,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
|
@ -74,5 +74,4 @@ static inline u32 sms_read_reg(u16 reg)
|
||||
*/
|
||||
#define SDRC_MPURATE_LOOPS 96
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,9 +28,16 @@ config S3C2412_DMA
|
||||
|
||||
config S3C2412_PM
|
||||
bool
|
||||
select S3C2412_PM_SLEEP
|
||||
help
|
||||
Internal config node to apply S3C2412 power management
|
||||
|
||||
config S3C2412_PM_SLEEP
|
||||
bool
|
||||
help
|
||||
Internal config node to apply sleep for S3C2412 power management.
|
||||
Can be selected by another SoCs with similar sleep procedure.
|
||||
|
||||
# Note, the S3C2412 IOtiming support is in plat-s3c24xx
|
||||
|
||||
config S3C2412_CPUFREQ
|
||||
|
@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o
|
||||
obj-$(CONFIG_CPU_S3C2412) += clock.o
|
||||
obj-$(CONFIG_CPU_S3C2412) += gpio.o
|
||||
obj-$(CONFIG_S3C2412_DMA) += dma.o
|
||||
obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_S3C2412_PM) += pm.o
|
||||
obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
|
||||
obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
|
||||
|
||||
# Machine support
|
||||
|
@ -27,6 +27,7 @@ config S3C2416_DMA
|
||||
|
||||
config S3C2416_PM
|
||||
bool
|
||||
select S3C2412_PM_SLEEP
|
||||
help
|
||||
Internal config node to apply S3C2416 power management
|
||||
|
||||
|
@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = {
|
||||
static struct max8998_platform_data aquila_max8998_pdata = {
|
||||
.num_regulators = ARRAY_SIZE(aquila_regulators),
|
||||
.regulators = aquila_regulators,
|
||||
.buck1_set1 = S5PV210_GPH0(3),
|
||||
.buck1_set2 = S5PV210_GPH0(4),
|
||||
.buck2_set3 = S5PV210_GPH0(5),
|
||||
.buck1_max_voltage1 = 1200000,
|
||||
.buck1_max_voltage2 = 1200000,
|
||||
.buck2_max_voltage = 1200000,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = {
|
||||
static struct max8998_platform_data goni_max8998_pdata = {
|
||||
.num_regulators = ARRAY_SIZE(goni_regulators),
|
||||
.regulators = goni_regulators,
|
||||
.buck1_set1 = S5PV210_GPH0(3),
|
||||
.buck1_set2 = S5PV210_GPH0(4),
|
||||
.buck2_set3 = S5PV210_GPH0(5),
|
||||
.buck1_max_voltage1 = 1200000,
|
||||
.buck1_max_voltage2 = 1200000,
|
||||
.buck2_max_voltage = 1200000,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
* Copyright (C) 2008 Renesas Solutions Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -14,24 +15,45 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#define INTCA_BASE 0xe6980000
|
||||
#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
|
||||
#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
|
||||
#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
|
||||
#define INTLVLB_OFFS 0x00000034 /* previous priority level */
|
||||
|
||||
.macro disable_fiq
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
ldr \base, =INTFLGA
|
||||
ldr \base, =INTCA_BASE
|
||||
.endm
|
||||
|
||||
.macro arch_ret_to_user, tmp1, tmp2
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
ldr \irqnr, [\base]
|
||||
/* The single INTFLGA read access below results in the following:
|
||||
*
|
||||
* 1. INTLVLB is updated with old priority value from INTLVLA
|
||||
* 2. Highest priority interrupt is accepted
|
||||
* 3. INTLVLA is updated to contain priority of accepted interrupt
|
||||
* 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
|
||||
*/
|
||||
ldr \irqnr, [\base, #INTFLGA_OFFS]
|
||||
|
||||
/* Restore INTLVLA with the value saved in INTLVLB.
|
||||
* This is required to support interrupt priorities properly.
|
||||
*/
|
||||
ldrb \tmp, [\base, #INTLVLB_OFFS]
|
||||
strb \tmp, [\base, #INTLVLA_OFFS]
|
||||
|
||||
/* Handle invalid vector number case */
|
||||
cmp \irqnr, #0
|
||||
beq 1000f
|
||||
/* intevt to irq number */
|
||||
|
||||
/* Convert vector to irq number, same as the evt2irq() macro */
|
||||
lsr \irqnr, \irqnr, #0x5
|
||||
subs \irqnr, \irqnr, #16
|
||||
|
||||
|
@ -2,6 +2,6 @@
|
||||
#define __ASM_MACH_VMALLOC_H
|
||||
|
||||
/* Vmalloc at ... - 0xe5ffffff */
|
||||
#define VMALLOC_END 0xe6000000
|
||||
#define VMALLOC_END 0xe6000000UL
|
||||
|
||||
#endif /* __ASM_MACH_VMALLOC_H */
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifndef __ARCH_ARM_OMAP_SRAM_H
|
||||
#define __ARCH_ARM_OMAP_SRAM_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void * omap_sram_push(void * start, unsigned long size);
|
||||
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
|
||||
|
||||
@ -74,4 +75,14 @@ extern void omap_push_sram_idle(void);
|
||||
static inline void omap_push_sram_idle(void) {}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* OMAP2+: define the SRAM PA addresses.
|
||||
* Used by the SRAM management code and the idle sleep code.
|
||||
*/
|
||||
#define OMAP2_SRAM_PA 0x40200000
|
||||
#define OMAP3_SRAM_PA 0x40200000
|
||||
#define OMAP4_SRAM_PA 0x40300000
|
||||
|
||||
#endif
|
||||
|
@ -41,15 +41,12 @@
|
||||
|
||||
#define OMAP1_SRAM_PA 0x20000000
|
||||
#define OMAP1_SRAM_VA VMALLOC_END
|
||||
#define OMAP2_SRAM_PA 0x40200000
|
||||
#define OMAP2_SRAM_PUB_PA 0x4020f800
|
||||
#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
|
||||
#define OMAP2_SRAM_VA 0xfe400000
|
||||
#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
|
||||
#define OMAP3_SRAM_PA 0x40200000
|
||||
#define OMAP3_SRAM_VA 0xfe400000
|
||||
#define OMAP3_SRAM_PUB_PA 0x40208000
|
||||
#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
|
||||
#define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000)
|
||||
#define OMAP4_SRAM_PA 0x40300000
|
||||
#define OMAP4_SRAM_VA 0xfe400000
|
||||
#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
|
||||
#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000)
|
||||
|
@ -8,7 +8,7 @@ config PLAT_S3C24XX
|
||||
default y
|
||||
select NO_IOPORT
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select S3C_DEVICE_NAND
|
||||
select S3C_DEV_NAND
|
||||
select S3C_GPIO_CFG_S3C24XX
|
||||
help
|
||||
Base platform code for any Samsung S3C24XX device
|
||||
|
@ -19,6 +19,8 @@ config MIPS
|
||||
select GENERIC_ATOMIC64 if !64BIT
|
||||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select GENERIC_IRQ_PROBE
|
||||
|
||||
menu "Machine selection"
|
||||
|
||||
@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB
|
||||
|
||||
endchoice
|
||||
|
||||
config FORCE_MAX_ZONEORDER
|
||||
int "Maximum zone order"
|
||||
range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
|
||||
default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
|
||||
range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
|
||||
default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
|
||||
range 11 64
|
||||
default "11"
|
||||
help
|
||||
The kernel memory allocator divides physically contiguous memory
|
||||
blocks into "zones", where each zone is a power of two number of
|
||||
pages. This option selects the largest power of two that the kernel
|
||||
keeps in the memory allocator. If you need to allocate very large
|
||||
blocks of physically contiguous memory, then you may need to
|
||||
increase this value.
|
||||
|
||||
This config option is actually maximum order plus one. For example,
|
||||
a value of 11 means that the largest free memory block is 2^10 pages.
|
||||
|
||||
The page size is not necessarily 4KB. Keep this in mind
|
||||
when choosing a value for this option.
|
||||
|
||||
config BOARD_SCACHE
|
||||
bool
|
||||
|
||||
@ -1921,20 +1945,6 @@ config CPU_R4000_WORKAROUNDS
|
||||
config CPU_R4400_WORKAROUNDS
|
||||
bool
|
||||
|
||||
#
|
||||
# Use the generic interrupt handling code in kernel/irq/:
|
||||
#
|
||||
config GENERIC_HARDIRQS
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_IRQ_PROBE
|
||||
bool
|
||||
default y
|
||||
|
||||
config IRQ_PER_CPU
|
||||
bool
|
||||
|
||||
#
|
||||
# - Highmem only makes sense for the 32-bit kernel.
|
||||
# - The current highmem code will only work properly on physically indexed
|
||||
|
@ -27,6 +27,7 @@
|
||||
static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
|
||||
unsigned int old_state)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
switch (state) {
|
||||
case 0:
|
||||
if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
|
||||
@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
|
||||
serial8250_do_pm(port, state, old_state);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PORT(_base, _irq) \
|
||||
|
@ -54,10 +54,9 @@ void __init prom_init(void)
|
||||
|
||||
prom_init_cmdline();
|
||||
memsize_str = prom_getenv("memsize");
|
||||
if (!memsize_str)
|
||||
if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
|
||||
memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
|
||||
else
|
||||
strict_strtoul(memsize_str, 0, &memsize);
|
||||
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
||||
|
@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
|
||||
calculate(base_clock, frequency, &prediv, &postdiv, &mul);
|
||||
|
||||
writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
|
||||
msleep(1);
|
||||
mdelay(1);
|
||||
writel(4, &clock->pll);
|
||||
while (readl(&clock->pll) & PLL_STATUS)
|
||||
;
|
||||
writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
|
||||
msleep(75);
|
||||
mdelay(75);
|
||||
}
|
||||
|
||||
static void __init tnetd7300_init_clocks(void)
|
||||
@ -456,7 +456,7 @@ void clk_put(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
int __init ar7_init_clocks(void)
|
||||
void __init ar7_init_clocks(void)
|
||||
{
|
||||
switch (ar7_chip_id()) {
|
||||
case AR7_CHIP_7100:
|
||||
@ -472,7 +472,4 @@ int __init ar7_init_clocks(void)
|
||||
}
|
||||
/* adjust vbus clock rate */
|
||||
vbus_clk.rate = bus_clk.rate / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(ar7_init_clocks);
|
||||
|
@ -30,6 +30,9 @@ void __init plat_time_init(void)
|
||||
{
|
||||
struct clk *cpu_clk;
|
||||
|
||||
/* Initialize ar7 clocks so the CPU clock frequency is correct */
|
||||
ar7_init_clocks();
|
||||
|
||||
cpu_clk = clk_get(NULL, "cpu");
|
||||
if (IS_ERR(cpu_clk)) {
|
||||
printk(KERN_ERR "unable to get cpu clock\n");
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
#include <bcm47xx.h>
|
||||
#include <asm/fw/cfe/cfe_api.h>
|
||||
#include <asm/mach-bcm47xx/nvram.h>
|
||||
|
||||
struct ssb_bus ssb_bcm47xx;
|
||||
@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void str2eaddr(char *str, char *dest)
|
||||
#define READ_FROM_NVRAM(_outvar, name, buf) \
|
||||
if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
|
||||
sprom->_outvar = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
|
||||
{
|
||||
int i = 0;
|
||||
char buf[100];
|
||||
u32 boardflags;
|
||||
|
||||
if (str == NULL) {
|
||||
memset(dest, 0, 6);
|
||||
return;
|
||||
memset(sprom, 0, sizeof(struct ssb_sprom));
|
||||
|
||||
sprom->revision = 1; /* Fallback: Old hardware does not define this. */
|
||||
READ_FROM_NVRAM(revision, "sromrev", buf);
|
||||
if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
|
||||
nvram_parse_macaddr(buf, sprom->il0mac);
|
||||
if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
|
||||
nvram_parse_macaddr(buf, sprom->et0mac);
|
||||
if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
|
||||
nvram_parse_macaddr(buf, sprom->et1mac);
|
||||
READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
|
||||
READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
|
||||
READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
|
||||
READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
|
||||
READ_FROM_NVRAM(board_rev, "boardrev", buf);
|
||||
READ_FROM_NVRAM(country_code, "ccode", buf);
|
||||
READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
|
||||
READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
|
||||
READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
|
||||
READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
|
||||
READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
|
||||
READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
|
||||
READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
|
||||
READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
|
||||
READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
|
||||
READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
|
||||
READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
|
||||
READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
|
||||
READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
|
||||
READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
|
||||
READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
|
||||
READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
|
||||
READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
|
||||
READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
|
||||
READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
|
||||
READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
|
||||
READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
|
||||
READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
|
||||
READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
|
||||
READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
|
||||
READ_FROM_NVRAM(tri2g, "tri2g", buf);
|
||||
READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
|
||||
READ_FROM_NVRAM(tri5g, "tri5g", buf);
|
||||
READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
|
||||
READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
|
||||
READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
|
||||
READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
|
||||
READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
|
||||
READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
|
||||
READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
|
||||
READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
|
||||
READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
|
||||
READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
|
||||
READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
|
||||
READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
|
||||
READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
|
||||
READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
|
||||
READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
|
||||
READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
|
||||
|
||||
if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
|
||||
boardflags = simple_strtoul(buf, NULL, 0);
|
||||
if (boardflags) {
|
||||
sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
|
||||
sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
dest[i++] = (char) simple_strtoul(str, NULL, 16);
|
||||
str += 2;
|
||||
if (!*str++ || i == 6)
|
||||
break;
|
||||
if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
|
||||
boardflags = simple_strtoul(buf, NULL, 0);
|
||||
if (boardflags) {
|
||||
sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
|
||||
sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
||||
struct ssb_init_invariants *iv)
|
||||
{
|
||||
char buf[100];
|
||||
char buf[20];
|
||||
|
||||
/* Fill boardinfo structure */
|
||||
memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
|
||||
|
||||
if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
|
||||
if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
|
||||
iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
|
||||
else
|
||||
iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
|
||||
if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
|
||||
iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
|
||||
if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
|
||||
iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
|
||||
if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
|
||||
if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
|
||||
iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
|
||||
|
||||
/* Fill sprom structure */
|
||||
memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
|
||||
iv->sprom.revision = 3;
|
||||
bcm47xx_fill_sprom(&iv->sprom);
|
||||
|
||||
if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
|
||||
str2eaddr(buf, iv->sprom.et0mac);
|
||||
|
||||
if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
|
||||
str2eaddr(buf, iv->sprom.et1mac);
|
||||
|
||||
if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
|
||||
iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
|
||||
iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
|
||||
iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
|
||||
nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
|
||||
iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
|
||||
if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
int err;
|
||||
char buf[100];
|
||||
struct ssb_mipscore *mcore;
|
||||
|
||||
err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
|
||||
bcm47xx_get_invariants);
|
||||
if (err)
|
||||
panic("Failed to initialize SSB bus (err %d)\n", err);
|
||||
|
||||
mcore = &ssb_bcm47xx.mipscore;
|
||||
if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
|
||||
if (strstr(buf, "console=ttyS1")) {
|
||||
struct ssb_serial_port port;
|
||||
|
||||
printk(KERN_DEBUG "Swapping serial ports!\n");
|
||||
/* swap serial ports */
|
||||
memcpy(&port, &mcore->serial_ports[0], sizeof(port));
|
||||
memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
|
||||
sizeof(port));
|
||||
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
|
||||
}
|
||||
}
|
||||
|
||||
_machine_restart = bcm47xx_machine_restart;
|
||||
_machine_halt = bcm47xx_machine_halt;
|
||||
pm_power_off = bcm47xx_machine_halt;
|
||||
|
@ -111,8 +111,8 @@
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
|
||||
*/
|
||||
|
||||
#define PRID_IMP_BMIPS4KC 0x4000
|
||||
#define PRID_IMP_BMIPS32 0x8000
|
||||
#define PRID_IMP_BMIPS32_REV4 0x4000
|
||||
#define PRID_IMP_BMIPS32_REV8 0x8000
|
||||
#define PRID_IMP_BMIPS3300 0x9000
|
||||
#define PRID_IMP_BMIPS3300_ALT 0x9100
|
||||
#define PRID_IMP_BMIPS3300_BUG 0x0000
|
||||
|
@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32;
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
set_personality(PER_LINUX); \
|
||||
if (personality(current->personality) != PER_LINUX) \
|
||||
set_personality(PER_LINUX); \
|
||||
\
|
||||
current->thread.abi = &mips_abi; \
|
||||
} while (0)
|
||||
@ -296,6 +297,8 @@ do { \
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
unsigned int p; \
|
||||
\
|
||||
clear_thread_flag(TIF_32BIT_REGS); \
|
||||
clear_thread_flag(TIF_32BIT_ADDR); \
|
||||
\
|
||||
@ -304,7 +307,8 @@ do { \
|
||||
else \
|
||||
current->thread.abi = &mips_abi; \
|
||||
\
|
||||
if (current->personality != PER_LINUX32) \
|
||||
p = personality(current->personality); \
|
||||
if (p != PER_LINUX32 && p != PER_LINUX) \
|
||||
set_personality(PER_LINUX); \
|
||||
} while (0)
|
||||
|
||||
|
@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \
|
||||
"dsrl32 %L0, %L0, 0" "\n\t" \
|
||||
"dsll32 %M0, %M0, 0" "\n\t" \
|
||||
"or %L0, %L0, %M0" "\n\t" \
|
||||
".set push" "\n\t" \
|
||||
".set noreorder" "\n\t" \
|
||||
".set nomacro" "\n\t" \
|
||||
"sd %L0, %2" "\n\t" \
|
||||
".set pop" "\n\t" \
|
||||
".set mips0" "\n" \
|
||||
: "=r" (__tmp) \
|
||||
: "0" (__val), "m" (*__mem)); \
|
||||
: "0" (__val), "R" (*__mem)); \
|
||||
if (irq) \
|
||||
local_irq_restore(__flags); \
|
||||
} else \
|
||||
@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
|
||||
local_irq_save(__flags); \
|
||||
__asm__ __volatile__( \
|
||||
".set mips3" "\t\t# __readq" "\n\t" \
|
||||
".set push" "\n\t" \
|
||||
".set noreorder" "\n\t" \
|
||||
".set nomacro" "\n\t" \
|
||||
"ld %L0, %1" "\n\t" \
|
||||
".set pop" "\n\t" \
|
||||
"dsra32 %M0, %L0, 0" "\n\t" \
|
||||
"sll %L0, %L0, 0" "\n\t" \
|
||||
".set mips0" "\n" \
|
||||
: "=r" (__val) \
|
||||
: "m" (*__mem)); \
|
||||
: "R" (*__mem)); \
|
||||
if (irq) \
|
||||
local_irq_restore(__flags); \
|
||||
} else { \
|
||||
|
@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit)
|
||||
}
|
||||
|
||||
int __init ar7_gpio_init(void);
|
||||
|
||||
int __init ar7_gpio_init(void);
|
||||
void __init ar7_init_clocks(void);
|
||||
|
||||
#endif /* __AR7_H__ */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define __NVRAM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
struct nvram_header {
|
||||
u32 magic;
|
||||
@ -36,4 +37,10 @@ struct nvram_header {
|
||||
|
||||
extern int nvram_getenv(char *name, char *val, size_t val_len);
|
||||
|
||||
static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
|
||||
{
|
||||
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
|
||||
&macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 2009 Qi Hardware inc.,
|
||||
* Author: Xiangfu Liu <xiangfu@qi-hardware.com>
|
||||
* Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
|
||||
* Copyright 2010, Lars-Peter Clausen <lars@metafoo.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 or later
|
||||
@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = {
|
||||
QI_LB60_GPIO_KEYIN(3),
|
||||
QI_LB60_GPIO_KEYIN(4),
|
||||
QI_LB60_GPIO_KEYIN(5),
|
||||
QI_LB60_GPIO_KEYIN(7),
|
||||
QI_LB60_GPIO_KEYIN(6),
|
||||
QI_LB60_GPIO_KEYIN8,
|
||||
};
|
||||
|
||||
|
@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = {
|
||||
|
||||
/* PCM */
|
||||
struct platform_device jz4740_pcm_device = {
|
||||
.name = "jz4740-pcm",
|
||||
.name = "jz4740-pcm-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/mach-jz4740/base.h>
|
||||
|
||||
void jz4740_init_cmdline(int argc, char *argv[])
|
||||
static __init void jz4740_init_cmdline(int argc, char *argv[])
|
||||
{
|
||||
unsigned int count = COMMAND_LINE_SIZE - 1;
|
||||
int i;
|
||||
|
@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
|
||||
cnt = read_c0_count();
|
||||
cnt += delta;
|
||||
write_c0_compare(cnt);
|
||||
res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
|
||||
res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
{
|
||||
decode_configs(c);
|
||||
switch (c->processor_id & 0xff00) {
|
||||
case PRID_IMP_BMIPS32:
|
||||
case PRID_IMP_BMIPS32_REV4:
|
||||
case PRID_IMP_BMIPS32_REV8:
|
||||
c->cputype = CPU_BMIPS32;
|
||||
__cpu_name[cpu] = "Broadcom BMIPS32";
|
||||
break;
|
||||
@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
__cpu_name[cpu] = "Broadcom BMIPS5000";
|
||||
c->options |= MIPS_CPU_ULRI;
|
||||
break;
|
||||
case PRID_IMP_BMIPS4KC:
|
||||
c->cputype = CPU_4KC;
|
||||
__cpu_name[cpu] = "MIPS 4Kc";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
|
||||
|
||||
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
|
||||
{
|
||||
unsigned int p = personality & 0xffffffff;
|
||||
int ret;
|
||||
personality &= 0xffffffff;
|
||||
|
||||
if (personality(current->personality) == PER_LINUX32 &&
|
||||
personality == PER_LINUX)
|
||||
personality = PER_LINUX32;
|
||||
ret = sys_personality(personality);
|
||||
if (ret == PER_LINUX32)
|
||||
ret = PER_LINUX;
|
||||
personality(p) == PER_LINUX)
|
||||
p = (p & ~PER_MASK) | PER_LINUX32;
|
||||
ret = sys_personality(p);
|
||||
if (ret != -1 && personality(ret) == PER_LINUX32)
|
||||
ret = (ret & ~PER_MASK) | PER_LINUX;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
childregs->regs[7] = 0; /* Clear error flag */
|
||||
|
||||
childregs->regs[2] = 0; /* Child gets zero as return value */
|
||||
regs->regs[2] = p->pid;
|
||||
|
||||
if (childregs->cp0_status & ST0_CU0) {
|
||||
childregs->regs[28] = (unsigned long) ti;
|
||||
|
@ -100,7 +100,7 @@ void __init device_tree_init(void)
|
||||
return;
|
||||
|
||||
base = virt_to_phys((void *)initial_boot_params);
|
||||
size = initial_boot_params->totalsize;
|
||||
size = be32_to_cpu(initial_boot_params->totalsize);
|
||||
|
||||
/* Before we do anything, lets reserve the dt blob */
|
||||
reserve_mem_mach(base, size);
|
||||
|
@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void)
|
||||
{
|
||||
extern int gic_present;
|
||||
|
||||
/* This is Malta specific: IPI,performance and timer inetrrupts */
|
||||
/* This is Malta specific: IPI,performance and timer interrupts */
|
||||
if (gic_present)
|
||||
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
|
||||
STATUSF_IP6 | STATUSF_IP7);
|
||||
|
@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void);
|
||||
extern asmlinkage void handle_reserved(void);
|
||||
|
||||
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
|
||||
struct mips_fpu_struct *ctx, int has_fpu);
|
||||
struct mips_fpu_struct *ctx, int has_fpu,
|
||||
void *__user *fault_addr);
|
||||
|
||||
void (*board_be_init)(void);
|
||||
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
|
||||
@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs)
|
||||
force_sig_info(SIGFPE, &info, current);
|
||||
}
|
||||
|
||||
static int process_fpemu_return(int sig, void __user *fault_addr)
|
||||
{
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
struct siginfo si = {0};
|
||||
si.si_addr = fault_addr;
|
||||
si.si_signo = sig;
|
||||
if (sig == SIGSEGV) {
|
||||
if (find_vma(current->mm, (unsigned long)fault_addr))
|
||||
si.si_code = SEGV_ACCERR;
|
||||
else
|
||||
si.si_code = SEGV_MAPERR;
|
||||
} else {
|
||||
si.si_code = BUS_ADRERR;
|
||||
}
|
||||
force_sig_info(sig, &si, current);
|
||||
return 1;
|
||||
} else if (sig) {
|
||||
force_sig(sig, current);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Delayed fp exceptions when doing a lazy ctx switch XXX
|
||||
*/
|
||||
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||
{
|
||||
siginfo_t info;
|
||||
siginfo_t info = {0};
|
||||
|
||||
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
|
||||
== NOTIFY_STOP)
|
||||
@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||
|
||||
if (fcr31 & FPU_CSR_UNI_X) {
|
||||
int sig;
|
||||
void __user *fault_addr = NULL;
|
||||
|
||||
/*
|
||||
* Unimplemented operation exception. If we've got the full
|
||||
@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||
lose_fpu(1);
|
||||
|
||||
/* Run the emulator */
|
||||
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1);
|
||||
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
|
||||
&fault_addr);
|
||||
|
||||
/*
|
||||
* We can't allow the emulated instruction to leave any of
|
||||
@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||
own_fpu(1); /* Using the FPU again. */
|
||||
|
||||
/* If something went wrong, signal */
|
||||
if (sig)
|
||||
force_sig(sig, current);
|
||||
process_fpemu_return(sig, fault_addr);
|
||||
|
||||
return;
|
||||
} else if (fcr31 & FPU_CSR_INV_X)
|
||||
@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
|
||||
|
||||
if (!raw_cpu_has_fpu) {
|
||||
int sig;
|
||||
void __user *fault_addr = NULL;
|
||||
sig = fpu_emulator_cop1Handler(regs,
|
||||
¤t->thread.fpu, 0);
|
||||
if (sig)
|
||||
force_sig(sig, current);
|
||||
else
|
||||
¤t->thread.fpu,
|
||||
0, &fault_addr);
|
||||
if (!process_fpemu_return(sig, fault_addr))
|
||||
mt_ase_fp_affinity();
|
||||
}
|
||||
|
||||
|
@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp)
|
||||
|
||||
/* this of-course trashes what was there before... */
|
||||
v->pbuffer = vmalloc(P_SIZE);
|
||||
if (!v->pbuffer) {
|
||||
pr_warning("VPE loader: unable to allocate memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
v->plen = P_SIZE;
|
||||
v->load_addr = NULL;
|
||||
v->len = 0;
|
||||
@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp)
|
||||
if (ret < 0)
|
||||
v->shared_ptr = NULL;
|
||||
|
||||
// cleanup any temp buffers
|
||||
if (v->pbuffer)
|
||||
vfree(v->pbuffer);
|
||||
vfree(v->pbuffer);
|
||||
v->plen = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
|
||||
if (v == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
if (v->pbuffer == NULL) {
|
||||
printk(KERN_ERR "VPE loader: no buffer for program\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if ((count + v->len) > v->plen) {
|
||||
printk(KERN_WARNING
|
||||
"VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
|
||||
|
@ -161,16 +161,16 @@ FEXPORT(__bzero)
|
||||
|
||||
.Lfwd_fixup:
|
||||
PTR_L t0, TI_TASK($28)
|
||||
LONG_L t0, THREAD_BUADDR(t0)
|
||||
andi a2, 0x3f
|
||||
LONG_L t0, THREAD_BUADDR(t0)
|
||||
LONG_ADDU a2, t1
|
||||
jr ra
|
||||
LONG_SUBU a2, t0
|
||||
|
||||
.Lpartial_fixup:
|
||||
PTR_L t0, TI_TASK($28)
|
||||
LONG_L t0, THREAD_BUADDR(t0)
|
||||
andi a2, LONGMASK
|
||||
LONG_L t0, THREAD_BUADDR(t0)
|
||||
LONG_ADDU a2, t1
|
||||
jr ra
|
||||
LONG_SUBU a2, t0
|
||||
|
@ -29,9 +29,9 @@ unsigned long memsize, highmemsize;
|
||||
|
||||
#define parse_even_earlier(res, option, p) \
|
||||
do { \
|
||||
int ret; \
|
||||
if (strncmp(option, (char *)p, strlen(option)) == 0) \
|
||||
strict_strtol((char *)p + strlen(option"="), \
|
||||
10, &res); \
|
||||
ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \
|
||||
} while (0)
|
||||
|
||||
void __init prom_init_env(void)
|
||||
|
@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
|
||||
|
||||
#if __mips >= 4 && __mips != 32
|
||||
static int fpux_emu(struct pt_regs *,
|
||||
struct mips_fpu_struct *, mips_instruction);
|
||||
struct mips_fpu_struct *, mips_instruction, void *__user *);
|
||||
#endif
|
||||
|
||||
/* Further private data for which no space exists in mips_fpu_struct */
|
||||
@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp)
|
||||
* Two instructions if the instruction is in a branch delay slot.
|
||||
*/
|
||||
|
||||
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
void *__user *fault_addr)
|
||||
{
|
||||
mips_instruction ir;
|
||||
unsigned long emulpc, contpc;
|
||||
unsigned int cond;
|
||||
|
||||
if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
|
||||
if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGSEGV;
|
||||
}
|
||||
|
||||
/* XXX NEC Vr54xx bug workaround */
|
||||
if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
|
||||
@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
#endif
|
||||
return SIGILL;
|
||||
}
|
||||
if (get_user(ir, (mips_instruction __user *) emulpc)) {
|
||||
if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)emulpc;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(ir, (mips_instruction __user *) emulpc)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)emulpc;
|
||||
return SIGSEGV;
|
||||
}
|
||||
/* __compute_return_epc() will have updated cp0_epc */
|
||||
contpc = xcp->cp0_epc;
|
||||
/* In order not to confuse ptrace() et al, tweak context */
|
||||
@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
u64 val;
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(loads);
|
||||
if (get_user(val, va)) {
|
||||
|
||||
if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
DITOREG(val, MIPSInst_RT(ir));
|
||||
break;
|
||||
}
|
||||
@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(stores);
|
||||
DIFROMREG(val, MIPSInst_RT(ir));
|
||||
if (put_user(val, va)) {
|
||||
if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__put_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
u32 val;
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(loads);
|
||||
if (get_user(val, va)) {
|
||||
if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
SITOREG(val, MIPSInst_RT(ir));
|
||||
break;
|
||||
}
|
||||
@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(stores);
|
||||
SIFROMREG(val, MIPSInst_RT(ir));
|
||||
if (put_user(val, va)) {
|
||||
if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__put_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -440,10 +478,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
contpc = (xcp->cp0_epc +
|
||||
(MIPSInst_SIMM(ir) << 2));
|
||||
|
||||
if (get_user(ir,
|
||||
if (!access_ok(VERIFY_READ, xcp->cp0_epc,
|
||||
sizeof(mips_instruction))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(ir,
|
||||
(mips_instruction __user *) xcp->cp0_epc)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
return SIGBUS;
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGSEGV;
|
||||
}
|
||||
|
||||
switch (MIPSInst_OPCODE(ir)) {
|
||||
@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
|
||||
|
||||
#if __mips >= 4 && __mips != 32
|
||||
case cop1x_op:{
|
||||
int sig;
|
||||
|
||||
if ((sig = fpux_emu(xcp, ctx, ir)))
|
||||
int sig = fpux_emu(xcp, ctx, ir, fault_addr);
|
||||
if (sig)
|
||||
return sig;
|
||||
break;
|
||||
}
|
||||
@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
|
||||
DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
|
||||
|
||||
static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
mips_instruction ir)
|
||||
mips_instruction ir, void *__user *fault_addr)
|
||||
{
|
||||
unsigned rcsr = 0; /* resulting csr */
|
||||
|
||||
@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
xcp->regs[MIPSInst_FT(ir)]);
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(loads);
|
||||
if (get_user(val, va)) {
|
||||
if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
SITOREG(val, MIPSInst_FD(ir));
|
||||
break;
|
||||
|
||||
@ -638,9 +688,15 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
MIPS_FPU_EMU_INC_STATS(stores);
|
||||
|
||||
SIFROMREG(val, MIPSInst_FS(ir));
|
||||
if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (put_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
return SIGBUS;
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
xcp->regs[MIPSInst_FT(ir)]);
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(loads);
|
||||
if (get_user(val, va)) {
|
||||
if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
DITOREG(val, MIPSInst_FD(ir));
|
||||
break;
|
||||
|
||||
@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
|
||||
MIPS_FPU_EMU_INC_STATS(stores);
|
||||
DIFROMREG(val, MIPSInst_FS(ir));
|
||||
if (put_user(val, va)) {
|
||||
if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__put_user(val, va)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = va;
|
||||
return SIGSEGV;
|
||||
}
|
||||
break;
|
||||
|
||||
case madd_d_op:
|
||||
@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
}
|
||||
|
||||
int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
int has_fpu)
|
||||
int has_fpu, void *__user *fault_addr)
|
||||
{
|
||||
unsigned long oldepc, prevepc;
|
||||
mips_instruction insn;
|
||||
@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
do {
|
||||
prevepc = xcp->cp0_epc;
|
||||
|
||||
if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
|
||||
if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGBUS;
|
||||
}
|
||||
if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
|
||||
MIPS_FPU_EMU_INC_STATS(errors);
|
||||
*fault_addr = (mips_instruction __user *)xcp->cp0_epc;
|
||||
return SIGSEGV;
|
||||
}
|
||||
if (insn == 0)
|
||||
xcp->cp0_epc += 4; /* skip nops */
|
||||
else {
|
||||
@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
*/
|
||||
/* convert to ieee library modes */
|
||||
ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
|
||||
sig = cop1Emulate(xcp, ctx);
|
||||
sig = cop1Emulate(xcp, ctx, fault_addr);
|
||||
/* revert to mips rounding mode */
|
||||
ieee754_csr.rm = mips_rm[ieee754_csr.rm];
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask)
|
||||
return plat_dma_supported(dev, mask);
|
||||
}
|
||||
|
||||
void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(direction == DMA_NONE);
|
||||
@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
__dma_sync((unsigned long)vaddr, size, direction);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dma_cache_sync);
|
||||
|
||||
static struct dma_map_ops mips_default_dma_map_ops = {
|
||||
.alloc_coherent = mips_dma_alloc_coherent,
|
||||
.free_coherent = mips_dma_free_coherent,
|
||||
|
@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
|
||||
*/
|
||||
static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
|
||||
{
|
||||
unsigned int config2 = read_c0_config2();
|
||||
unsigned int tmp;
|
||||
|
||||
/* Check the bypass bit (L2B) */
|
||||
switch (c->cputype) {
|
||||
case CPU_34K:
|
||||
@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
|
||||
c->scache.linesz = 2 << tmp;
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int __init mips_sc_probe(void)
|
||||
|
@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys)
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" .set push \n"
|
||||
" .set noreorder \n"
|
||||
" .set nomacro \n"
|
||||
" ld %0, %1 \n"
|
||||
" .set pop \n"
|
||||
" lbu %0, (%0) \n"
|
||||
" .set mips0 \n"
|
||||
: "=r" (res)
|
||||
: "m" (vaddr));
|
||||
: "R" (vaddr));
|
||||
|
||||
write_c0_status(sr);
|
||||
ssnop_4();
|
||||
@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" .set push \n"
|
||||
" .set noreorder \n"
|
||||
" .set nomacro \n"
|
||||
" ld %0, %1 \n"
|
||||
" .set pop \n"
|
||||
" sb %2, (%0) \n"
|
||||
" .set mips0 \n"
|
||||
: "=&r" (tmp)
|
||||
: "m" (vaddr), "r" (c));
|
||||
: "R" (vaddr), "r" (c));
|
||||
|
||||
write_c0_status(sr);
|
||||
ssnop_4();
|
||||
|
@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
|
||||
enum swarm_rtc_type {
|
||||
RTC_NONE,
|
||||
RTC_XICOR,
|
||||
RTC_M4LT81
|
||||
RTC_M41T81,
|
||||
};
|
||||
|
||||
enum swarm_rtc_type swarm_rtc_type;
|
||||
@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts)
|
||||
sec = xicor_get_time();
|
||||
break;
|
||||
|
||||
case RTC_M4LT81:
|
||||
case RTC_M41T81:
|
||||
sec = m41t81_get_time();
|
||||
break;
|
||||
|
||||
@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec)
|
||||
case RTC_XICOR:
|
||||
return xicor_set_time(sec);
|
||||
|
||||
case RTC_M4LT81:
|
||||
case RTC_M41T81:
|
||||
return m41t81_set_time(sec);
|
||||
|
||||
case RTC_NONE:
|
||||
@ -141,7 +141,7 @@ void __init plat_mem_setup(void)
|
||||
if (xicor_probe())
|
||||
swarm_rtc_type = RTC_XICOR;
|
||||
if (m41t81_probe())
|
||||
swarm_rtc_type = RTC_M4LT81;
|
||||
swarm_rtc_type = RTC_M41T81;
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
screen_info = (struct screen_info) {
|
||||
|
@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
|
||||
unsigned long long ll;
|
||||
unsigned l[2];
|
||||
} tsc64, result;
|
||||
unsigned long tsc, tmp;
|
||||
unsigned long tmp;
|
||||
unsigned product[3]; /* 96-bit intermediate value */
|
||||
|
||||
/* cnt32_to_63() is not safe with preemption */
|
||||
preempt_disable();
|
||||
|
||||
/* read the TSC value
|
||||
*/
|
||||
tsc = get_cycles();
|
||||
|
||||
/* expand to 64-bits.
|
||||
/* expand the tsc to 64-bits.
|
||||
* - sched_clock() must be called once a minute or better or the
|
||||
* following will go horribly wrong - see cnt32_to_63()
|
||||
*/
|
||||
tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
|
||||
tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
|
||||
|
||||
preempt_enable();
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||
struct pt_regs;
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
|
||||
void do_signal(struct pt_regs *regs);
|
||||
#endif
|
||||
|
@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The assembly shim for this function arranges to ignore the return value. */
|
||||
long compat_sys_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct compat_rt_sigframe __user *frame =
|
||||
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
|
||||
sigset_t set;
|
||||
long r0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
|
||||
goto badframe;
|
||||
|
||||
return r0;
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
|
@ -1342,8 +1342,8 @@ handle_syscall:
|
||||
lw r20, r20
|
||||
|
||||
/* Jump to syscall handler. */
|
||||
jalr r20; .Lhandle_syscall_link:
|
||||
FEEDBACK_REENTER(handle_syscall)
|
||||
jalr r20
|
||||
.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
|
||||
|
||||
/*
|
||||
* Write our r0 onto the stack so it gets restored instead
|
||||
@ -1352,6 +1352,9 @@ handle_syscall:
|
||||
PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
|
||||
sw r29, r0
|
||||
|
||||
.Lsyscall_sigreturn_skip:
|
||||
FEEDBACK_REENTER(handle_syscall)
|
||||
|
||||
/* Do syscall trace again, if requested. */
|
||||
lw r30, r31
|
||||
andi r30, r30, _TIF_SYSCALL_TRACE
|
||||
@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
|
||||
}; \
|
||||
STD_ENDPROC(_##x)
|
||||
|
||||
/*
|
||||
* Special-case sigreturn to not write r0 to the stack on return.
|
||||
* This is technically more efficient, but it also avoids difficulties
|
||||
* in the 64-bit OS when handling 32-bit compat code, since we must not
|
||||
* sign-extend r0 for the sigreturn return-value case.
|
||||
*/
|
||||
#define PTREGS_SYSCALL_SIGRETURN(x, reg) \
|
||||
STD_ENTRY(_##x); \
|
||||
addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
|
||||
{ \
|
||||
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
|
||||
j x \
|
||||
}; \
|
||||
STD_ENDPROC(_##x)
|
||||
|
||||
PTREGS_SYSCALL(sys_execve, r3)
|
||||
PTREGS_SYSCALL(sys_sigaltstack, r2)
|
||||
PTREGS_SYSCALL(sys_rt_sigreturn, r0)
|
||||
PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
|
||||
PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
|
||||
|
||||
/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
|
||||
|
@ -211,6 +211,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
||||
childregs->regs[0] = 0; /* return value is zero */
|
||||
childregs->sp = sp; /* override with new user stack pointer */
|
||||
|
||||
/*
|
||||
* If CLONE_SETTLS is set, set "tp" in the new task to "r4",
|
||||
* which is passed in as arg #5 to sys_clone().
|
||||
*/
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
childregs->tp = regs->regs[4];
|
||||
|
||||
/*
|
||||
* Copy the callee-saved registers from the passed pt_regs struct
|
||||
* into the context-switch callee-saved registers area.
|
||||
@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
|
||||
return __switch_to(prev, next, next_current_ksp0(next));
|
||||
}
|
||||
|
||||
/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
|
||||
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
||||
void __user *, parent_tidptr, void __user *, child_tidptr,
|
||||
struct pt_regs *, regs)
|
||||
|
@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
|
||||
*/
|
||||
|
||||
int restore_sigcontext(struct pt_regs *regs,
|
||||
struct sigcontext __user *sc, long *pr0)
|
||||
struct sigcontext __user *sc)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
|
||||
|
||||
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||
|
||||
err |= __get_user(*pr0, &sc->gregs[0]);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sigreturn() returns long since it restores r0 in the interrupted code. */
|
||||
/* The assembly shim for this function arranges to ignore the return value. */
|
||||
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame =
|
||||
(struct rt_sigframe __user *)(regs->sp);
|
||||
sigset_t set;
|
||||
long r0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return r0;
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
|
@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
|
||||
if (heap > 0x3fffffffffffUL)
|
||||
error("Destination address too large");
|
||||
#else
|
||||
if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
|
||||
if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
|
||||
error("Destination address too large");
|
||||
#endif
|
||||
#ifndef CONFIG_RELOCATABLE
|
||||
|
@ -72,6 +72,9 @@ struct e820map {
|
||||
#define BIOS_BEGIN 0x000a0000
|
||||
#define BIOS_END 0x00100000
|
||||
|
||||
#define BIOS_ROM_BASE 0xffe00000
|
||||
#define BIOS_ROM_END 0xffffffff
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* see comment in arch/x86/kernel/e820.c */
|
||||
extern struct e820map e820;
|
||||
|
@ -79,7 +79,7 @@
|
||||
#define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
|
||||
#define KVM_MIN_FREE_MMU_PAGES 5
|
||||
#define KVM_REFILL_PAGES 25
|
||||
#define KVM_MAX_CPUID_ENTRIES 40
|
||||
#define KVM_MAX_CPUID_ENTRIES 80
|
||||
#define KVM_NR_FIXED_MTRR_REGION 88
|
||||
#define KVM_NR_VAR_MTRR 8
|
||||
|
||||
|
@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
|
||||
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
|
||||
obj-y += tsc.o io_delay.o rtc.o
|
||||
obj-y += pci-iommu_table.o
|
||||
obj-y += resource.o
|
||||
|
||||
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
|
||||
obj-y += process.o
|
||||
|
@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void)
|
||||
|
||||
setup_apic_nmi_watchdog(NULL);
|
||||
apic_pm_activate();
|
||||
|
||||
/*
|
||||
* Now that local APIC setup is completed for BP, configure the fault
|
||||
* handling for interrupt remapping.
|
||||
*/
|
||||
if (!smp_processor_id() && intr_remapping_enabled)
|
||||
enable_drhd_fault_handling();
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_X2APIC
|
||||
|
@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data)
|
||||
{
|
||||
struct irq_cfg *cfg = data->chip_data;
|
||||
int i, do_unmask_irq = 0, irq = data->irq;
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
unsigned long v;
|
||||
|
||||
irq_complete_move(cfg);
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
/* If we are moving the irq we need to mask it */
|
||||
if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
|
||||
if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
|
||||
do_unmask_irq = 1;
|
||||
mask_ioapic(cfg);
|
||||
}
|
||||
@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
||||
msg.data |= MSI_DATA_VECTOR(cfg->vector);
|
||||
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
|
||||
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
|
||||
msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
|
||||
|
||||
dmar_msi_write(irq, &msg);
|
||||
|
||||
|
@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void)
|
||||
/* need to update phys_pkg_id */
|
||||
apic->phys_pkg_id = apicid_phys_pkg_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that apic routing model is selected, configure the
|
||||
* fault handling for intr remapping.
|
||||
*/
|
||||
if (intr_remapping_enabled)
|
||||
enable_drhd_fault_handling();
|
||||
}
|
||||
|
||||
/* Same for both flat and physical. */
|
||||
|
@ -60,16 +60,18 @@
|
||||
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
|
||||
#endif
|
||||
|
||||
/* Number of possible pages in the lowmem region */
|
||||
LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
|
||||
|
||||
/* Enough space to fit pagetables for the low memory linear map */
|
||||
MAPPING_BEYOND_END = \
|
||||
PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
|
||||
MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
|
||||
|
||||
/*
|
||||
* Worst-case size of the kernel mapping we need to make:
|
||||
* the worst-case size of the kernel itself, plus the extra we need
|
||||
* to map for the linear map.
|
||||
* a relocatable kernel can live anywhere in lowmem, so we need to be able
|
||||
* to map all of lowmem.
|
||||
*/
|
||||
KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
|
||||
KERNEL_PAGES = LOWMEM_PAGES
|
||||
|
||||
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
|
||||
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
|
||||
@ -620,13 +622,13 @@ ENTRY(initial_code)
|
||||
__PAGE_ALIGNED_BSS
|
||||
.align PAGE_SIZE_asm
|
||||
#ifdef CONFIG_X86_PAE
|
||||
initial_pg_pmd:
|
||||
ENTRY(initial_pg_pmd)
|
||||
.fill 1024*KPMDS,4,0
|
||||
#else
|
||||
ENTRY(initial_page_table)
|
||||
.fill 1024,4,0
|
||||
#endif
|
||||
initial_pg_fixmap:
|
||||
ENTRY(initial_pg_fixmap)
|
||||
.fill 1024,4,0
|
||||
ENTRY(empty_zero_page)
|
||||
.fill 4096,1,0
|
||||
|
@ -27,6 +27,9 @@
|
||||
#define HPET_DEV_FSB_CAP 0x1000
|
||||
#define HPET_DEV_PERI_CAP 0x2000
|
||||
|
||||
#define HPET_MIN_CYCLES 128
|
||||
#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
|
||||
|
||||
#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
|
||||
|
||||
/*
|
||||
@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void)
|
||||
/* Calculate the min / max delta */
|
||||
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
|
||||
&hpet_clockevent);
|
||||
/* 5 usec minimum reprogramming delta. */
|
||||
hpet_clockevent.min_delta_ns = 5000;
|
||||
/* Setup minimum reprogramming delta. */
|
||||
hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
|
||||
&hpet_clockevent);
|
||||
|
||||
/*
|
||||
* Start hpet with the boot cpu mask and make it
|
||||
@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta,
|
||||
* the wraparound into account) nor a simple count down event
|
||||
* mode. Further the write to the comparator register is
|
||||
* delayed internally up to two HPET clock cycles in certain
|
||||
* chipsets (ATI, ICH9,10). We worked around that by reading
|
||||
* back the compare register, but that required another
|
||||
* workaround for ICH9,10 chips where the first readout after
|
||||
* write can return the old stale value. We already have a
|
||||
* minimum delta of 5us enforced, but a NMI or SMI hitting
|
||||
* chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
|
||||
* longer delays. We worked around that by reading back the
|
||||
* compare register, but that required another workaround for
|
||||
* ICH9,10 chips where the first readout after write can
|
||||
* return the old stale value. We already had a minimum
|
||||
* programming delta of 5us enforced, but a NMI or SMI hitting
|
||||
* between the counter readout and the comparator write can
|
||||
* move us behind that point easily. Now instead of reading
|
||||
* the compare register back several times, we make the ETIME
|
||||
* decision based on the following: Return ETIME if the
|
||||
* counter value after the write is less than 8 HPET cycles
|
||||
* counter value after the write is less than HPET_MIN_CYCLES
|
||||
* away from the event or if the counter is already ahead of
|
||||
* the event.
|
||||
* the event. The minimum programming delta for the generic
|
||||
* clockevents code is set to 1.5 * HPET_MIN_CYCLES.
|
||||
*/
|
||||
res = (s32)(cnt - hpet_readl(HPET_COUNTER));
|
||||
|
||||
return res < 8 ? -ETIME : 0;
|
||||
return res < HPET_MIN_CYCLES ? -ETIME : 0;
|
||||
}
|
||||
|
||||
static void hpet_legacy_set_mode(enum clock_event_mode mode,
|
||||
|
48
arch/x86/kernel/resource.c
Normal file
48
arch/x86/kernel/resource.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
static void resource_clip(struct resource *res, resource_size_t start,
|
||||
resource_size_t end)
|
||||
{
|
||||
resource_size_t low = 0, high = 0;
|
||||
|
||||
if (res->end < start || res->start > end)
|
||||
return; /* no conflict */
|
||||
|
||||
if (res->start < start)
|
||||
low = start - res->start;
|
||||
|
||||
if (res->end > end)
|
||||
high = res->end - end;
|
||||
|
||||
/* Keep the area above or below the conflict, whichever is larger */
|
||||
if (low > high)
|
||||
res->end = start - 1;
|
||||
else
|
||||
res->start = end + 1;
|
||||
}
|
||||
|
||||
static void remove_e820_regions(struct resource *avail)
|
||||
{
|
||||
int i;
|
||||
struct e820entry *entry;
|
||||
|
||||
for (i = 0; i < e820.nr_map; i++) {
|
||||
entry = &e820.map[i];
|
||||
|
||||
resource_clip(avail, entry->addr,
|
||||
entry->addr + entry->size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void arch_remove_reservations(struct resource *avail)
|
||||
{
|
||||
/* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
|
||||
if (avail->flags & IORESOURCE_MEM) {
|
||||
if (avail->start < BIOS_END)
|
||||
avail->start = BIOS_END;
|
||||
resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
|
||||
|
||||
remove_e820_regions(avail);
|
||||
}
|
||||
}
|
@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
x86_init.oem.arch_setup();
|
||||
|
||||
resource_alloc_from_bottom = 0;
|
||||
iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
|
||||
setup_memory_map();
|
||||
parse_setup_data();
|
||||
|
@ -394,7 +394,8 @@ static void __init setup_xstate_init(void)
|
||||
* Setup init_xstate_buf to represent the init state of
|
||||
* all the features managed by the xsave
|
||||
*/
|
||||
init_xstate_buf = alloc_bootmem(xstate_size);
|
||||
init_xstate_buf = alloc_bootmem_align(xstate_size,
|
||||
__alignof__(struct xsave_struct));
|
||||
init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
|
||||
|
||||
clts();
|
||||
|
@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
|
||||
static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
|
||||
{
|
||||
switch (func) {
|
||||
case 0x00000001:
|
||||
/* Mask out xsave bit as long as it is not supported by SVM */
|
||||
entry->ecx &= ~(bit(X86_FEATURE_XSAVE));
|
||||
break;
|
||||
case 0x80000001:
|
||||
if (nested)
|
||||
entry->ecx |= (1 << 2); /* Set SVM bit */
|
||||
|
@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void)
|
||||
return PT_PDPE_LEVEL;
|
||||
}
|
||||
|
||||
static inline u32 bit(int bitno)
|
||||
{
|
||||
return 1 << (bitno & 31);
|
||||
}
|
||||
|
||||
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||
|
||||
u64 __read_mostly host_xcr0;
|
||||
|
||||
static inline u32 bit(int bitno)
|
||||
{
|
||||
return 1 << (bitno & 31);
|
||||
}
|
||||
|
||||
static void kvm_on_user_return(struct user_return_notifier *urn)
|
||||
{
|
||||
unsigned slot;
|
||||
@ -4569,9 +4564,11 @@ static void kvm_timer_init(void)
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
struct cpufreq_policy policy;
|
||||
memset(&policy, 0, sizeof(policy));
|
||||
cpufreq_get_policy(&policy, get_cpu());
|
||||
cpu = get_cpu();
|
||||
cpufreq_get_policy(&policy, cpu);
|
||||
if (policy.cpuinfo.max_freq)
|
||||
max_tsc_khz = policy.cpuinfo.max_freq;
|
||||
put_cpu();
|
||||
#endif
|
||||
cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
|
||||
|
||||
mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
|
||||
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
|
||||
if (sregs->cr4 & X86_CR4_OSXSAVE)
|
||||
update_cpuid(vcpu);
|
||||
if (!is_long_mode(vcpu) && is_pae(vcpu)) {
|
||||
load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
|
||||
mmu_reset_needed = 1;
|
||||
|
@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
|
||||
return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
|
||||
}
|
||||
|
||||
static inline u32 bit(int bitno)
|
||||
{
|
||||
return 1 << (bitno & 31);
|
||||
}
|
||||
|
||||
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
|
||||
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
|
||||
int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
|
||||
|
@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3)
|
||||
{
|
||||
lguest_data.pgdir = cr3;
|
||||
lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
|
||||
cr3_changed = true;
|
||||
|
||||
/* These two page tables are simple, linear, and used during boot */
|
||||
if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
|
||||
cr3_changed = true;
|
||||
}
|
||||
|
||||
static unsigned long lguest_read_cr3(void)
|
||||
@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
|
||||
* to forget all of them. Fortunately, this is very rare.
|
||||
*
|
||||
* ... except in early boot when the kernel sets up the initial pagetables,
|
||||
* which makes booting astonishingly slow: 1.83 seconds! So we don't even tell
|
||||
* the Host anything changed until we've done the first page table switch,
|
||||
* which brings boot back to 0.25 seconds.
|
||||
* which makes booting astonishingly slow: 48 seconds! So we don't even tell
|
||||
* the Host anything changed until we've done the first real page table switch,
|
||||
* which brings boot back to 4.3 seconds.
|
||||
*/
|
||||
static void lguest_set_pte(pte_t *ptep, pte_t pteval)
|
||||
{
|
||||
@ -1002,7 +1005,7 @@ static void lguest_time_init(void)
|
||||
clockevents_register_device(&lguest_clockevent);
|
||||
|
||||
/* Finally, we unblock the timer interrupt. */
|
||||
enable_lguest_irq(0);
|
||||
clear_bit(0, lguest_data.blocked_interrupts);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1349,9 +1352,6 @@ __init void lguest_init(void)
|
||||
*/
|
||||
switch_to_new_gdt(0);
|
||||
|
||||
/* We actually boot with all memory mapped, but let's say 128MB. */
|
||||
max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* The Host<->Guest Switcher lives at the top of our address space, and
|
||||
* the Host told us how big it is when we made LGUEST_INIT hypercall:
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
/*G:020
|
||||
* Our story starts with the kernel booting into startup_32 in
|
||||
@ -37,9 +38,113 @@ ENTRY(lguest_entry)
|
||||
/* Set up the initial stack so we can run C code. */
|
||||
movl $(init_thread_union+THREAD_SIZE),%esp
|
||||
|
||||
call init_pagetables
|
||||
|
||||
/* Jumps are relative: we're running __PAGE_OFFSET too low. */
|
||||
jmp lguest_init+__PAGE_OFFSET
|
||||
|
||||
/*
|
||||
* Initialize page tables. This creates a PDE and a set of page
|
||||
* tables, which are located immediately beyond __brk_base. The variable
|
||||
* _brk_end is set up to point to the first "safe" location.
|
||||
* Mappings are created both at virtual address 0 (identity mapping)
|
||||
* and PAGE_OFFSET for up to _end.
|
||||
*
|
||||
* FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they
|
||||
* don't have a stack at this point, so we can't just use call and ret.
|
||||
*/
|
||||
init_pagetables:
|
||||
#if PTRS_PER_PMD > 1
|
||||
#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
|
||||
#else
|
||||
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
|
||||
#endif
|
||||
#define pa(X) ((X) - __PAGE_OFFSET)
|
||||
|
||||
/* Enough space to fit pagetables for the low memory linear map */
|
||||
MAPPING_BEYOND_END = \
|
||||
PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
|
||||
#ifdef CONFIG_X86_PAE
|
||||
|
||||
/*
|
||||
* In PAE mode initial_page_table is statically defined to contain
|
||||
* enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
|
||||
* entries). The identity mapping is handled by pointing two PGD entries
|
||||
* to the first kernel PMD.
|
||||
*
|
||||
* Note the upper half of each PMD or PTE are always zero at this stage.
|
||||
*/
|
||||
|
||||
#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
|
||||
|
||||
xorl %ebx,%ebx /* %ebx is kept at zero */
|
||||
|
||||
movl $pa(__brk_base), %edi
|
||||
movl $pa(initial_pg_pmd), %edx
|
||||
movl $PTE_IDENT_ATTR, %eax
|
||||
10:
|
||||
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */
|
||||
movl %ecx,(%edx) /* Store PMD entry */
|
||||
/* Upper half already zero */
|
||||
addl $8,%edx
|
||||
movl $512,%ecx
|
||||
11:
|
||||
stosl
|
||||
xchgl %eax,%ebx
|
||||
stosl
|
||||
xchgl %eax,%ebx
|
||||
addl $0x1000,%eax
|
||||
loop 11b
|
||||
|
||||
/*
|
||||
* End condition: we must map up to the end + MAPPING_BEYOND_END.
|
||||
*/
|
||||
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
|
||||
cmpl %ebp,%eax
|
||||
jb 10b
|
||||
1:
|
||||
addl $__PAGE_OFFSET, %edi
|
||||
movl %edi, pa(_brk_end)
|
||||
shrl $12, %eax
|
||||
movl %eax, pa(max_pfn_mapped)
|
||||
|
||||
/* Do early initialization of the fixmap area */
|
||||
movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
|
||||
movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
|
||||
#else /* Not PAE */
|
||||
|
||||
page_pde_offset = (__PAGE_OFFSET >> 20);
|
||||
|
||||
movl $pa(__brk_base), %edi
|
||||
movl $pa(initial_page_table), %edx
|
||||
movl $PTE_IDENT_ATTR, %eax
|
||||
10:
|
||||
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
|
||||
movl %ecx,(%edx) /* Store identity PDE entry */
|
||||
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
|
||||
addl $4,%edx
|
||||
movl $1024, %ecx
|
||||
11:
|
||||
stosl
|
||||
addl $0x1000,%eax
|
||||
loop 11b
|
||||
/*
|
||||
* End condition: we must map up to the end + MAPPING_BEYOND_END.
|
||||
*/
|
||||
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
|
||||
cmpl %ebp,%eax
|
||||
jb 10b
|
||||
addl $__PAGE_OFFSET, %edi
|
||||
movl %edi, pa(_brk_end)
|
||||
shrl $12, %eax
|
||||
movl %eax, pa(max_pfn_mapped)
|
||||
|
||||
/* Do early initialization of the fixmap area */
|
||||
movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
|
||||
movl %eax,pa(initial_page_table+0xffc)
|
||||
#endif
|
||||
ret
|
||||
|
||||
/*G:055
|
||||
* We create a macro which puts the assembler code between lgstart_ and lgend_
|
||||
* markers. These templates are put in the .text section: they can't be
|
||||
|
@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
|
||||
resource_size_t size, resource_size_t align)
|
||||
{
|
||||
struct pci_dev *dev = data;
|
||||
resource_size_t start = round_down(res->end - size + 1, align);
|
||||
resource_size_t start = res->start;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
|
||||
/*
|
||||
* If we're avoiding ISA aliases, the largest contiguous I/O
|
||||
* port space is 256 bytes. Clearing bits 9 and 10 preserves
|
||||
* all 256-byte and smaller alignments, so the result will
|
||||
* still be correctly aligned.
|
||||
*/
|
||||
if (!skip_isa_ioresource_align(dev))
|
||||
start &= ~0x300;
|
||||
} else if (res->flags & IORESOURCE_MEM) {
|
||||
if (start < BIOS_END)
|
||||
start = res->end; /* fail; no space */
|
||||
if (skip_isa_ioresource_align(dev))
|
||||
return start;
|
||||
if (start & 0x300)
|
||||
start = (start + 0x3ff) & ~0x3ff;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
|
||||
|
||||
export CPPFLAGS_vdso.lds += -P -C
|
||||
|
||||
VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \
|
||||
VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
|
||||
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
|
||||
|
||||
$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
|
||||
@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter
|
||||
vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
|
||||
|
||||
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
|
||||
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1
|
||||
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
|
||||
|
||||
# This makes sure the $(obj) subdirectory exists even though vdso32/
|
||||
# is not a kbuild sub-make subdirectory.
|
||||
|
@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
unsigned long uaddr = (unsigned long)iov[i].iov_base;
|
||||
|
||||
if (!iov[i].iov_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (uaddr & queue_dma_alignment(q)) {
|
||||
unaligned = 1;
|
||||
break;
|
||||
}
|
||||
if (!iov[i].iov_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unaligned || (q->dma_pad_mask & len) || map_data)
|
||||
|
@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
|
||||
return 0;
|
||||
|
||||
fbio = bio;
|
||||
cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
|
||||
cluster = blk_queue_cluster(q);
|
||||
seg_size = 0;
|
||||
nr_phys_segs = 0;
|
||||
for_each_bio(bio) {
|
||||
@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments);
|
||||
static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
|
||||
struct bio *nxt)
|
||||
{
|
||||
if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
|
||||
if (!blk_queue_cluster(q))
|
||||
return 0;
|
||||
|
||||
if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
|
||||
@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
|
||||
int nsegs, cluster;
|
||||
|
||||
nsegs = 0;
|
||||
cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
|
||||
cluster = blk_queue_cluster(q);
|
||||
|
||||
/*
|
||||
* for each bio in rq
|
||||
|
@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim)
|
||||
lim->alignment_offset = 0;
|
||||
lim->io_opt = 0;
|
||||
lim->misaligned = 0;
|
||||
lim->no_cluster = 0;
|
||||
lim->cluster = 1;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_set_default_limits);
|
||||
|
||||
@ -229,8 +229,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
|
||||
EXPORT_SYMBOL(blk_queue_bounce_limit);
|
||||
|
||||
/**
|
||||
* blk_queue_max_hw_sectors - set max sectors for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request
|
||||
* @limits: the queue limits
|
||||
* @max_hw_sectors: max hardware sectors in the usual 512b unit
|
||||
*
|
||||
* Description:
|
||||
@ -244,7 +244,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
|
||||
* per-device basis in /sys/block/<device>/queue/max_sectors_kb.
|
||||
* The soft limit can not exceed max_hw_sectors.
|
||||
**/
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
|
||||
void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors)
|
||||
{
|
||||
if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
|
||||
max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
|
||||
@ -252,9 +252,23 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto
|
||||
__func__, max_hw_sectors);
|
||||
}
|
||||
|
||||
q->limits.max_hw_sectors = max_hw_sectors;
|
||||
q->limits.max_sectors = min_t(unsigned int, max_hw_sectors,
|
||||
BLK_DEF_MAX_SECTORS);
|
||||
limits->max_hw_sectors = max_hw_sectors;
|
||||
limits->max_sectors = min_t(unsigned int, max_hw_sectors,
|
||||
BLK_DEF_MAX_SECTORS);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_limits_max_hw_sectors);
|
||||
|
||||
/**
|
||||
* blk_queue_max_hw_sectors - set max sectors for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* @max_hw_sectors: max hardware sectors in the usual 512b unit
|
||||
*
|
||||
* Description:
|
||||
* See description for blk_limits_max_hw_sectors().
|
||||
**/
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
|
||||
{
|
||||
blk_limits_max_hw_sectors(&q->limits, max_hw_sectors);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
|
||||
|
||||
@ -464,15 +478,6 @@ EXPORT_SYMBOL(blk_queue_io_opt);
|
||||
void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
|
||||
{
|
||||
blk_stack_limits(&t->limits, &b->limits, 0);
|
||||
|
||||
if (!t->queue_lock)
|
||||
WARN_ON_ONCE(1);
|
||||
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(t->queue_lock, flags);
|
||||
queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
|
||||
spin_unlock_irqrestore(t->queue_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_stack_limits);
|
||||
|
||||
@ -545,7 +550,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
|
||||
t->io_min = max(t->io_min, b->io_min);
|
||||
t->io_opt = lcm(t->io_opt, b->io_opt);
|
||||
|
||||
t->no_cluster |= b->no_cluster;
|
||||
t->cluster &= b->cluster;
|
||||
t->discard_zeroes_data &= b->discard_zeroes_data;
|
||||
|
||||
/* Physical block size a multiple of the logical block size? */
|
||||
@ -641,7 +646,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
||||
sector_t offset)
|
||||
{
|
||||
struct request_queue *t = disk->queue;
|
||||
struct request_queue *b = bdev_get_queue(bdev);
|
||||
|
||||
if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
|
||||
char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
|
||||
@ -652,17 +656,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
||||
printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
|
||||
top, bottom);
|
||||
}
|
||||
|
||||
if (!t->queue_lock)
|
||||
WARN_ON_ONCE(1);
|
||||
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(t->queue_lock, flags);
|
||||
if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
|
||||
queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
|
||||
spin_unlock_irqrestore(t->queue_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(disk_stack_limits);
|
||||
|
||||
|
@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *
|
||||
|
||||
static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
|
||||
{
|
||||
if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
|
||||
if (blk_queue_cluster(q))
|
||||
return queue_var_show(queue_max_segment_size(q), (page));
|
||||
|
||||
return queue_var_show(PAGE_CACHE_SIZE, (page));
|
||||
|
@ -355,6 +355,12 @@ throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
|
||||
tg->slice_end[rw], jiffies);
|
||||
}
|
||||
|
||||
static inline void throtl_set_slice_end(struct throtl_data *td,
|
||||
struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
|
||||
{
|
||||
tg->slice_end[rw] = roundup(jiffy_end, throtl_slice);
|
||||
}
|
||||
|
||||
static inline void throtl_extend_slice(struct throtl_data *td,
|
||||
struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
|
||||
{
|
||||
@ -391,6 +397,16 @@ throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
|
||||
if (throtl_slice_used(td, tg, rw))
|
||||
return;
|
||||
|
||||
/*
|
||||
* A bio has been dispatched. Also adjust slice_end. It might happen
|
||||
* that initially cgroup limit was very low resulting in high
|
||||
* slice_end, but later limit was bumped up and bio was dispached
|
||||
* sooner, then we need to reduce slice_end. A high bogus slice_end
|
||||
* is bad because it does not allow new slice to start.
|
||||
*/
|
||||
|
||||
throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice);
|
||||
|
||||
time_elapsed = jiffies - tg->slice_start[rw];
|
||||
|
||||
nr_slices = time_elapsed / throtl_slice;
|
||||
@ -709,26 +725,21 @@ static void throtl_process_limit_change(struct throtl_data *td)
|
||||
struct throtl_grp *tg;
|
||||
struct hlist_node *pos, *n;
|
||||
|
||||
/*
|
||||
* Make sure atomic_inc() effects from
|
||||
* throtl_update_blkio_group_read_bps(), group of functions are
|
||||
* visible.
|
||||
* Is this required or smp_mb__after_atomic_inc() was suffcient
|
||||
* after the atomic_inc().
|
||||
*/
|
||||
smp_rmb();
|
||||
if (!atomic_read(&td->limits_changed))
|
||||
return;
|
||||
|
||||
throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed));
|
||||
|
||||
hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
|
||||
/*
|
||||
* Do I need an smp_rmb() here to make sure tg->limits_changed
|
||||
* update is visible. I am relying on smp_rmb() at the
|
||||
* beginning of function and not putting a new one here.
|
||||
*/
|
||||
/*
|
||||
* Make sure updates from throtl_update_blkio_group_read_bps() group
|
||||
* of functions to tg->limits_changed are visible. We do not
|
||||
* want update td->limits_changed to be visible but update to
|
||||
* tg->limits_changed not being visible yet on this cpu. Hence
|
||||
* the read barrier.
|
||||
*/
|
||||
smp_rmb();
|
||||
|
||||
hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
|
||||
if (throtl_tg_on_rr(tg) && tg->limits_changed) {
|
||||
throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu"
|
||||
" riops=%u wiops=%u", tg->bps[READ],
|
||||
|
@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk)
|
||||
InquiryData_struct *inq_buff = NULL;
|
||||
|
||||
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
|
||||
if (!h->drv[logvol])
|
||||
continue;
|
||||
if (memcmp(h->drv[logvol]->LunID, drv->LunID,
|
||||
sizeof(drv->LunID)) == 0) {
|
||||
FOUND = 1;
|
||||
|
@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev)
|
||||
}
|
||||
|
||||
shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header);
|
||||
rv = drbd_recv(mdev, &header->h80.payload, shs);
|
||||
if (unlikely(rv != shs)) {
|
||||
dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
|
||||
dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (shs) {
|
||||
rv = drbd_recv(mdev, &header->h80.payload, shs);
|
||||
if (unlikely(rv != shs)) {
|
||||
dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs);
|
||||
|
||||
if (unlikely(!rv)) {
|
||||
|
@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
|
||||
}
|
||||
|
||||
/* completion of master bio is outside of spinlock.
|
||||
* If you need it irqsave, do it your self! */
|
||||
* If you need it irqsave, do it your self!
|
||||
* Which means: don't use from bio endio callback. */
|
||||
static inline int req_mod(struct drbd_request *req,
|
||||
enum drbd_req_event what)
|
||||
{
|
||||
|
@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error)
|
||||
*/
|
||||
void drbd_endio_pri(struct bio *bio, int error)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct drbd_request *req = bio->bi_private;
|
||||
struct drbd_conf *mdev = req->mdev;
|
||||
struct bio_and_error m;
|
||||
enum drbd_req_event what;
|
||||
int uptodate = bio_flagged(bio, BIO_UPTODATE);
|
||||
|
||||
@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error)
|
||||
bio_put(req->private_bio);
|
||||
req->private_bio = ERR_PTR(error);
|
||||
|
||||
req_mod(req, what);
|
||||
/* not req_mod(), we need irqsave here! */
|
||||
spin_lock_irqsave(&mdev->req_lock, flags);
|
||||
__req_mod(req, what, &m);
|
||||
spin_unlock_irqrestore(&mdev->req_lock, flags);
|
||||
|
||||
if (m.bio)
|
||||
complete_master_bio(mdev, &m);
|
||||
}
|
||||
|
||||
int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
|
||||
|
@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
|
||||
} while (delay);
|
||||
}
|
||||
|
||||
static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
|
||||
{
|
||||
if (delta > p->max_match_value)
|
||||
dev_warn(&p->pdev->dev, "delta out of range\n");
|
||||
|
||||
p->next_match_value = delta;
|
||||
sh_cmt_clock_event_program_verify(p, 0);
|
||||
}
|
||||
|
||||
static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (delta > p->max_match_value)
|
||||
dev_warn(&p->pdev->dev, "delta out of range\n");
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
p->next_match_value = delta;
|
||||
sh_cmt_clock_event_program_verify(p, 0);
|
||||
__sh_cmt_set_next(p, delta);
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
|
||||
|
||||
/* setup timeout if no clockevent */
|
||||
if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
|
||||
sh_cmt_set_next(p, p->max_match_value);
|
||||
__sh_cmt_set_next(p, p->max_match_value);
|
||||
out:
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
|
||||
@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
|
||||
|
||||
/* adjust the timeout to maximum if only clocksource left */
|
||||
if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
|
||||
sh_cmt_set_next(p, p->max_match_value);
|
||||
__sh_cmt_set_next(p, p->max_match_value);
|
||||
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev,
|
||||
}
|
||||
#undef OLD_KEY_MAX
|
||||
|
||||
static int evdev_handle_get_keycode(struct input_dev *dev,
|
||||
void __user *p, size_t size)
|
||||
static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p)
|
||||
{
|
||||
struct input_keymap_entry ke = {
|
||||
.len = sizeof(unsigned int),
|
||||
.flags = 0,
|
||||
};
|
||||
int __user *ip = (int __user *)p;
|
||||
int error;
|
||||
|
||||
/* legacy case */
|
||||
if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
|
||||
error = input_get_keycode(dev, &ke);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (put_user(ke.keycode, ip + 1))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p)
|
||||
{
|
||||
struct input_keymap_entry ke;
|
||||
int error;
|
||||
|
||||
memset(&ke, 0, sizeof(ke));
|
||||
if (copy_from_user(&ke, p, sizeof(ke)))
|
||||
return -EFAULT;
|
||||
|
||||
if (size == sizeof(unsigned int[2])) {
|
||||
/* legacy case */
|
||||
int __user *ip = (int __user *)p;
|
||||
error = input_get_keycode(dev, &ke);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
if (copy_to_user(p, &ke, sizeof(ke)))
|
||||
return -EFAULT;
|
||||
|
||||
ke.len = sizeof(unsigned int);
|
||||
ke.flags = 0;
|
||||
|
||||
error = input_get_keycode(dev, &ke);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (put_user(ke.keycode, ip + 1))
|
||||
return -EFAULT;
|
||||
|
||||
} else {
|
||||
size = min(size, sizeof(ke));
|
||||
|
||||
if (copy_from_user(&ke, p, size))
|
||||
return -EFAULT;
|
||||
|
||||
error = input_get_keycode(dev, &ke);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (copy_to_user(p, &ke, size))
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int evdev_handle_set_keycode(struct input_dev *dev,
|
||||
void __user *p, size_t size)
|
||||
static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p)
|
||||
{
|
||||
struct input_keymap_entry ke = {
|
||||
.len = sizeof(unsigned int),
|
||||
.flags = 0,
|
||||
};
|
||||
int __user *ip = (int __user *)p;
|
||||
|
||||
if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(ke.keycode, ip + 1))
|
||||
return -EFAULT;
|
||||
|
||||
return input_set_keycode(dev, &ke);
|
||||
}
|
||||
|
||||
static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
|
||||
{
|
||||
struct input_keymap_entry ke;
|
||||
|
||||
memset(&ke, 0, sizeof(ke));
|
||||
if (copy_from_user(&ke, p, sizeof(ke)))
|
||||
return -EFAULT;
|
||||
|
||||
if (size == sizeof(unsigned int[2])) {
|
||||
/* legacy case */
|
||||
int __user *ip = (int __user *)p;
|
||||
|
||||
if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(ke.keycode, ip + 1))
|
||||
return -EFAULT;
|
||||
|
||||
ke.len = sizeof(unsigned int);
|
||||
ke.flags = 0;
|
||||
|
||||
} else {
|
||||
size = min(size, sizeof(ke));
|
||||
|
||||
if (copy_from_user(&ke, p, size))
|
||||
return -EFAULT;
|
||||
|
||||
if (ke.len > sizeof(ke.scancode))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ke.len > sizeof(ke.scancode))
|
||||
return -EINVAL;
|
||||
|
||||
return input_set_keycode(dev, &ke);
|
||||
}
|
||||
@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
return evdev_grab(evdev, client);
|
||||
else
|
||||
return evdev_ungrab(evdev, client);
|
||||
|
||||
case EVIOCGKEYCODE:
|
||||
return evdev_handle_get_keycode(dev, p);
|
||||
|
||||
case EVIOCSKEYCODE:
|
||||
return evdev_handle_set_keycode(dev, p);
|
||||
|
||||
case EVIOCGKEYCODE_V2:
|
||||
return evdev_handle_get_keycode_v2(dev, p);
|
||||
|
||||
case EVIOCSKEYCODE_V2:
|
||||
return evdev_handle_set_keycode_v2(dev, p);
|
||||
}
|
||||
|
||||
size = _IOC_SIZE(cmd);
|
||||
@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
return -EFAULT;
|
||||
|
||||
return error;
|
||||
|
||||
case EVIOC_MASK_SIZE(EVIOCGKEYCODE):
|
||||
return evdev_handle_get_keycode(dev, p, size);
|
||||
|
||||
case EVIOC_MASK_SIZE(EVIOCSKEYCODE):
|
||||
return evdev_handle_set_keycode(dev, p, size);
|
||||
}
|
||||
|
||||
/* Multi-number variable-length handlers */
|
||||
|
@ -1436,6 +1436,8 @@ static struct wacom_features wacom_features_0xD2 =
|
||||
{ "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
|
||||
static struct wacom_features wacom_features_0xD3 =
|
||||
{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
|
||||
static const struct wacom_features wacom_features_0xD4 =
|
||||
{ "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT };
|
||||
static struct wacom_features wacom_features_0xD8 =
|
||||
{ "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
|
||||
static struct wacom_features wacom_features_0xDA =
|
||||
@ -1510,6 +1512,7 @@ const struct usb_device_id wacom_ids[] = {
|
||||
{ USB_DEVICE_WACOM(0xD1) },
|
||||
{ USB_DEVICE_WACOM(0xD2) },
|
||||
{ USB_DEVICE_WACOM(0xD3) },
|
||||
{ USB_DEVICE_WACOM(0xD4) },
|
||||
{ USB_DEVICE_WACOM(0xD8) },
|
||||
{ USB_DEVICE_WACOM(0xDA) },
|
||||
{ USB_DEVICE_WACOM(0xDB) },
|
||||
|
@ -517,9 +517,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
|
||||
*/
|
||||
|
||||
if (q->merge_bvec_fn && !ti->type->merge)
|
||||
limits->max_sectors =
|
||||
min_not_zero(limits->max_sectors,
|
||||
(unsigned int) (PAGE_SIZE >> 9));
|
||||
blk_limits_max_hw_sectors(limits,
|
||||
(unsigned int) (PAGE_SIZE >> 9));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_set_device_limits);
|
||||
@ -1131,11 +1130,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
|
||||
*/
|
||||
q->limits = *limits;
|
||||
|
||||
if (limits->no_cluster)
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
|
||||
else
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
|
||||
|
||||
if (!dm_table_supports_discards(t))
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
|
||||
else
|
||||
|
@ -4295,9 +4295,6 @@ static int md_alloc(dev_t dev, char *name)
|
||||
goto abort;
|
||||
mddev->queue->queuedata = mddev;
|
||||
|
||||
/* Can be unlocked because the queue is new: no concurrency */
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
|
||||
|
||||
blk_queue_make_request(mddev->queue, md_make_request);
|
||||
|
||||
disk = alloc_disk(1 << shift);
|
||||
|
@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e
|
||||
static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
|
||||
|
||||
int b_depth = vv->ov_fmt->depth;
|
||||
int b_bpl = vv->ov_fb.fmt.bytesperline;
|
||||
@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct saa7146_video_dma vdma1;
|
||||
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
int width = buf->fmt->width;
|
||||
int height = buf->fmt->height;
|
||||
@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
|
||||
struct saa7146_video_dma vdma2;
|
||||
struct saa7146_video_dma vdma3;
|
||||
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
int width = buf->fmt->width;
|
||||
int height = buf->fmt->height;
|
||||
@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
|
||||
|
||||
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
|
||||
{
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
u32 vdma1_prot_addr;
|
||||
|
||||
|
@ -84,7 +84,7 @@ static struct saa7146_format formats[] = {
|
||||
|
||||
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
|
||||
|
||||
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
|
||||
struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
|
||||
{
|
||||
int i, j = NUM_FORMATS;
|
||||
|
||||
@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
|
||||
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
|
||||
struct scatterlist *list = dma->sglist;
|
||||
int length = dma->sglen;
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
|
||||
|
||||
@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh)
|
||||
}
|
||||
}
|
||||
|
||||
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
|
||||
return -EPERM;
|
||||
|
||||
/* check args */
|
||||
fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
|
||||
if (NULL == fmt)
|
||||
return -EINVAL;
|
||||
|
||||
@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
|
||||
|
||||
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
|
||||
|
||||
fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
|
||||
if (NULL == fmt)
|
||||
return -EINVAL;
|
||||
|
||||
@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||
buf->fmt = &fh->video_fmt;
|
||||
buf->vb.field = fh->video_fmt.field;
|
||||
|
||||
sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
release_all_pagetables(dev, buf);
|
||||
if( 0 != IS_PLANAR(sfmt->trans)) {
|
||||
@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
|
||||
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
fh->video_fmt.bytesperline = 0;
|
||||
fh->video_fmt.field = V4L2_FIELD_ANY;
|
||||
sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
|
||||
|
||||
videobuf_queue_sg_init(&fh->video_q, &video_qops,
|
||||
|
@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
|
||||
|
||||
static const struct v4l2_file_operations rtrack_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.ioctl = video_ioctl2,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
};
|
||||
|
||||
static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
|
||||
@ -412,13 +412,6 @@ static int __init rtrack_init(void)
|
||||
rt->vdev.release = video_device_release_empty;
|
||||
video_set_drvdata(&rt->vdev, rt);
|
||||
|
||||
if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
v4l2_device_unregister(&rt->v4l2_dev);
|
||||
release_region(rt->io, 2);
|
||||
return -EINVAL;
|
||||
}
|
||||
v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
|
||||
|
||||
/* Set up the I/O locking */
|
||||
|
||||
mutex_init(&rt->lock);
|
||||
@ -430,6 +423,13 @@ static int __init rtrack_init(void)
|
||||
sleep_delay(2000000); /* make sure it's totally down */
|
||||
outb(0xc0, rt->io); /* steady volume, mute card */
|
||||
|
||||
if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
v4l2_device_unregister(&rt->v4l2_dev);
|
||||
release_region(rt->io, 2);
|
||||
return -EINVAL;
|
||||
}
|
||||
v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user