mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
Merge branch 'x86/urgent' into x86/core
This commit is contained in:
commit
3b6f7b9beb
1
CREDITS
1
CREDITS
@ -2166,7 +2166,6 @@ D: Initial implementation of VC's, pty's and select()
|
||||
|
||||
N: Pavel Machek
|
||||
E: pavel@ucw.cz
|
||||
E: pavel@suse.cz
|
||||
D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd
|
||||
D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB,
|
||||
D: work on suspend-to-ram/disk, killing duplicates from ioctl32
|
||||
|
@ -1,6 +1,6 @@
|
||||
What: /sys/firmware/memmap/
|
||||
Date: June 2008
|
||||
Contact: Bernhard Walle <bwalle@suse.de>
|
||||
Contact: Bernhard Walle <bernhard.walle@gmx.de>
|
||||
Description:
|
||||
On all platforms, the firmware provides a memory map which the
|
||||
kernel reads. The resources from that memory map are registered
|
||||
|
@ -93,7 +93,7 @@ the PCI Express Port Bus driver from loading a service driver.
|
||||
|
||||
int pcie_port_service_register(struct pcie_port_service_driver *new)
|
||||
|
||||
This API replaces the Linux Driver Model's pci_module_init API. A
|
||||
This API replaces the Linux Driver Model's pci_register_driver API. A
|
||||
service driver should always calls pcie_port_service_register at
|
||||
module init. Note that after service driver being loaded, calls
|
||||
such as pci_enable_device(dev) and pci_set_master(dev) are no longer
|
||||
|
@ -252,10 +252,8 @@ cgroup file system directories.
|
||||
When a task is moved from one cgroup to another, it gets a new
|
||||
css_set pointer - if there's an already existing css_set with the
|
||||
desired collection of cgroups then that group is reused, else a new
|
||||
css_set is allocated. Note that the current implementation uses a
|
||||
linear search to locate an appropriate existing css_set, so isn't
|
||||
very efficient. A future version will use a hash table for better
|
||||
performance.
|
||||
css_set is allocated. The appropriate existing css_set is located by
|
||||
looking into a hash table.
|
||||
|
||||
To allow access from a cgroup to the css_sets (and hence tasks)
|
||||
that comprise it, a set of cg_cgroup_link objects form a lattice;
|
||||
|
101
Documentation/hwmon/hpfall.c
Normal file
101
Documentation/hwmon/hpfall.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* Disk protection for HP machines.
|
||||
*
|
||||
* Copyright 2008 Eric Piel
|
||||
* Copyright 2009 Pavel Machek <pavel@suse.cz>
|
||||
*
|
||||
* GPLv2.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
void write_int(char *path, int i)
|
||||
{
|
||||
char buf[1024];
|
||||
int fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(buf, "%d", i);
|
||||
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void set_led(int on)
|
||||
{
|
||||
write_int("/sys/class/leds/hp::hddprotect/brightness", on);
|
||||
}
|
||||
|
||||
void protect(int seconds)
|
||||
{
|
||||
write_int("/sys/block/sda/device/unload_heads", seconds*1000);
|
||||
}
|
||||
|
||||
int on_ac(void)
|
||||
{
|
||||
// /sys/class/power_supply/AC0/online
|
||||
}
|
||||
|
||||
int lid_open(void)
|
||||
{
|
||||
// /proc/acpi/button/lid/LID/state
|
||||
}
|
||||
|
||||
void ignore_me(void)
|
||||
{
|
||||
protect(0);
|
||||
set_led(0);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
fd = open("/dev/freefall", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
signal(SIGALRM, ignore_me);
|
||||
|
||||
for (;;) {
|
||||
unsigned char count;
|
||||
|
||||
ret = read(fd, &count, sizeof(count));
|
||||
alarm(0);
|
||||
if ((ret == -1) && (errno == EINTR)) {
|
||||
/* Alarm expired, time to unpark the heads */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret != sizeof(count)) {
|
||||
perror("read");
|
||||
break;
|
||||
}
|
||||
|
||||
protect(21);
|
||||
set_led(1);
|
||||
if (1 || on_ac() || lid_open()) {
|
||||
alarm(2);
|
||||
} else {
|
||||
alarm(20);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -33,6 +33,14 @@ rate - reports the sampling rate of the accelerometer device in HZ
|
||||
This driver also provides an absolute input class device, allowing
|
||||
the laptop to act as a pinball machine-esque joystick.
|
||||
|
||||
Another feature of the driver is misc device called "freefall" that
|
||||
acts similar to /dev/rtc and reacts on free-fall interrupts received
|
||||
from the device. It supports blocking operations, poll/select and
|
||||
fasync operation modes. You must read 1 bytes from the device. The
|
||||
result is number of free-fall interrupts since the last successful
|
||||
read (or 255 if number of interrupts would not fit).
|
||||
|
||||
|
||||
Axes orientation
|
||||
----------------
|
||||
|
||||
|
@ -78,12 +78,10 @@ to view your kernel log and look for "mmiotrace has lost events" warning. If
|
||||
events were lost, the trace is incomplete. You should enlarge the buffers and
|
||||
try again. Buffers are enlarged by first seeing how large the current buffers
|
||||
are:
|
||||
$ cat /debug/tracing/trace_entries
|
||||
$ cat /debug/tracing/buffer_size_kb
|
||||
gives you a number. Approximately double this number and write it back, for
|
||||
instance:
|
||||
$ echo 0 > /debug/tracing/tracing_enabled
|
||||
$ echo 128000 > /debug/tracing/trace_entries
|
||||
$ echo 1 > /debug/tracing/tracing_enabled
|
||||
$ echo 128000 > /debug/tracing/buffer_size_kb
|
||||
Then start again from the top.
|
||||
|
||||
If you are doing a trace for a driver project, e.g. Nouveau, you should also
|
||||
|
25
MAINTAINERS
25
MAINTAINERS
@ -692,6 +692,13 @@ M: kernel@wantstofly.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
ARM/NUVOTON W90X900 ARM ARCHITECTURE
|
||||
P: Wan ZongShun
|
||||
M: mcuos.com@gmail.com
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.mcuos.com
|
||||
S: Maintained
|
||||
|
||||
ARPD SUPPORT
|
||||
P: Jonathan Layes
|
||||
L: netdev@vger.kernel.org
|
||||
@ -1905,10 +1912,10 @@ W: http://gigaset307x.sourceforge.net/
|
||||
S: Maintained
|
||||
|
||||
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
|
||||
P: Robert Love
|
||||
M: rlove@rlove.org
|
||||
M: linux-kernel@vger.kernel.org
|
||||
W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
|
||||
P: Frank Seidel
|
||||
M: frank@f-seidel.de
|
||||
L: lm-sensors@lm-sensors.org
|
||||
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
|
||||
S: Maintained
|
||||
|
||||
GSPCA FINEPIX SUBDRIVER
|
||||
@ -2001,7 +2008,7 @@ S: Maintained
|
||||
|
||||
HIBERNATION (aka Software Suspend, aka swsusp)
|
||||
P: Pavel Machek
|
||||
M: pavel@suse.cz
|
||||
M: pavel@ucw.cz
|
||||
P: Rafael J. Wysocki
|
||||
M: rjw@sisk.pl
|
||||
L: linux-pm@lists.linux-foundation.org
|
||||
@ -4172,7 +4179,7 @@ SUSPEND TO RAM
|
||||
P: Len Brown
|
||||
M: len.brown@intel.com
|
||||
P: Pavel Machek
|
||||
M: pavel@suse.cz
|
||||
M: pavel@ucw.cz
|
||||
P: Rafael J. Wysocki
|
||||
M: rjw@sisk.pl
|
||||
L: linux-pm@lists.linux-foundation.org
|
||||
@ -4924,11 +4931,11 @@ L: zd1211-devs@lists.sourceforge.net (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
ZR36067 VIDEO FOR LINUX DRIVER
|
||||
P: Ronald Bultje
|
||||
M: rbultje@ronald.bitfreak.net
|
||||
L: mjpeg-users@lists.sourceforge.net
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://mjpeg.sourceforge.net/driver-zoran/
|
||||
S: Maintained
|
||||
T: Mercurial http://linuxtv.org/hg/v4l-dvb
|
||||
S: Odd Fixes
|
||||
|
||||
ZS DECSTATION Z85C30 SERIAL DRIVER
|
||||
P: Maciej W. Rozycki
|
||||
|
2
Makefile
2
Makefile
@ -389,6 +389,7 @@ PHONY += outputmakefile
|
||||
# output directory.
|
||||
outputmakefile:
|
||||
ifneq ($(KBUILD_SRC),)
|
||||
$(Q)ln -fsn $(srctree) source
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
|
||||
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
|
||||
endif
|
||||
@ -947,7 +948,6 @@ ifneq ($(KBUILD_SRC),)
|
||||
mkdir -p include2; \
|
||||
ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \
|
||||
fi
|
||||
ln -fsn $(srctree) source
|
||||
endif
|
||||
|
||||
# prepare2 creates a makefile if using a separate output directory
|
||||
|
@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr)
|
||||
if (cpuid != boot_cpuid) {
|
||||
flags |= 0x00040000UL; /* "remain halted" */
|
||||
*pflags = flags;
|
||||
cpu_clear(cpuid, cpu_present_map);
|
||||
cpu_clear(cpuid, cpu_possible_map);
|
||||
set_cpu_present(cpuid, false);
|
||||
set_cpu_possible(cpuid, false);
|
||||
halt();
|
||||
}
|
||||
#endif
|
||||
@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Wait for the secondaries to halt. */
|
||||
cpu_clear(boot_cpuid, cpu_present_map);
|
||||
cpu_clear(boot_cpuid, cpu_possible_map);
|
||||
set_cpu_present(boot_cpuid, false);
|
||||
set_cpu_possible(boot_cpuid, false);
|
||||
while (cpus_weight(cpu_present_map))
|
||||
barrier();
|
||||
#endif
|
||||
|
@ -120,12 +120,12 @@ void __cpuinit
|
||||
smp_callin(void)
|
||||
{
|
||||
int cpuid = hard_smp_processor_id();
|
||||
cpumask_t mask = cpu_online_map;
|
||||
|
||||
if (cpu_test_and_set(cpuid, mask)) {
|
||||
if (cpu_online(cpuid)) {
|
||||
printk("??, cpu 0x%x already present??\n", cpuid);
|
||||
BUG();
|
||||
}
|
||||
set_cpu_online(cpuid, true);
|
||||
|
||||
/* Turn on machine checks. */
|
||||
wrmces(7);
|
||||
@ -436,8 +436,8 @@ setup_smp(void)
|
||||
((char *)cpubase + i*hwrpb->processor_size);
|
||||
if ((cpu->flags & 0x1cc) == 0x1cc) {
|
||||
smp_num_probed++;
|
||||
cpu_set(i, cpu_possible_map);
|
||||
cpu_set(i, cpu_present_map);
|
||||
set_cpu_possible(i, true);
|
||||
set_cpu_present(i, true);
|
||||
cpu->pal_revision = boot_cpu_palrev;
|
||||
}
|
||||
|
||||
@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
/* Nothing to do on a UP box, or when told not to. */
|
||||
if (smp_num_probed == 1 || max_cpus == 0) {
|
||||
cpu_possible_map = cpumask_of_cpu(boot_cpuid);
|
||||
cpu_present_map = cpumask_of_cpu(boot_cpuid);
|
||||
init_cpu_possible(cpumask_of(boot_cpuid));
|
||||
init_cpu_present(cpumask_of(boot_cpuid));
|
||||
printk(KERN_INFO "SMP mode deactivated.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -700,7 +700,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -710,7 +710,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -606,7 +606,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_AT91SAM9_WATCHDOG=y
|
||||
CONFIG_AT91SAM9X_WATCHDOG=y
|
||||
|
||||
#
|
||||
# Sonics Silicon Backplane
|
||||
|
@ -727,7 +727,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
# CONFIG_AT91SAM9_WATCHDOG is not set
|
||||
# CONFIG_AT91SAM9X_WATCHDOG is not set
|
||||
|
||||
#
|
||||
# USB-based Watchdog Cards
|
||||
|
@ -74,9 +74,9 @@ EXPORT_SYMBOL(elf_set_personality);
|
||||
*/
|
||||
int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
|
||||
{
|
||||
if (executable_stack != EXSTACK_ENABLE_X)
|
||||
if (executable_stack != EXSTACK_DISABLE_X)
|
||||
return 1;
|
||||
if (cpu_architecture() <= CPU_ARCH_ARMv6)
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -697,7 +697,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91cap9_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -643,7 +643,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9260_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -621,7 +621,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9261_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -854,7 +854,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9263_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -609,7 +609,7 @@ static void __init at91_add_device_rtt(void)
|
||||
* Watchdog
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
|
||||
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||
static struct platform_device at91sam9rl_wdt_device = {
|
||||
.name = "at91_wdt",
|
||||
.id = -1,
|
||||
|
@ -490,7 +490,8 @@ postcore_initcall(at91_gpio_debugfs_init);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/* This lock class tells lockdep that GPIO irqs are in a different
|
||||
/*
|
||||
* This lock class tells lockdep that GPIO irqs are in a different
|
||||
* category than their parents, so it won't report false recursion.
|
||||
*/
|
||||
static struct lock_class_key gpio_lock_class;
|
||||
@ -509,9 +510,6 @@ void __init at91_gpio_irq_setup(void)
|
||||
unsigned id = this->id;
|
||||
unsigned i;
|
||||
|
||||
/* enable PIO controller's clock */
|
||||
clk_enable(this->clock);
|
||||
|
||||
__raw_writel(~0, this->regbase + PIO_IDR);
|
||||
|
||||
for (i = 0, pin = this->chipbase; i < 32; i++, pin++) {
|
||||
@ -556,7 +554,14 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
|
||||
data->chipbase = PIN_BASE + i * 32;
|
||||
data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS;
|
||||
|
||||
/* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
|
||||
/* enable PIO controller's clock */
|
||||
clk_enable(data->clock);
|
||||
|
||||
/*
|
||||
* Some processors share peripheral ID between multiple GPIO banks.
|
||||
* SAM9263 (PIOC, PIOD, PIOE)
|
||||
* CAP9 (PIOA, PIOB, PIOC, PIOD)
|
||||
*/
|
||||
if (last && last->id == data->id)
|
||||
last->next = data;
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ struct atmel_nand_data {
|
||||
u8 enable_pin; /* chip enable */
|
||||
u8 det_pin; /* card detect */
|
||||
u8 rdy_pin; /* ready/busy */
|
||||
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
|
||||
u8 ale; /* address line number connected to ALE */
|
||||
u8 cle; /* address line number connected to CLE */
|
||||
u8 bus_width_16; /* buswidth is 16 bit */
|
||||
|
@ -1,3 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-ep93xx/include/mach/gesbc9312.h
|
||||
*/
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "gesbc9312.h"
|
||||
#include "ts72xx.h"
|
||||
|
||||
#endif
|
||||
|
@ -42,7 +42,7 @@ void __init kirkwood_init_irq(void)
|
||||
writel(0, GPIO_EDGE_CAUSE(32));
|
||||
|
||||
for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -40,7 +40,7 @@ void __init mv78xx0_init_irq(void)
|
||||
writel(0, GPIO_EDGE_CAUSE(0));
|
||||
|
||||
for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -565,7 +565,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
|
||||
* find the corresponding register field value. The return register value is
|
||||
* the value before left-shifting. Returns 0xffffffff on error
|
||||
* the value before left-shifting. Returns ~0 on error
|
||||
*/
|
||||
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
{
|
||||
@ -577,7 +577,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (clks == NULL)
|
||||
return 0;
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->div == div))
|
||||
@ -588,7 +588,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
printk(KERN_ERR "clock: Could not find divisor %d for "
|
||||
"clock %s parent %s\n", div, clk->name,
|
||||
clk->parent->name);
|
||||
return 0;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
return clkr->val;
|
||||
@ -708,7 +708,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (clkr->flags & (cpu_mask | DEFAULT_RATE))
|
||||
if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
|
||||
break; /* Found the default rate for this platform */
|
||||
}
|
||||
|
||||
@ -746,7 +746,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->usecount > 0)
|
||||
_omap2_clk_disable(clk);
|
||||
omap2_clk_disable(clk);
|
||||
|
||||
/* Set new source value (previous dividers if any in effect) */
|
||||
reg_val = __raw_readl(src_addr) & ~field_mask;
|
||||
@ -759,11 +759,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
wmb();
|
||||
}
|
||||
|
||||
if (clk->usecount > 0)
|
||||
_omap2_clk_enable(clk);
|
||||
|
||||
clk->parent = new_parent;
|
||||
|
||||
if (clk->usecount > 0)
|
||||
omap2_clk_enable(clk);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = new_parent->rate;
|
||||
|
||||
|
@ -44,7 +44,7 @@ void __init orion5x_init_irq(void)
|
||||
* User can use set_type() if he wants to use edge types handlers.
|
||||
*/
|
||||
for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) {
|
||||
set_irq_chip(i, &orion_gpio_irq_level_chip);
|
||||
set_irq_chip(i, &orion_gpio_irq_chip);
|
||||
set_irq_handler(i, handle_level_irq);
|
||||
irq_desc[i].status |= IRQ_LEVEL;
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
|
@ -693,7 +693,8 @@ static void __init sanity_check_meminfo(void)
|
||||
* Check whether this memory bank would entirely overlap
|
||||
* the vmalloc area.
|
||||
*/
|
||||
if (__va(bank->start) >= VMALLOC_MIN) {
|
||||
if (__va(bank->start) >= VMALLOC_MIN ||
|
||||
__va(bank->start) < PAGE_OFFSET) {
|
||||
printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
|
||||
"(vmalloc region overlap).\n",
|
||||
bank->start, bank->start + bank->size - 1);
|
||||
|
@ -265,51 +265,36 @@ EXPORT_SYMBOL(orion_gpio_set_blink);
|
||||
* polarity LEVEL mask
|
||||
*
|
||||
****************************************************************************/
|
||||
static void gpio_irq_edge_ack(u32 irq)
|
||||
{
|
||||
int pin = irq_to_gpio(irq);
|
||||
|
||||
writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin));
|
||||
static void gpio_irq_ack(u32 irq)
|
||||
{
|
||||
int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
|
||||
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
|
||||
int pin = irq_to_gpio(irq);
|
||||
writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin));
|
||||
}
|
||||
}
|
||||
|
||||
static void gpio_irq_edge_mask(u32 irq)
|
||||
static void gpio_irq_mask(u32 irq)
|
||||
{
|
||||
int pin = irq_to_gpio(irq);
|
||||
u32 u;
|
||||
|
||||
u = readl(GPIO_EDGE_MASK(pin));
|
||||
int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
|
||||
u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
|
||||
GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
|
||||
u32 u = readl(reg);
|
||||
u &= ~(1 << (pin & 31));
|
||||
writel(u, GPIO_EDGE_MASK(pin));
|
||||
writel(u, reg);
|
||||
}
|
||||
|
||||
static void gpio_irq_edge_unmask(u32 irq)
|
||||
static void gpio_irq_unmask(u32 irq)
|
||||
{
|
||||
int pin = irq_to_gpio(irq);
|
||||
u32 u;
|
||||
|
||||
u = readl(GPIO_EDGE_MASK(pin));
|
||||
int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK;
|
||||
u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ?
|
||||
GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin);
|
||||
u32 u = readl(reg);
|
||||
u |= 1 << (pin & 31);
|
||||
writel(u, GPIO_EDGE_MASK(pin));
|
||||
}
|
||||
|
||||
static void gpio_irq_level_mask(u32 irq)
|
||||
{
|
||||
int pin = irq_to_gpio(irq);
|
||||
u32 u;
|
||||
|
||||
u = readl(GPIO_LEVEL_MASK(pin));
|
||||
u &= ~(1 << (pin & 31));
|
||||
writel(u, GPIO_LEVEL_MASK(pin));
|
||||
}
|
||||
|
||||
static void gpio_irq_level_unmask(u32 irq)
|
||||
{
|
||||
int pin = irq_to_gpio(irq);
|
||||
u32 u;
|
||||
|
||||
u = readl(GPIO_LEVEL_MASK(pin));
|
||||
u |= 1 << (pin & 31);
|
||||
writel(u, GPIO_LEVEL_MASK(pin));
|
||||
writel(u, reg);
|
||||
}
|
||||
|
||||
static int gpio_irq_set_type(u32 irq, u32 type)
|
||||
@ -331,9 +316,9 @@ static int gpio_irq_set_type(u32 irq, u32 type)
|
||||
* Set edge/level type.
|
||||
*/
|
||||
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
|
||||
desc->chip = &orion_gpio_irq_edge_chip;
|
||||
desc->handle_irq = handle_edge_irq;
|
||||
} else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
|
||||
desc->chip = &orion_gpio_irq_level_chip;
|
||||
desc->handle_irq = handle_level_irq;
|
||||
} else {
|
||||
printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
|
||||
return -EINVAL;
|
||||
@ -371,19 +356,11 @@ static int gpio_irq_set_type(u32 irq, u32 type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct irq_chip orion_gpio_irq_edge_chip = {
|
||||
.name = "orion_gpio_irq_edge",
|
||||
.ack = gpio_irq_edge_ack,
|
||||
.mask = gpio_irq_edge_mask,
|
||||
.unmask = gpio_irq_edge_unmask,
|
||||
.set_type = gpio_irq_set_type,
|
||||
};
|
||||
|
||||
struct irq_chip orion_gpio_irq_level_chip = {
|
||||
.name = "orion_gpio_irq_level",
|
||||
.mask = gpio_irq_level_mask,
|
||||
.mask_ack = gpio_irq_level_mask,
|
||||
.unmask = gpio_irq_level_unmask,
|
||||
struct irq_chip orion_gpio_irq_chip = {
|
||||
.name = "orion_gpio",
|
||||
.ack = gpio_irq_ack,
|
||||
.mask = gpio_irq_mask,
|
||||
.unmask = gpio_irq_unmask,
|
||||
.set_type = gpio_irq_set_type,
|
||||
};
|
||||
|
||||
|
@ -31,8 +31,7 @@ void orion_gpio_set_blink(unsigned pin, int blink);
|
||||
/*
|
||||
* GPIO interrupt handling.
|
||||
*/
|
||||
extern struct irq_chip orion_gpio_irq_edge_chip;
|
||||
extern struct irq_chip orion_gpio_irq_level_chip;
|
||||
extern struct irq_chip orion_gpio_irq_chip;
|
||||
void orion_gpio_irq_handler(int irqoff);
|
||||
|
||||
|
||||
|
@ -116,6 +116,7 @@ struct atmel_nand_data {
|
||||
int enable_pin; /* chip enable */
|
||||
int det_pin; /* card detect */
|
||||
int rdy_pin; /* ready/busy */
|
||||
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
|
||||
u8 ale; /* address line number connected to ALE */
|
||||
u8 cle; /* address line number connected to CLE */
|
||||
u8 bus_width_16; /* buswidth is 16 bit */
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/* Select x86 specific features in <linux/kvm.h> */
|
||||
#define __KVM_HAVE_IOAPIC
|
||||
#define __KVM_HAVE_DEVICE_ASSIGNMENT
|
||||
|
||||
/* Architectural interrupt line count. */
|
||||
#define KVM_NR_INTERRUPTS 256
|
||||
|
||||
|
@ -31,10 +31,6 @@ static inline int pfn_to_nid(unsigned long pfn)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
|
||||
extern int early_pfn_to_nid(unsigned long pfn);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IA64_DIG /* DIG systems are small */
|
||||
# define MAX_PHYSNODE_ID 8
|
||||
# define NR_NODE_MEMBLKS (MAX_NUMNODES * 8)
|
||||
|
@ -1337,6 +1337,10 @@ static void kvm_release_vm_pages(struct kvm *kvm)
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_sync_events(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
{
|
||||
kvm_iommu_unmap_guest(kvm);
|
||||
|
@ -455,13 +455,18 @@ fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr,
|
||||
if (!vmm_fpswa_interface)
|
||||
return (fpswa_ret_t) {-1, 0, 0, 0};
|
||||
|
||||
/*
|
||||
* Just let fpswa driver to use hardware fp registers.
|
||||
* No fp register is valid in memory.
|
||||
*/
|
||||
memset(&fp_state, 0, sizeof(fp_state_t));
|
||||
|
||||
/*
|
||||
* compute fp_state. only FP registers f6 - f11 are used by the
|
||||
* vmm, so set those bits in the mask and set the low volatile
|
||||
* pointer to point to these registers.
|
||||
*/
|
||||
fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */
|
||||
|
||||
fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6;
|
||||
|
||||
/*
|
||||
* unsigned long (*EFI_FPSWA) (
|
||||
* unsigned long trap_type,
|
||||
* void *Bundle,
|
||||
@ -545,10 +550,6 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim,
|
||||
status = vmm_handle_fpu_swa(0, regs, isr);
|
||||
if (!status)
|
||||
return ;
|
||||
else if (-EAGAIN == status) {
|
||||
vcpu_decrement_iip(vcpu);
|
||||
return ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr)
|
||||
* SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
|
||||
* the section resides.
|
||||
*/
|
||||
int early_pfn_to_nid(unsigned long pfn)
|
||||
int __meminit __early_pfn_to_nid(unsigned long pfn)
|
||||
{
|
||||
int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
|
||||
|
||||
@ -70,7 +70,7 @@ int early_pfn_to_nid(unsigned long pfn)
|
||||
return node_memblk[i].nid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
|
@ -60,7 +60,7 @@
|
||||
/* It should be preserving the high 48 bits and then specifically */
|
||||
/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
|
||||
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
||||
_PAGE_HPTEFLAGS)
|
||||
_PAGE_HPTEFLAGS | _PAGE_SPECIAL)
|
||||
|
||||
/* Bits to mask out from a PMD to get to the PTE page */
|
||||
#define PMD_MASKED_BITS 0
|
||||
|
@ -114,7 +114,7 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
|
||||
* pgprot changes
|
||||
*/
|
||||
#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
|
||||
_PAGE_ACCESSED)
|
||||
_PAGE_ACCESSED | _PAGE_SPECIAL)
|
||||
|
||||
/* Bits to mask out from a PMD to get to the PTE page */
|
||||
#define PMD_MASKED_BITS 0x1ff
|
||||
|
@ -429,7 +429,8 @@ extern int icache_44x_need_flush;
|
||||
#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
|
||||
#endif
|
||||
|
||||
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
|
||||
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
||||
_PAGE_SPECIAL)
|
||||
|
||||
|
||||
#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
|
||||
|
@ -646,11 +646,16 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
|
||||
unsigned int areg, struct pt_regs *regs,
|
||||
unsigned int flags, unsigned int length)
|
||||
{
|
||||
char *ptr = (char *) ¤t->thread.TS_FPR(reg);
|
||||
char *ptr;
|
||||
int ret = 0;
|
||||
|
||||
flush_vsx_to_thread(current);
|
||||
|
||||
if (reg < 32)
|
||||
ptr = (char *) ¤t->thread.TS_FPR(reg);
|
||||
else
|
||||
ptr = (char *) ¤t->thread.vr[reg - 32];
|
||||
|
||||
if (flags & ST)
|
||||
ret = __copy_to_user(addr, ptr, length);
|
||||
else {
|
||||
|
@ -125,6 +125,10 @@ static void kvmppc_free_vcpus(struct kvm *kvm)
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_sync_events(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
{
|
||||
kvmppc_free_vcpus(kvm);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/lmb.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <asm/sparsemem.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/system.h>
|
||||
@ -882,7 +883,7 @@ static void mark_reserved_regions_for_nid(int nid)
|
||||
unsigned long physbase = lmb.reserved.region[i].base;
|
||||
unsigned long size = lmb.reserved.region[i].size;
|
||||
unsigned long start_pfn = physbase >> PAGE_SHIFT;
|
||||
unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
|
||||
unsigned long end_pfn = PFN_UP(physbase + size);
|
||||
struct node_active_region node_ar;
|
||||
unsigned long node_end_pfn = node->node_start_pfn +
|
||||
node->node_spanned_pages;
|
||||
@ -908,7 +909,7 @@ static void mark_reserved_regions_for_nid(int nid)
|
||||
*/
|
||||
if (end_pfn > node_ar.end_pfn)
|
||||
reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
|
||||
- (start_pfn << PAGE_SHIFT);
|
||||
- physbase;
|
||||
/*
|
||||
* Only worry about *this* node, others may not
|
||||
* yet have valid NODE_DATA().
|
||||
|
@ -328,7 +328,7 @@ static int __init ps3_mm_add_memory(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
core_initcall(ps3_mm_add_memory);
|
||||
device_initcall(ps3_mm_add_memory);
|
||||
|
||||
/*============================================================================*/
|
||||
/* dma routines */
|
||||
|
@ -145,7 +145,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value)
|
||||
value->tv_usec = rp.subreg.even / 4096;
|
||||
value->tv_sec = rp.subreg.odd;
|
||||
#else
|
||||
value->tv_usec = cputime % 4096000000ULL;
|
||||
value->tv_usec = (cputime % 4096000000ULL) / 4096;
|
||||
value->tv_sec = cputime / 4096000000ULL;
|
||||
#endif
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ struct mem_chunk {
|
||||
|
||||
extern struct mem_chunk memory_chunk[];
|
||||
extern unsigned long real_memory_size;
|
||||
extern int memory_end_set;
|
||||
extern unsigned long memory_end;
|
||||
|
||||
void detect_memory_layout(struct mem_chunk chunk[]);
|
||||
|
||||
|
@ -82,7 +82,9 @@ char elf_platform[ELF_PLATFORM_SIZE];
|
||||
|
||||
struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
|
||||
volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
|
||||
static unsigned long __initdata memory_end;
|
||||
|
||||
int __initdata memory_end_set;
|
||||
unsigned long __initdata memory_end;
|
||||
|
||||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
@ -281,6 +283,7 @@ void (*pm_power_off)(void) = machine_power_off;
|
||||
static int __init early_parse_mem(char *p)
|
||||
{
|
||||
memory_end = memparse(p, &p);
|
||||
memory_end_set = 1;
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", early_parse_mem);
|
||||
@ -508,8 +511,10 @@ static void __init setup_memory_end(void)
|
||||
int i;
|
||||
|
||||
#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
|
||||
if (ipl_info.type == IPL_TYPE_FCP_DUMP)
|
||||
if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
|
||||
memory_end = ZFCPDUMP_HSA_SIZE;
|
||||
memory_end_set = 1;
|
||||
}
|
||||
#endif
|
||||
memory_size = 0;
|
||||
memory_end &= PAGE_MASK;
|
||||
|
@ -212,6 +212,10 @@ static void kvm_free_vcpus(struct kvm *kvm)
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_sync_events(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
{
|
||||
kvm_free_vcpus(kvm);
|
||||
|
@ -175,28 +175,8 @@ config IOMMU_LEAK
|
||||
Add a simple leak tracer to the IOMMU code. This is useful when you
|
||||
are debugging a buggy device driver that leaks IOMMU mappings.
|
||||
|
||||
config MMIOTRACE
|
||||
bool "Memory mapped IO tracing"
|
||||
depends on DEBUG_KERNEL && PCI
|
||||
select TRACING
|
||||
help
|
||||
Mmiotrace traces Memory Mapped I/O access and is meant for
|
||||
debugging and reverse engineering. It is called from the ioremap
|
||||
implementation and works via page faults. Tracing is disabled by
|
||||
default and can be enabled at run-time.
|
||||
|
||||
See Documentation/tracers/mmiotrace.txt.
|
||||
If you are not helping to develop drivers, say N.
|
||||
|
||||
config MMIOTRACE_TEST
|
||||
tristate "Test module for mmiotrace"
|
||||
depends on MMIOTRACE && m
|
||||
help
|
||||
This is a dumb module for testing mmiotrace. It is very dangerous
|
||||
as it will write garbage to IO memory starting at a given address.
|
||||
However, it should be safe to use on e.g. unused portion of VRAM.
|
||||
|
||||
Say N, unless you absolutely know what you are doing.
|
||||
config HAVE_MMIOTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
#
|
||||
# IO delay types:
|
||||
|
@ -9,6 +9,13 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/* Select x86 specific features in <linux/kvm.h> */
|
||||
#define __KVM_HAVE_PIT
|
||||
#define __KVM_HAVE_IOAPIC
|
||||
#define __KVM_HAVE_DEVICE_ASSIGNMENT
|
||||
#define __KVM_HAVE_MSI
|
||||
#define __KVM_HAVE_USER_NMI
|
||||
|
||||
/* Architectural interrupt line count. */
|
||||
#define KVM_NR_INTERRUPTS 256
|
||||
|
||||
|
@ -32,8 +32,6 @@ static inline void get_memcfg_numa(void)
|
||||
get_memcfg_numa_flat();
|
||||
}
|
||||
|
||||
extern int early_pfn_to_nid(unsigned long pfn);
|
||||
|
||||
extern void resume_map_numa_kva(pgd_t *pgd);
|
||||
|
||||
#else /* !CONFIG_NUMA */
|
||||
|
@ -40,8 +40,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
|
||||
#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
|
||||
NODE_DATA(nid)->node_spanned_pages)
|
||||
|
||||
extern int early_pfn_to_nid(unsigned long pfn);
|
||||
|
||||
#ifdef CONFIG_NUMA_EMU
|
||||
#define FAKE_NODE_MIN_SIZE (64 * 1024 * 1024)
|
||||
#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))
|
||||
|
@ -837,7 +837,7 @@ void clear_local_APIC(void)
|
||||
}
|
||||
|
||||
/* lets not touch this if we didn't frob it */
|
||||
#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL)
|
||||
#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
|
||||
if (maxlvt >= 5) {
|
||||
v = apic_read(APIC_LVTTHMR);
|
||||
apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
|
||||
|
@ -1157,8 +1157,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
|
||||
data->cpu = pol->cpu;
|
||||
data->currpstate = HW_PSTATE_INVALID;
|
||||
|
||||
rc = powernow_k8_cpu_init_acpi(data);
|
||||
if (rc) {
|
||||
if (powernow_k8_cpu_init_acpi(data)) {
|
||||
/*
|
||||
* Use the PSB BIOS structure. This is only availabe on
|
||||
* an UP version, and is deprecated by AMD.
|
||||
@ -1176,17 +1175,20 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
|
||||
"ACPI maintainers and complain to your BIOS "
|
||||
"vendor.\n");
|
||||
#endif
|
||||
goto err_out;
|
||||
kfree(data);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (pol->cpu != 0) {
|
||||
printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
|
||||
"CPU other than CPU0. Complain to your BIOS "
|
||||
"vendor.\n");
|
||||
goto err_out;
|
||||
kfree(data);
|
||||
return -ENODEV;
|
||||
}
|
||||
rc = find_psb_table(data);
|
||||
if (rc) {
|
||||
goto err_out;
|
||||
kfree(data);
|
||||
return -ENODEV;
|
||||
}
|
||||
/* Take a crude guess here.
|
||||
* That guess was in microseconds, so multiply with 1000 */
|
||||
|
@ -295,11 +295,11 @@ void do_machine_check(struct pt_regs * regs, long error_code)
|
||||
* If we know that the error was in user space, send a
|
||||
* SIGBUS. Otherwise, panic if tolerance is low.
|
||||
*
|
||||
* do_exit() takes an awful lot of locks and has a slight
|
||||
* force_sig() takes an awful lot of locks and has a slight
|
||||
* risk of deadlocking.
|
||||
*/
|
||||
if (user_space) {
|
||||
do_exit(SIGBUS);
|
||||
force_sig(SIGBUS, current);
|
||||
} else if (panic_on_oops || tolerant < 2) {
|
||||
mce_panic("Uncorrected machine check",
|
||||
&panicm, mcestart);
|
||||
@ -734,6 +734,7 @@ __setup("mce=", mcheck_enable);
|
||||
static int mce_resume(struct sys_device *dev)
|
||||
{
|
||||
mce_init(NULL);
|
||||
mce_cpu_features(¤t_cpu_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,6 @@ void cpu_idle(void)
|
||||
check_pgt_cache();
|
||||
rmb();
|
||||
|
||||
if (rcu_pending(cpu))
|
||||
rcu_check_callbacks(cpu, 0);
|
||||
|
||||
if (cpu_is_offline(cpu))
|
||||
play_dead();
|
||||
|
||||
|
@ -283,10 +283,13 @@ void __devinit vmi_time_ap_init(void)
|
||||
#endif
|
||||
|
||||
/** vmi clocksource */
|
||||
static struct clocksource clocksource_vmi;
|
||||
|
||||
static cycle_t read_real_cycles(void)
|
||||
{
|
||||
return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
|
||||
cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
|
||||
return ret >= clocksource_vmi.cycle_last ?
|
||||
ret : clocksource_vmi.cycle_last;
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_vmi = {
|
||||
|
@ -207,7 +207,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
|
||||
hrtimer_add_expires_ns(&pt->timer, pt->period);
|
||||
pt->scheduled = hrtimer_get_expires_ns(&pt->timer);
|
||||
if (pt->period)
|
||||
ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer);
|
||||
ps->channels[0].count_load_time = ktime_get();
|
||||
|
||||
return (pt->period == 0 ? 0 : 1);
|
||||
}
|
||||
|
@ -87,13 +87,6 @@ void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
|
||||
|
||||
void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
|
||||
{
|
||||
kvm_apic_timer_intr_post(vcpu, vec);
|
||||
/* TODO: PIT, RTC etc. */
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_timer_intr_post);
|
||||
|
||||
void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
__kvm_migrate_apic_timer(vcpu);
|
||||
|
@ -89,7 +89,6 @@ static inline int irqchip_in_kernel(struct kvm *kvm)
|
||||
|
||||
void kvm_pic_reset(struct kvm_kpic_state *s);
|
||||
|
||||
void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
|
||||
void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
|
||||
void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
|
||||
void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu);
|
||||
|
@ -35,6 +35,12 @@
|
||||
#include "kvm_cache_regs.h"
|
||||
#include "irq.h"
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
|
||||
#else
|
||||
#define mod_64(x, y) ((x) % (y))
|
||||
#endif
|
||||
|
||||
#define PRId64 "d"
|
||||
#define PRIx64 "llx"
|
||||
#define PRIu64 "u"
|
||||
@ -511,52 +517,22 @@ static void apic_send_ipi(struct kvm_lapic *apic)
|
||||
|
||||
static u32 apic_get_tmcct(struct kvm_lapic *apic)
|
||||
{
|
||||
u64 counter_passed;
|
||||
ktime_t passed, now;
|
||||
ktime_t remaining;
|
||||
s64 ns;
|
||||
u32 tmcct;
|
||||
|
||||
ASSERT(apic != NULL);
|
||||
|
||||
now = apic->timer.dev.base->get_time();
|
||||
tmcct = apic_get_reg(apic, APIC_TMICT);
|
||||
|
||||
/* if initial count is 0, current count should also be 0 */
|
||||
if (tmcct == 0)
|
||||
if (apic_get_reg(apic, APIC_TMICT) == 0)
|
||||
return 0;
|
||||
|
||||
if (unlikely(ktime_to_ns(now) <=
|
||||
ktime_to_ns(apic->timer.last_update))) {
|
||||
/* Wrap around */
|
||||
passed = ktime_add(( {
|
||||
(ktime_t) {
|
||||
.tv64 = KTIME_MAX -
|
||||
(apic->timer.last_update).tv64}; }
|
||||
), now);
|
||||
apic_debug("time elapsed\n");
|
||||
} else
|
||||
passed = ktime_sub(now, apic->timer.last_update);
|
||||
remaining = hrtimer_expires_remaining(&apic->timer.dev);
|
||||
if (ktime_to_ns(remaining) < 0)
|
||||
remaining = ktime_set(0, 0);
|
||||
|
||||
counter_passed = div64_u64(ktime_to_ns(passed),
|
||||
(APIC_BUS_CYCLE_NS * apic->timer.divide_count));
|
||||
|
||||
if (counter_passed > tmcct) {
|
||||
if (unlikely(!apic_lvtt_period(apic))) {
|
||||
/* one-shot timers stick at 0 until reset */
|
||||
tmcct = 0;
|
||||
} else {
|
||||
/*
|
||||
* periodic timers reset to APIC_TMICT when they
|
||||
* hit 0. The while loop simulates this happening N
|
||||
* times. (counter_passed %= tmcct) would also work,
|
||||
* but might be slower or not work on 32-bit??
|
||||
*/
|
||||
while (counter_passed > tmcct)
|
||||
counter_passed -= tmcct;
|
||||
tmcct -= counter_passed;
|
||||
}
|
||||
} else {
|
||||
tmcct -= counter_passed;
|
||||
}
|
||||
ns = mod_64(ktime_to_ns(remaining), apic->timer.period);
|
||||
tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
|
||||
|
||||
return tmcct;
|
||||
}
|
||||
@ -653,8 +629,6 @@ static void start_apic_timer(struct kvm_lapic *apic)
|
||||
{
|
||||
ktime_t now = apic->timer.dev.base->get_time();
|
||||
|
||||
apic->timer.last_update = now;
|
||||
|
||||
apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
|
||||
APIC_BUS_CYCLE_NS * apic->timer.divide_count;
|
||||
atomic_set(&apic->timer.pending, 0);
|
||||
@ -1110,16 +1084,6 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
|
||||
if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec)
|
||||
apic->timer.last_update = ktime_add_ns(
|
||||
apic->timer.last_update,
|
||||
apic->timer.period);
|
||||
}
|
||||
|
||||
int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int vector = kvm_apic_has_interrupt(vcpu);
|
||||
|
@ -12,7 +12,6 @@ struct kvm_lapic {
|
||||
atomic_t pending;
|
||||
s64 period; /* unit: ns */
|
||||
u32 divide_count;
|
||||
ktime_t last_update;
|
||||
struct hrtimer dev;
|
||||
} timer;
|
||||
struct kvm_vcpu *vcpu;
|
||||
@ -42,7 +41,6 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
|
||||
void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
|
||||
int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
|
||||
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
|
||||
void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
|
||||
|
||||
void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
|
||||
void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
|
||||
|
@ -1698,8 +1698,13 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
|
||||
if (largepage)
|
||||
spte |= PT_PAGE_SIZE_MASK;
|
||||
if (mt_mask) {
|
||||
mt_mask = get_memory_type(vcpu, gfn) <<
|
||||
kvm_x86_ops->get_mt_mask_shift();
|
||||
if (!kvm_is_mmio_pfn(pfn)) {
|
||||
mt_mask = get_memory_type(vcpu, gfn) <<
|
||||
kvm_x86_ops->get_mt_mask_shift();
|
||||
mt_mask |= VMX_EPT_IGMT_BIT;
|
||||
} else
|
||||
mt_mask = MTRR_TYPE_UNCACHABLE <<
|
||||
kvm_x86_ops->get_mt_mask_shift();
|
||||
spte |= mt_mask;
|
||||
}
|
||||
|
||||
|
@ -1600,7 +1600,6 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
|
||||
/* Okay, we can deliver the interrupt: grab it and update PIC state. */
|
||||
intr_vector = kvm_cpu_get_interrupt(vcpu);
|
||||
svm_inject_irq(svm, intr_vector);
|
||||
kvm_timer_intr_post(vcpu, intr_vector);
|
||||
out:
|
||||
update_cr8_intercept(vcpu);
|
||||
}
|
||||
|
@ -903,6 +903,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
|
||||
data = vmcs_readl(GUEST_SYSENTER_ESP);
|
||||
break;
|
||||
default:
|
||||
vmx_load_host_state(to_vmx(vcpu));
|
||||
msr = find_msr_entry(to_vmx(vcpu), msr_index);
|
||||
if (msr) {
|
||||
data = msr->data;
|
||||
@ -3285,7 +3286,6 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
if (vcpu->arch.interrupt.pending) {
|
||||
vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
|
||||
kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr);
|
||||
if (kvm_cpu_has_interrupt(vcpu))
|
||||
enable_irq_window(vcpu);
|
||||
}
|
||||
@ -3687,8 +3687,7 @@ static int __init vmx_init(void)
|
||||
if (vm_need_ept()) {
|
||||
bypass_guest_pf = 0;
|
||||
kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
|
||||
VMX_EPT_WRITABLE_MASK |
|
||||
VMX_EPT_IGMT_BIT);
|
||||
VMX_EPT_WRITABLE_MASK);
|
||||
kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
|
||||
VMX_EPT_EXECUTABLE_MASK,
|
||||
VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
|
||||
|
@ -967,7 +967,6 @@ int kvm_dev_ioctl_check_extension(long ext)
|
||||
case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
|
||||
case KVM_CAP_SET_TSS_ADDR:
|
||||
case KVM_CAP_EXT_CPUID:
|
||||
case KVM_CAP_CLOCKSOURCE:
|
||||
case KVM_CAP_PIT:
|
||||
case KVM_CAP_NOP_IO_DELAY:
|
||||
case KVM_CAP_MP_STATE:
|
||||
@ -992,6 +991,9 @@ int kvm_dev_ioctl_check_extension(long ext)
|
||||
case KVM_CAP_IOMMU:
|
||||
r = iommu_found();
|
||||
break;
|
||||
case KVM_CAP_CLOCKSOURCE:
|
||||
r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC);
|
||||
break;
|
||||
default:
|
||||
r = 0;
|
||||
break;
|
||||
@ -4127,9 +4129,13 @@ static void kvm_free_vcpus(struct kvm *kvm)
|
||||
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
void kvm_arch_sync_events(struct kvm *kvm)
|
||||
{
|
||||
kvm_free_all_assigned_devices(kvm);
|
||||
}
|
||||
|
||||
void kvm_arch_destroy_vm(struct kvm *kvm)
|
||||
{
|
||||
kvm_iommu_unmap_guest(kvm);
|
||||
kvm_free_pit(kvm);
|
||||
kfree(kvm->arch.vpic);
|
||||
|
@ -166,7 +166,7 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes,
|
||||
return shift;
|
||||
}
|
||||
|
||||
int early_pfn_to_nid(unsigned long pfn)
|
||||
int __meminit __early_pfn_to_nid(unsigned long pfn)
|
||||
{
|
||||
return phys_to_nid(pfn << PAGE_SHIFT);
|
||||
}
|
||||
|
@ -508,18 +508,13 @@ static int split_large_page(pte_t *kpte, unsigned long address)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Install the new, split up pagetable. Important details here:
|
||||
* Install the new, split up pagetable.
|
||||
*
|
||||
* On Intel the NX bit of all levels must be cleared to make a
|
||||
* page executable. See section 4.13.2 of Intel 64 and IA-32
|
||||
* Architectures Software Developer's Manual).
|
||||
*
|
||||
* Mark the entry present. The current mapping might be
|
||||
* set to not present, which we preserved above.
|
||||
* We use the standard kernel pagetable protections for the new
|
||||
* pagetable protections, the actual ptes set above control the
|
||||
* primary protection behavior:
|
||||
*/
|
||||
ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte)));
|
||||
pgprot_val(ref_prot) |= _PAGE_PRESENT;
|
||||
__set_pmd_pte(kpte, address, mk_pte(base, ref_prot));
|
||||
__set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE)));
|
||||
base = NULL;
|
||||
|
||||
out_unlock:
|
||||
|
@ -209,12 +209,19 @@ void blk_abort_queue(struct request_queue *q)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct request *rq, *tmp;
|
||||
LIST_HEAD(list);
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
|
||||
elv_abort_queue(q);
|
||||
|
||||
list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
|
||||
/*
|
||||
* Splice entries to local list, to avoid deadlocking if entries
|
||||
* get readded to the timeout list by error handling
|
||||
*/
|
||||
list_splice_init(&q->timeout_list, &list);
|
||||
|
||||
list_for_each_entry_safe(rq, tmp, &list, timeout_list)
|
||||
blk_abort_request(rq);
|
||||
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
@ -142,7 +142,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
|
||||
|
||||
what |= ddir_act[rw & WRITE];
|
||||
what |= MASK_TC_BIT(rw, BARRIER);
|
||||
what |= MASK_TC_BIT(rw, SYNC);
|
||||
what |= MASK_TC_BIT(rw, SYNCIO);
|
||||
what |= MASK_TC_BIT(rw, AHEAD);
|
||||
what |= MASK_TC_BIT(rw, META);
|
||||
what |= MASK_TC_BIT(rw, DISCARD);
|
||||
|
17
block/bsg.c
17
block/bsg.c
@ -244,7 +244,8 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
|
||||
* map sg_io_v4 to a request.
|
||||
*/
|
||||
static struct request *
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
|
||||
u8 *sense)
|
||||
{
|
||||
struct request_queue *q = bd->queue;
|
||||
struct request *rq, *next_rq = NULL;
|
||||
@ -306,6 +307,10 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
|
||||
return rq;
|
||||
out:
|
||||
if (rq->cmd != rq->__cmd)
|
||||
@ -348,9 +353,6 @@ static void bsg_rq_end_io(struct request *rq, int uptodate)
|
||||
static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
|
||||
struct bsg_command *bc, struct request *rq)
|
||||
{
|
||||
rq->sense = bc->sense;
|
||||
rq->sense_len = 0;
|
||||
|
||||
/*
|
||||
* add bc command to busy queue and submit rq for io
|
||||
*/
|
||||
@ -419,7 +421,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
dprintk("rq %p bio %p %u\n", rq, bio, rq->errors);
|
||||
dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
|
||||
/*
|
||||
* fill in all the output members
|
||||
*/
|
||||
@ -635,7 +637,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
|
||||
/*
|
||||
* get a request, fill in the blanks, and add to request queue
|
||||
*/
|
||||
rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm);
|
||||
rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense);
|
||||
if (IS_ERR(rq)) {
|
||||
ret = PTR_ERR(rq);
|
||||
rq = NULL;
|
||||
@ -922,11 +924,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
struct request *rq;
|
||||
struct bio *bio, *bidi_bio = NULL;
|
||||
struct sg_io_v4 hdr;
|
||||
u8 sense[SCSI_SENSE_BUFFERSIZE];
|
||||
|
||||
if (copy_from_user(&hdr, uarg, sizeof(hdr)))
|
||||
return -EFAULT;
|
||||
|
||||
rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE);
|
||||
rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense);
|
||||
if (IS_ERR(rq))
|
||||
return PTR_ERR(rq);
|
||||
|
||||
|
@ -1087,6 +1087,14 @@ dev_t blk_lookup_devt(const char *name, int partno)
|
||||
if (strcmp(dev_name(dev), name))
|
||||
continue;
|
||||
|
||||
if (partno < disk->minors) {
|
||||
/* We need to return the right devno, even
|
||||
* if the partition doesn't exist yet.
|
||||
*/
|
||||
devt = MKDEV(MAJOR(dev->devt),
|
||||
MINOR(dev->devt) + partno);
|
||||
break;
|
||||
}
|
||||
part = disk_get_part(disk, partno);
|
||||
if (part) {
|
||||
devt = part_devt(part);
|
||||
|
@ -45,7 +45,13 @@ struct priv {
|
||||
|
||||
static inline void setbit128_bbe(void *b, int bit)
|
||||
{
|
||||
__set_bit(bit ^ 0x78, b);
|
||||
__set_bit(bit ^ (0x80 -
|
||||
#ifdef __BIG_ENDIAN
|
||||
BITS_PER_LONG
|
||||
#else
|
||||
BITS_PER_BYTE
|
||||
#endif
|
||||
), b);
|
||||
}
|
||||
|
||||
static int setkey(struct crypto_tfm *parent, const u8 *key,
|
||||
|
@ -773,18 +773,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
|
||||
else
|
||||
iowrite32_rep(data_addr, buf, words);
|
||||
|
||||
/* Transfer trailing bytes, if any */
|
||||
if (unlikely(slop)) {
|
||||
__le32 pad;
|
||||
unsigned char pad[4];
|
||||
|
||||
/* Point buf to the tail of buffer */
|
||||
buf += buflen - slop;
|
||||
|
||||
/*
|
||||
* Use io*_rep() accessors here as well to avoid pointlessly
|
||||
* swapping bytes to and fro on the big endian machines...
|
||||
*/
|
||||
if (rw == READ) {
|
||||
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
||||
memcpy(buf + buflen - slop, &pad, slop);
|
||||
if (slop < 3)
|
||||
ioread16_rep(data_addr, pad, 1);
|
||||
else
|
||||
ioread32_rep(data_addr, pad, 1);
|
||||
memcpy(buf, pad, slop);
|
||||
} else {
|
||||
memcpy(&pad, buf + buflen - slop, slop);
|
||||
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||
memcpy(pad, buf, slop);
|
||||
if (slop < 3)
|
||||
iowrite16_rep(data_addr, pad, 1);
|
||||
else
|
||||
iowrite32_rep(data_addr, pad, 1);
|
||||
}
|
||||
words++;
|
||||
}
|
||||
return words << 2;
|
||||
return (buflen + 1) & ~1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
|
||||
|
||||
|
@ -110,7 +110,8 @@ static const struct via_isa_bridge {
|
||||
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
|
||||
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
|
||||
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
|
||||
{ "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
|
||||
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
@ -593,6 +594,7 @@ static int via_reinit_one(struct pci_dev *pdev)
|
||||
#endif
|
||||
|
||||
static const struct pci_device_id via[] = {
|
||||
{ PCI_VDEVICE(VIA, 0x0415), },
|
||||
{ PCI_VDEVICE(VIA, 0x0571), },
|
||||
{ PCI_VDEVICE(VIA, 0x0581), },
|
||||
{ PCI_VDEVICE(VIA, 0x1571), },
|
||||
|
@ -421,19 +421,21 @@ static struct ata_port_operations nv_generic_ops = {
|
||||
.hardreset = ATA_OP_NULL,
|
||||
};
|
||||
|
||||
/* OSDL bz3352 reports that nf2/3 controllers can't determine device
|
||||
* signature reliably. Also, the following thread reports detection
|
||||
* failure on cold boot with the standard debouncing timing.
|
||||
/* nf2 is ripe with hardreset related problems.
|
||||
*
|
||||
* kernel bz#3352 reports nf2/3 controllers can't determine device
|
||||
* signature reliably. The following thread reports detection failure
|
||||
* on cold boot with the standard debouncing timing.
|
||||
*
|
||||
* http://thread.gmane.org/gmane.linux.ide/34098
|
||||
*
|
||||
* Debounce with hotplug timing and request follow-up SRST.
|
||||
* And bz#12176 reports that hardreset simply doesn't work on nf2.
|
||||
* Give up on it and just don't do hardreset.
|
||||
*/
|
||||
static struct ata_port_operations nv_nf2_ops = {
|
||||
.inherits = &nv_common_ops,
|
||||
.inherits = &nv_generic_ops,
|
||||
.freeze = nv_nf2_freeze,
|
||||
.thaw = nv_nf2_thaw,
|
||||
.hardreset = nv_noclassify_hardreset,
|
||||
};
|
||||
|
||||
/* For initial probing after boot and hot plugging, hardreset mostly
|
||||
|
@ -18,6 +18,7 @@
|
||||
enum {
|
||||
AOECMD_ATA,
|
||||
AOECMD_CFG,
|
||||
AOECMD_VEND_MIN = 0xf0,
|
||||
|
||||
AOEFL_RSP = (1<<3),
|
||||
AOEFL_ERR = (1<<2),
|
||||
|
@ -142,6 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
|
||||
aoecmd_cfg_rsp(skb);
|
||||
break;
|
||||
default:
|
||||
if (h->cmd >= AOECMD_VEND_MIN)
|
||||
break; /* don't complain about vendor commands */
|
||||
printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
|
||||
}
|
||||
exit:
|
||||
|
@ -3390,6 +3390,203 @@ static void free_hba(int i)
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
/* Send a message CDB to the firmware. */
|
||||
static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type)
|
||||
{
|
||||
typedef struct {
|
||||
CommandListHeader_struct CommandHeader;
|
||||
RequestBlock_struct Request;
|
||||
ErrDescriptor_struct ErrorDescriptor;
|
||||
} Command;
|
||||
static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct);
|
||||
Command *cmd;
|
||||
dma_addr_t paddr64;
|
||||
uint32_t paddr32, tag;
|
||||
void __iomem *vaddr;
|
||||
int i, err;
|
||||
|
||||
vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
|
||||
if (vaddr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* The Inbound Post Queue only accepts 32-bit physical addresses for the
|
||||
CCISS commands, so they must be allocated from the lower 4GiB of
|
||||
memory. */
|
||||
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
if (err) {
|
||||
iounmap(vaddr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64);
|
||||
if (cmd == NULL) {
|
||||
iounmap(vaddr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* This must fit, because of the 32-bit consistent DMA mask. Also,
|
||||
although there's no guarantee, we assume that the address is at
|
||||
least 4-byte aligned (most likely, it's page-aligned). */
|
||||
paddr32 = paddr64;
|
||||
|
||||
cmd->CommandHeader.ReplyQueue = 0;
|
||||
cmd->CommandHeader.SGList = 0;
|
||||
cmd->CommandHeader.SGTotal = 0;
|
||||
cmd->CommandHeader.Tag.lower = paddr32;
|
||||
cmd->CommandHeader.Tag.upper = 0;
|
||||
memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8);
|
||||
|
||||
cmd->Request.CDBLen = 16;
|
||||
cmd->Request.Type.Type = TYPE_MSG;
|
||||
cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE;
|
||||
cmd->Request.Type.Direction = XFER_NONE;
|
||||
cmd->Request.Timeout = 0; /* Don't time out */
|
||||
cmd->Request.CDB[0] = opcode;
|
||||
cmd->Request.CDB[1] = type;
|
||||
memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */
|
||||
|
||||
cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command);
|
||||
cmd->ErrorDescriptor.Addr.upper = 0;
|
||||
cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct);
|
||||
|
||||
writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
|
||||
if ((tag & ~3) == paddr32)
|
||||
break;
|
||||
schedule_timeout_uninterruptible(HZ);
|
||||
}
|
||||
|
||||
iounmap(vaddr);
|
||||
|
||||
/* we leak the DMA buffer here ... no choice since the controller could
|
||||
still complete the command. */
|
||||
if (i == 10) {
|
||||
printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n",
|
||||
opcode, type);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
pci_free_consistent(pdev, cmd_sz, cmd, paddr64);
|
||||
|
||||
if (tag & 2) {
|
||||
printk(KERN_ERR "cciss: controller message %02x:%02x failed\n",
|
||||
opcode, type);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n",
|
||||
opcode, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0)
|
||||
#define cciss_noop(p) cciss_message(p, 3, 0)
|
||||
|
||||
static __devinit int cciss_reset_msi(struct pci_dev *pdev)
|
||||
{
|
||||
/* the #defines are stolen from drivers/pci/msi.h. */
|
||||
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
|
||||
#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
|
||||
|
||||
int pos;
|
||||
u16 control = 0;
|
||||
|
||||
pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
|
||||
if (pos) {
|
||||
pci_read_config_word(pdev, msi_control_reg(pos), &control);
|
||||
if (control & PCI_MSI_FLAGS_ENABLE) {
|
||||
printk(KERN_INFO "cciss: resetting MSI\n");
|
||||
pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
|
||||
if (pos) {
|
||||
pci_read_config_word(pdev, msi_control_reg(pos), &control);
|
||||
if (control & PCI_MSIX_FLAGS_ENABLE) {
|
||||
printk(KERN_INFO "cciss: resetting MSI-X\n");
|
||||
pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This does a hard reset of the controller using PCI power management
|
||||
* states. */
|
||||
static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev)
|
||||
{
|
||||
u16 pmcsr, saved_config_space[32];
|
||||
int i, pos;
|
||||
|
||||
printk(KERN_INFO "cciss: using PCI PM to reset controller\n");
|
||||
|
||||
/* This is very nearly the same thing as
|
||||
|
||||
pci_save_state(pci_dev);
|
||||
pci_set_power_state(pci_dev, PCI_D3hot);
|
||||
pci_set_power_state(pci_dev, PCI_D0);
|
||||
pci_restore_state(pci_dev);
|
||||
|
||||
but we can't use these nice canned kernel routines on
|
||||
kexec, because they also check the MSI/MSI-X state in PCI
|
||||
configuration space and do the wrong thing when it is
|
||||
set/cleared. Also, the pci_save/restore_state functions
|
||||
violate the ordering requirements for restoring the
|
||||
configuration space from the CCISS document (see the
|
||||
comment below). So we roll our own .... */
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
|
||||
|
||||
pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
|
||||
if (pos == 0) {
|
||||
printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Quoting from the Open CISS Specification: "The Power
|
||||
* Management Control/Status Register (CSR) controls the power
|
||||
* state of the device. The normal operating state is D0,
|
||||
* CSR=00h. The software off state is D3, CSR=03h. To reset
|
||||
* the controller, place the interface device in D3 then to
|
||||
* D0, this causes a secondary PCI reset which will reset the
|
||||
* controller." */
|
||||
|
||||
/* enter the D3hot power management state */
|
||||
pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
|
||||
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
|
||||
pmcsr |= PCI_D3hot;
|
||||
pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
|
||||
|
||||
schedule_timeout_uninterruptible(HZ >> 1);
|
||||
|
||||
/* enter the D0 power management state */
|
||||
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
|
||||
pmcsr |= PCI_D0;
|
||||
pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
|
||||
|
||||
schedule_timeout_uninterruptible(HZ >> 1);
|
||||
|
||||
/* Restore the PCI configuration space. The Open CISS
|
||||
* Specification says, "Restore the PCI Configuration
|
||||
* Registers, offsets 00h through 60h. It is important to
|
||||
* restore the command register, 16-bits at offset 04h,
|
||||
* last. Do not restore the configuration status register,
|
||||
* 16-bits at offset 06h." Note that the offset is 2*i. */
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (i == 2 || i == 3)
|
||||
continue;
|
||||
pci_write_config_word(pdev, 2*i, saved_config_space[i]);
|
||||
}
|
||||
wmb();
|
||||
pci_write_config_word(pdev, 4, saved_config_space[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is it. Find all the controllers and register them. I really hate
|
||||
* stealing all these major device numbers.
|
||||
@ -3404,6 +3601,24 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
||||
int dac, return_code;
|
||||
InquiryData_struct *inq_buff = NULL;
|
||||
|
||||
if (reset_devices) {
|
||||
/* Reset the controller with a PCI power-cycle */
|
||||
if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev))
|
||||
return -ENODEV;
|
||||
|
||||
/* Some devices (notably the HP Smart Array 5i Controller)
|
||||
need a little pause here */
|
||||
schedule_timeout_uninterruptible(30*HZ);
|
||||
|
||||
/* Now try to get the controller to respond to a no-op */
|
||||
for (i=0; i<12; i++) {
|
||||
if (cciss_noop(pdev) == 0)
|
||||
break;
|
||||
else
|
||||
printk("cciss: no-op failed%s\n", (i < 11 ? "; re-trying" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
i = alloc_cciss_hba();
|
||||
if (i < 0)
|
||||
return -1;
|
||||
|
@ -558,6 +558,8 @@ static void process_fd_request(void);
|
||||
static void recalibrate_floppy(void);
|
||||
static void floppy_shutdown(unsigned long);
|
||||
|
||||
static int floppy_request_regions(int);
|
||||
static void floppy_release_regions(int);
|
||||
static int floppy_grab_irq_and_dma(void);
|
||||
static void floppy_release_irq_and_dma(void);
|
||||
|
||||
@ -4274,8 +4276,7 @@ static int __init floppy_init(void)
|
||||
FDCS->rawcmd = 2;
|
||||
if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
|
||||
/* free ioports reserved by floppy_grab_irq_and_dma() */
|
||||
release_region(FDCS->address + 2, 4);
|
||||
release_region(FDCS->address + 7, 1);
|
||||
floppy_release_regions(fdc);
|
||||
FDCS->address = -1;
|
||||
FDCS->version = FDC_NONE;
|
||||
continue;
|
||||
@ -4284,8 +4285,7 @@ static int __init floppy_init(void)
|
||||
FDCS->version = get_fdc_version();
|
||||
if (FDCS->version == FDC_NONE) {
|
||||
/* free ioports reserved by floppy_grab_irq_and_dma() */
|
||||
release_region(FDCS->address + 2, 4);
|
||||
release_region(FDCS->address + 7, 1);
|
||||
floppy_release_regions(fdc);
|
||||
FDCS->address = -1;
|
||||
continue;
|
||||
}
|
||||
@ -4358,6 +4358,47 @@ out_put_disk:
|
||||
|
||||
static DEFINE_SPINLOCK(floppy_usage_lock);
|
||||
|
||||
static const struct io_region {
|
||||
int offset;
|
||||
int size;
|
||||
} io_regions[] = {
|
||||
{ 2, 1 },
|
||||
/* address + 3 is sometimes reserved by pnp bios for motherboard */
|
||||
{ 4, 2 },
|
||||
/* address + 6 is reserved, and may be taken by IDE.
|
||||
* Unfortunately, Adaptec doesn't know this :-(, */
|
||||
{ 7, 1 },
|
||||
};
|
||||
|
||||
static void floppy_release_allocated_regions(int fdc, const struct io_region *p)
|
||||
{
|
||||
while (p != io_regions) {
|
||||
p--;
|
||||
release_region(FDCS->address + p->offset, p->size);
|
||||
}
|
||||
}
|
||||
|
||||
#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
|
||||
|
||||
static int floppy_request_regions(int fdc)
|
||||
{
|
||||
const struct io_region *p;
|
||||
|
||||
for (p = io_regions; p < ARRAY_END(io_regions); p++) {
|
||||
if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
|
||||
DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
|
||||
floppy_release_allocated_regions(fdc, p);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void floppy_release_regions(int fdc)
|
||||
{
|
||||
floppy_release_allocated_regions(fdc, ARRAY_END(io_regions));
|
||||
}
|
||||
|
||||
static int floppy_grab_irq_and_dma(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -4399,18 +4440,8 @@ static int floppy_grab_irq_and_dma(void)
|
||||
|
||||
for (fdc = 0; fdc < N_FDC; fdc++) {
|
||||
if (FDCS->address != -1) {
|
||||
if (!request_region(FDCS->address + 2, 4, "floppy")) {
|
||||
DPRINT("Floppy io-port 0x%04lx in use\n",
|
||||
FDCS->address + 2);
|
||||
goto cleanup1;
|
||||
}
|
||||
if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
|
||||
DPRINT("Floppy io-port 0x%04lx in use\n",
|
||||
FDCS->address + 7);
|
||||
goto cleanup2;
|
||||
}
|
||||
/* address + 6 is reserved, and may be taken by IDE.
|
||||
* Unfortunately, Adaptec doesn't know this :-(, */
|
||||
if (floppy_request_regions(fdc))
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
for (fdc = 0; fdc < N_FDC; fdc++) {
|
||||
@ -4432,15 +4463,11 @@ static int floppy_grab_irq_and_dma(void)
|
||||
fdc = 0;
|
||||
irqdma_allocated = 1;
|
||||
return 0;
|
||||
cleanup2:
|
||||
release_region(FDCS->address + 2, 4);
|
||||
cleanup1:
|
||||
cleanup:
|
||||
fd_free_irq();
|
||||
fd_free_dma();
|
||||
while (--fdc >= 0) {
|
||||
release_region(FDCS->address + 2, 4);
|
||||
release_region(FDCS->address + 7, 1);
|
||||
}
|
||||
while (--fdc >= 0)
|
||||
floppy_release_regions(fdc);
|
||||
spin_lock_irqsave(&floppy_usage_lock, flags);
|
||||
usage_count--;
|
||||
spin_unlock_irqrestore(&floppy_usage_lock, flags);
|
||||
@ -4501,10 +4528,8 @@ static void floppy_release_irq_and_dma(void)
|
||||
#endif
|
||||
old_fdc = fdc;
|
||||
for (fdc = 0; fdc < N_FDC; fdc++)
|
||||
if (FDCS->address != -1) {
|
||||
release_region(FDCS->address + 2, 4);
|
||||
release_region(FDCS->address + 7, 1);
|
||||
}
|
||||
if (FDCS->address != -1)
|
||||
floppy_release_regions(fdc);
|
||||
fdc = old_fdc;
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,7 @@ static void xs(char *buf, char *targ, int len)
|
||||
|
||||
for (k = 0; k < len; k++) {
|
||||
char c = *buf++;
|
||||
if (c != ' ' || c != l)
|
||||
if (c != ' ' && c != l)
|
||||
l = *targ++ = c;
|
||||
}
|
||||
if (l == ' ')
|
||||
|
@ -518,6 +518,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
|
||||
dma_chan_name(chan), err);
|
||||
else
|
||||
break;
|
||||
chan->private = NULL;
|
||||
chan = NULL;
|
||||
}
|
||||
}
|
||||
@ -536,6 +537,7 @@ void dma_release_channel(struct dma_chan *chan)
|
||||
WARN_ONCE(chan->client_count != 1,
|
||||
"chan reference count %d != 1\n", chan->client_count);
|
||||
dma_chan_put(chan);
|
||||
chan->private = NULL;
|
||||
mutex_unlock(&dma_list_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_release_channel);
|
||||
|
@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma_slave *dws = dwc->dws;
|
||||
struct dw_dma_slave *dws = chan->private;
|
||||
struct dw_desc *prev;
|
||||
struct dw_desc *first;
|
||||
u32 ctllo;
|
||||
@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
|
||||
cfghi = DWC_CFGH_FIFO_MODE;
|
||||
cfglo = 0;
|
||||
|
||||
dws = dwc->dws;
|
||||
dws = chan->private;
|
||||
if (dws) {
|
||||
/*
|
||||
* We need controller-specific data to set up slave
|
||||
@ -866,7 +866,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
|
||||
spin_lock_bh(&dwc->lock);
|
||||
list_splice_init(&dwc->free_list, &list);
|
||||
dwc->descs_allocated = 0;
|
||||
dwc->dws = NULL;
|
||||
|
||||
/* Disable interrupts */
|
||||
channel_clear_bit(dw, MASK.XFER, dwc->mask);
|
||||
|
@ -139,8 +139,6 @@ struct dw_dma_chan {
|
||||
struct list_head queue;
|
||||
struct list_head free_list;
|
||||
|
||||
struct dw_dma_slave *dws;
|
||||
|
||||
unsigned int descs_allocated;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* linux/drivers/firmware/memmap.c
|
||||
* Copyright (C) 2008 SUSE LINUX Products GmbH
|
||||
* by Bernhard Walle <bwalle@suse.de>
|
||||
* by Bernhard Walle <bernhard.walle@gmx.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License v2.0 as published by
|
||||
|
@ -80,18 +80,17 @@ config DRM_I915
|
||||
XFree86 4.4 and above. If unsure, build this and i830 as modules and
|
||||
the X server will load the correct one.
|
||||
|
||||
endchoice
|
||||
|
||||
config DRM_I915_KMS
|
||||
bool "Enable modesetting on intel by default"
|
||||
depends on DRM_I915
|
||||
help
|
||||
Choose this option if you want kernel modesetting enabled by default,
|
||||
and you have a new enough userspace to support this. Running old
|
||||
userspaces with this enabled will cause pain. Note that this causes
|
||||
the driver to bind to PCI devices, which precludes loading things
|
||||
like intelfb.
|
||||
Choose this option if you want kernel modesetting enabled by default,
|
||||
and you have a new enough userspace to support this. Running old
|
||||
userspaces with this enabled will cause pain. Note that this causes
|
||||
the driver to bind to PCI devices, which precludes loading things
|
||||
like intelfb.
|
||||
|
||||
endchoice
|
||||
|
||||
config DRM_MGA
|
||||
tristate "Matrox g200/g400"
|
||||
|
@ -1300,7 +1300,13 @@ static const struct hid_device_id hid_blacklist[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
||||
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
|
||||
@ -1605,6 +1611,7 @@ static const struct hid_device_id hid_ignore_list[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
|
||||
@ -1612,10 +1619,6 @@ static const struct hid_device_id hid_ignore_list[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
|
||||
@ -1626,8 +1629,6 @@ static const struct hid_device_id hid_ignore_list[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -348,6 +348,9 @@
|
||||
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
|
||||
#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
|
||||
|
||||
#define USB_VENDOR_ID_POWERCOM 0x0d9f
|
||||
#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_SAITEK 0x06a3
|
||||
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
|
||||
|
||||
|
@ -267,8 +267,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
|
||||
default:
|
||||
{
|
||||
struct hid_device *hid = dev->hid;
|
||||
if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
|
||||
return -EINVAL;
|
||||
if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
|
||||
int len;
|
||||
@ -277,8 +279,9 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
|
||||
len = strlen(hid->name) + 1;
|
||||
if (len > _IOC_SIZE(cmd))
|
||||
len = _IOC_SIZE(cmd);
|
||||
return copy_to_user(user_arg, hid->name, len) ?
|
||||
ret = copy_to_user(user_arg, hid->name, len) ?
|
||||
-EFAULT : len;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
|
||||
@ -288,12 +291,13 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
|
||||
len = strlen(hid->phys) + 1;
|
||||
if (len > _IOC_SIZE(cmd))
|
||||
len = _IOC_SIZE(cmd);
|
||||
return copy_to_user(user_arg, hid->phys, len) ?
|
||||
ret = copy_to_user(user_arg, hid->phys, len) ?
|
||||
-EFAULT : len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = -ENOTTY;
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
unlock_kernel();
|
||||
return ret;
|
||||
|
@ -1872,7 +1872,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
|
||||
|
||||
devid = superio_inw(sioaddr, SIO_REG_MANID);
|
||||
if (devid != SIO_FINTEK_ID) {
|
||||
printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
|
||||
pr_debug(DRVNAME ": Not a Fintek device\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1932,7 +1932,7 @@ static int __init f71882fg_device_add(unsigned short address,
|
||||
res.name = f71882fg_pdev->name;
|
||||
err = acpi_check_resource_conflict(&res);
|
||||
if (err)
|
||||
return err;
|
||||
goto exit_device_put;
|
||||
|
||||
err = platform_device_add_resources(f71882fg_pdev, &res, 1);
|
||||
if (err) {
|
||||
|
@ -166,6 +166,18 @@ static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3};
|
||||
}, \
|
||||
.driver_data = &lis3lv02d_axis_##_axis \
|
||||
}
|
||||
|
||||
#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \
|
||||
_class2, _name2, \
|
||||
_axis) { \
|
||||
.ident = _ident, \
|
||||
.callback = lis3lv02d_dmi_matched, \
|
||||
.matches = { \
|
||||
DMI_MATCH(DMI_##_class1, _name1), \
|
||||
DMI_MATCH(DMI_##_class2, _name2), \
|
||||
}, \
|
||||
.driver_data = &lis3lv02d_axis_##_axis \
|
||||
}
|
||||
static struct dmi_system_id lis3lv02d_dmi_ids[] = {
|
||||
/* product names are truncated to match all kinds of a same model */
|
||||
AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
|
||||
@ -179,6 +191,16 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
|
||||
AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
|
||||
AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
|
||||
AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted),
|
||||
/* Intel-based HP Pavilion dv5 */
|
||||
AXIS_DMI_MATCH2("HPDV5_I",
|
||||
PRODUCT_NAME, "HP Pavilion dv5",
|
||||
BOARD_NAME, "3603",
|
||||
x_inverted),
|
||||
/* AMD-based HP Pavilion dv5 */
|
||||
AXIS_DMI_MATCH2("HPDV5_A",
|
||||
PRODUCT_NAME, "HP Pavilion dv5",
|
||||
BOARD_NAME, "3600",
|
||||
y_inverted),
|
||||
{ NULL, }
|
||||
/* Laptop models without axis info (yet):
|
||||
* "NC6910" "HP Compaq 6910"
|
||||
@ -213,9 +235,49 @@ static struct delayed_led_classdev hpled_led = {
|
||||
.set_brightness = hpled_set,
|
||||
};
|
||||
|
||||
static acpi_status
|
||||
lis3lv02d_get_resource(struct acpi_resource *resource, void *context)
|
||||
{
|
||||
if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
|
||||
struct acpi_resource_extended_irq *irq;
|
||||
u32 *device_irq = context;
|
||||
|
||||
irq = &resource->data.extended_irq;
|
||||
*device_irq = irq->interrupts[0];
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static void lis3lv02d_enum_resources(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
lis3lv02d_get_resource, &adev.irq);
|
||||
if (ACPI_FAILURE(status))
|
||||
printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
|
||||
}
|
||||
|
||||
static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
|
||||
{
|
||||
u8 lo, hi;
|
||||
|
||||
adev.read(handle, reg - 1, &lo);
|
||||
adev.read(handle, reg, &hi);
|
||||
/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
|
||||
return (s16)((hi << 8) | lo);
|
||||
}
|
||||
|
||||
static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
|
||||
{
|
||||
s8 lo;
|
||||
adev.read(handle, reg, &lo);
|
||||
return lo;
|
||||
}
|
||||
|
||||
static int lis3lv02d_add(struct acpi_device *device)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (!device)
|
||||
@ -229,10 +291,22 @@ static int lis3lv02d_add(struct acpi_device *device)
|
||||
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
|
||||
device->driver_data = &adev;
|
||||
|
||||
lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
|
||||
if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
|
||||
lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
|
||||
switch (adev.whoami) {
|
||||
case LIS_DOUBLE_ID:
|
||||
printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
|
||||
adev.read_data = lis3lv02d_read_16;
|
||||
adev.mdps_max_val = 2048;
|
||||
break;
|
||||
case LIS_SINGLE_ID:
|
||||
printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
|
||||
adev.read_data = lis3lv02d_read_8;
|
||||
adev.mdps_max_val = 128;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
": Accelerometer chip not LIS3LV02D{L,Q}\n");
|
||||
": unknown sensor type 0x%X\n", adev.whoami);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If possible use a "standard" axes order */
|
||||
@ -247,6 +321,9 @@ static int lis3lv02d_add(struct acpi_device *device)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* obtain IRQ number of our device from ACPI */
|
||||
lis3lv02d_enum_resources(adev.device);
|
||||
|
||||
ret = lis3lv02d_init_device(&adev);
|
||||
if (ret) {
|
||||
flush_work(&hpled_led.work);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2007-2008 Yan Burman
|
||||
* Copyright (C) 2008 Eric Piel
|
||||
* Copyright (C) 2008 Pavel Machek
|
||||
* Copyright (C) 2008-2009 Pavel Machek
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -35,6 +35,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <asm/atomic.h>
|
||||
#include "lis3lv02d.h"
|
||||
@ -52,24 +53,14 @@
|
||||
* joystick.
|
||||
*/
|
||||
|
||||
/* Maximum value our axis may get for the input device (signed 12 bits) */
|
||||
#define MDPS_MAX_VAL 2048
|
||||
struct acpi_lis3lv02d adev = {
|
||||
.misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
|
||||
};
|
||||
|
||||
struct acpi_lis3lv02d adev;
|
||||
EXPORT_SYMBOL_GPL(adev);
|
||||
|
||||
static int lis3lv02d_add_fs(struct acpi_device *device);
|
||||
|
||||
static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
|
||||
{
|
||||
u8 lo, hi;
|
||||
|
||||
adev.read(handle, reg, &lo);
|
||||
adev.read(handle, reg + 1, &hi);
|
||||
/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
|
||||
return (s16)((hi << 8) | lo);
|
||||
}
|
||||
|
||||
/**
|
||||
* lis3lv02d_get_axis - For the given axis, give the value converted
|
||||
* @axis: 1,2,3 - can also be negative
|
||||
@ -98,9 +89,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
|
||||
{
|
||||
int position[3];
|
||||
|
||||
position[0] = lis3lv02d_read_16(handle, OUTX_L);
|
||||
position[1] = lis3lv02d_read_16(handle, OUTY_L);
|
||||
position[2] = lis3lv02d_read_16(handle, OUTZ_L);
|
||||
position[0] = adev.read_data(handle, OUTX);
|
||||
position[1] = adev.read_data(handle, OUTY);
|
||||
position[2] = adev.read_data(handle, OUTZ);
|
||||
|
||||
*x = lis3lv02d_get_axis(adev.ac.x, position);
|
||||
*y = lis3lv02d_get_axis(adev.ac.y, position);
|
||||
@ -110,26 +101,13 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
|
||||
void lis3lv02d_poweroff(acpi_handle handle)
|
||||
{
|
||||
adev.is_on = 0;
|
||||
/* disable X,Y,Z axis and power down */
|
||||
adev.write(handle, CTRL_REG1, 0x00);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
|
||||
|
||||
void lis3lv02d_poweron(acpi_handle handle)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
adev.is_on = 1;
|
||||
adev.init(handle);
|
||||
adev.write(handle, FF_WU_CFG, 0);
|
||||
/*
|
||||
* BDU: LSB and MSB values are not updated until both have been read.
|
||||
* So the value read will always be correct.
|
||||
* IEN: Interrupt for free-fall and DD, not for data-ready.
|
||||
*/
|
||||
adev.read(handle, CTRL_REG2, &val);
|
||||
val |= CTRL2_BDU | CTRL2_IEN;
|
||||
adev.write(handle, CTRL_REG2, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
|
||||
|
||||
@ -162,6 +140,140 @@ static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
|
||||
mutex_unlock(&dev->lock);
|
||||
}
|
||||
|
||||
static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
|
||||
{
|
||||
/*
|
||||
* Be careful: on some HP laptops the bios force DD when on battery and
|
||||
* the lid is closed. This leads to interrupts as soon as a little move
|
||||
* is done.
|
||||
*/
|
||||
atomic_inc(&adev.count);
|
||||
|
||||
wake_up_interruptible(&adev.misc_wait);
|
||||
kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (test_and_set_bit(0, &adev.misc_opened))
|
||||
return -EBUSY; /* already open */
|
||||
|
||||
atomic_set(&adev.count, 0);
|
||||
|
||||
/*
|
||||
* The sensor can generate interrupts for free-fall and direction
|
||||
* detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep
|
||||
* the things simple and _fast_ we activate it only for free-fall, so
|
||||
* no need to read register (very slow with ACPI). For the same reason,
|
||||
* we forbid shared interrupts.
|
||||
*
|
||||
* IRQF_TRIGGER_RISING seems pointless on HP laptops because the
|
||||
* io-apic is not configurable (and generates a warning) but I keep it
|
||||
* in case of support for other hardware.
|
||||
*/
|
||||
ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
|
||||
DRIVER_NAME, &adev);
|
||||
|
||||
if (ret) {
|
||||
clear_bit(0, &adev.misc_opened);
|
||||
printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
lis3lv02d_increase_use(&adev);
|
||||
printk("lis3: registered interrupt %d\n", adev.irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
fasync_helper(-1, file, 0, &adev.async_queue);
|
||||
lis3lv02d_decrease_use(&adev);
|
||||
free_irq(adev.irq, &adev);
|
||||
clear_bit(0, &adev.misc_opened); /* release the device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
u32 data;
|
||||
unsigned char byte_data;
|
||||
ssize_t retval = 1;
|
||||
|
||||
if (count < 1)
|
||||
return -EINVAL;
|
||||
|
||||
add_wait_queue(&adev.misc_wait, &wait);
|
||||
while (true) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
data = atomic_xchg(&adev.count, 0);
|
||||
if (data)
|
||||
break;
|
||||
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
retval = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
if (data < 255)
|
||||
byte_data = data;
|
||||
else
|
||||
byte_data = 255;
|
||||
|
||||
/* make sure we are not going into copy_to_user() with
|
||||
* TASK_INTERRUPTIBLE state */
|
||||
set_current_state(TASK_RUNNING);
|
||||
if (copy_to_user(buf, &byte_data, sizeof(byte_data)))
|
||||
retval = -EFAULT;
|
||||
|
||||
out:
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&adev.misc_wait, &wait);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
poll_wait(file, &adev.misc_wait, wait);
|
||||
if (atomic_read(&adev.count))
|
||||
return POLLIN | POLLRDNORM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
return fasync_helper(fd, file, on, &adev.async_queue);
|
||||
}
|
||||
|
||||
static const struct file_operations lis3lv02d_misc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.read = lis3lv02d_misc_read,
|
||||
.open = lis3lv02d_misc_open,
|
||||
.release = lis3lv02d_misc_release,
|
||||
.poll = lis3lv02d_misc_poll,
|
||||
.fasync = lis3lv02d_misc_fasync,
|
||||
};
|
||||
|
||||
static struct miscdevice lis3lv02d_misc_device = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "freefall",
|
||||
.fops = &lis3lv02d_misc_fops,
|
||||
};
|
||||
|
||||
/**
|
||||
* lis3lv02d_joystick_kthread - Kthread polling function
|
||||
* @data: unused - here to conform to threadfn prototype
|
||||
@ -203,7 +315,6 @@ static void lis3lv02d_joystick_close(struct input_dev *input)
|
||||
lis3lv02d_decrease_use(&adev);
|
||||
}
|
||||
|
||||
|
||||
static inline void lis3lv02d_calibrate_joystick(void)
|
||||
{
|
||||
lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
|
||||
@ -231,9 +342,9 @@ int lis3lv02d_joystick_enable(void)
|
||||
adev.idev->close = lis3lv02d_joystick_close;
|
||||
|
||||
set_bit(EV_ABS, adev.idev->evbit);
|
||||
input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
|
||||
input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
|
||||
input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
|
||||
input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
|
||||
input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
|
||||
input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
|
||||
|
||||
err = input_register_device(adev.idev);
|
||||
if (err) {
|
||||
@ -250,6 +361,7 @@ void lis3lv02d_joystick_disable(void)
|
||||
if (!adev.idev)
|
||||
return;
|
||||
|
||||
misc_deregister(&lis3lv02d_misc_device);
|
||||
input_unregister_device(adev.idev);
|
||||
adev.idev = NULL;
|
||||
}
|
||||
@ -268,6 +380,19 @@ int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
|
||||
if (lis3lv02d_joystick_enable())
|
||||
printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
|
||||
|
||||
printk("lis3_init_device: irq %d\n", dev->irq);
|
||||
|
||||
/* if we did not get an IRQ from ACPI - we have nothing more to do */
|
||||
if (!dev->irq) {
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
": No IRQ in ACPI. Disabling /dev/freefall\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printk("lis3: registering device\n");
|
||||
if (misc_register(&lis3lv02d_misc_device))
|
||||
printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
|
||||
out:
|
||||
lis3lv02d_decrease_use(dev);
|
||||
return 0;
|
||||
}
|
||||
@ -351,6 +476,6 @@ int lis3lv02d_remove_fs(void)
|
||||
EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
|
||||
|
||||
MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
|
||||
MODULE_AUTHOR("Yan Burman and Eric Piel");
|
||||
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -22,12 +22,15 @@
|
||||
/*
|
||||
* The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
|
||||
* be connected via SPI. There exists also several similar chips (such as LIS302DL or
|
||||
* LIS3L02DQ) but not in the HP laptops and they have slightly different registers.
|
||||
* LIS3L02DQ) and they have slightly different registers, but we can provide a
|
||||
* common interface for all of them.
|
||||
* They can also be connected via I²C.
|
||||
*/
|
||||
|
||||
#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */
|
||||
#define LIS302DL_ID 0x3B /* Also the LIS202DL! */
|
||||
/* 2-byte registers */
|
||||
#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */
|
||||
/* 1-byte registers */
|
||||
#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */
|
||||
|
||||
enum lis3lv02d_reg {
|
||||
WHO_AM_I = 0x0F,
|
||||
@ -44,10 +47,13 @@ enum lis3lv02d_reg {
|
||||
STATUS_REG = 0x27,
|
||||
OUTX_L = 0x28,
|
||||
OUTX_H = 0x29,
|
||||
OUTX = 0x29,
|
||||
OUTY_L = 0x2A,
|
||||
OUTY_H = 0x2B,
|
||||
OUTY = 0x2B,
|
||||
OUTZ_L = 0x2C,
|
||||
OUTZ_H = 0x2D,
|
||||
OUTZ = 0x2D,
|
||||
FF_WU_CFG = 0x30,
|
||||
FF_WU_SRC = 0x31,
|
||||
FF_WU_ACK = 0x32,
|
||||
@ -159,6 +165,10 @@ struct acpi_lis3lv02d {
|
||||
acpi_status (*write) (acpi_handle handle, int reg, u8 val);
|
||||
acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
|
||||
|
||||
u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
|
||||
s16 (*read_data) (acpi_handle handle, int reg);
|
||||
int mdps_max_val;
|
||||
|
||||
struct input_dev *idev; /* input device */
|
||||
struct task_struct *kthread; /* kthread for input */
|
||||
struct mutex lock;
|
||||
@ -170,6 +180,11 @@ struct acpi_lis3lv02d {
|
||||
unsigned char is_on; /* whether the device is on or off */
|
||||
unsigned char usage; /* usage counter */
|
||||
struct axis_conversion ac; /* hw -> logical axis */
|
||||
|
||||
u32 irq; /* IRQ number */
|
||||
struct fasync_struct *async_queue; /* queue for the misc device */
|
||||
wait_queue_head_t misc_wait; /* Wait queue for the misc device */
|
||||
unsigned long misc_opened; /* bit0: whether the device is open */
|
||||
};
|
||||
|
||||
int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
|
||||
|
@ -1262,7 +1262,7 @@ static int __init vt1211_device_add(unsigned short address)
|
||||
res.name = pdev->name;
|
||||
err = acpi_check_resource_conflict(&res);
|
||||
if (err)
|
||||
goto EXIT;
|
||||
goto EXIT_DEV_PUT;
|
||||
|
||||
err = platform_device_add_resources(pdev, &res, 1);
|
||||
if (err) {
|
||||
|
@ -1548,7 +1548,7 @@ static int __init sensors_w83627ehf_init(void)
|
||||
|
||||
err = acpi_check_resource_conflict(&res);
|
||||
if (err)
|
||||
goto exit;
|
||||
goto exit_device_put;
|
||||
|
||||
err = platform_device_add_resources(pdev, &res, 1);
|
||||
if (err) {
|
||||
|
@ -328,7 +328,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
|
||||
struct dpages old_pages = *dp;
|
||||
|
||||
if (sync)
|
||||
rw |= (1 << BIO_RW_SYNC);
|
||||
rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
|
||||
|
||||
/*
|
||||
* For multiple regions we need to be careful to rewind
|
||||
|
@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job)
|
||||
{
|
||||
int r;
|
||||
struct dm_io_request io_req = {
|
||||
.bi_rw = job->rw | (1 << BIO_RW_SYNC),
|
||||
.bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG),
|
||||
.mem.type = DM_IO_PAGE_LIST,
|
||||
.mem.ptr.pl = job->pages,
|
||||
.mem.offset = job->offset,
|
||||
|
@ -474,7 +474,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
|
||||
* causes ENOTSUPP, we allocate a spare bio...
|
||||
*/
|
||||
struct bio *bio = bio_alloc(GFP_NOIO, 1);
|
||||
int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
|
||||
int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG);
|
||||
|
||||
bio->bi_bdev = rdev->bdev;
|
||||
bio->bi_sector = sector;
|
||||
@ -531,7 +531,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size,
|
||||
struct completion event;
|
||||
int ret;
|
||||
|
||||
rw |= (1 << BIO_RW_SYNC);
|
||||
rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
|
||||
|
||||
bio->bi_bdev = bdev;
|
||||
bio->bi_sector = sector;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user