diff --git a/[refs] b/[refs]
index c135b8f24bbf..65eadee59765 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 76be97c1fc945db08aae1f1b746012662d643e97
+refs/heads/master: b6dd08652e2b70e73661c4975ae46398066c06f8
diff --git a/trunk/Documentation/DocBook/kernel-locking.tmpl b/trunk/Documentation/DocBook/kernel-locking.tmpl
index 0b1a3f97f285..084f6ad7b7a0 100644
--- a/trunk/Documentation/DocBook/kernel-locking.tmpl
+++ b/trunk/Documentation/DocBook/kernel-locking.tmpl
@@ -1922,12 +1922,9 @@ machines due to caching.
mutex_lock()
- There is a mutex_trylock() which does not
- sleep. Still, it must not be used inside interrupt context since
- its implementation is not safe for that.
+ There is a mutex_trylock() which can be
+ used inside interrupt context, as it will not sleep.
mutex_unlock() will also never sleep.
- It cannot be used in interrupt context either since a mutex
- must be released by the same task that acquired it.
diff --git a/trunk/Documentation/hwmon/f71882fg b/trunk/Documentation/hwmon/f71882fg
index a7952c2bd959..1a07fd674cd0 100644
--- a/trunk/Documentation/hwmon/f71882fg
+++ b/trunk/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
======================
Supported chips:
+ * Fintek F71808E
+ Prefix: 'f71808fg'
+ Addresses scanned: none, address read from Super I/O config space
+ Datasheet: Not public
* Fintek F71858FG
Prefix: 'f71858fg'
Addresses scanned: none, address read from Super I/O config space
diff --git a/trunk/Documentation/laptops/thinkpad-acpi.txt b/trunk/Documentation/laptops/thinkpad-acpi.txt
index 1565eefd6fd5..f6f80257addb 100644
--- a/trunk/Documentation/laptops/thinkpad-acpi.txt
+++ b/trunk/Documentation/laptops/thinkpad-acpi.txt
@@ -1024,10 +1024,6 @@ ThinkPad-specific interface. The driver will disable its native
backlight brightness control interface if it detects that the standard
ACPI interface is available in the ThinkPad.
-If you want to use the thinkpad-acpi backlight brightness control
-instead of the generic ACPI video backlight brightness control for some
-reason, you should use the acpi_backlight=vendor kernel parameter.
-
The brightness_enable module parameter can be used to control whether
the LCD brightness control feature will be enabled when available.
brightness_enable=0 forces it to be disabled. brightness_enable=1
diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt
index 302db5da49b3..568fa08e82e5 100644
--- a/trunk/Documentation/powerpc/booting-without-of.txt
+++ b/trunk/Documentation/powerpc/booting-without-of.txt
@@ -49,13 +49,40 @@ Table of Contents
f) MDIO on GPIOs
g) SPI busses
- VII - Specifying interrupt information for devices
+ VII - Marvell Discovery mv64[345]6x System Controller chips
+ 1) The /system-controller node
+ 2) Child nodes of /system-controller
+ a) Marvell Discovery MDIO bus
+ b) Marvell Discovery ethernet controller
+ c) Marvell Discovery PHY nodes
+ d) Marvell Discovery SDMA nodes
+ e) Marvell Discovery BRG nodes
+ f) Marvell Discovery CUNIT nodes
+ g) Marvell Discovery MPSCROUTING nodes
+ h) Marvell Discovery MPSCINTR nodes
+ i) Marvell Discovery MPSC nodes
+ j) Marvell Discovery Watch Dog Timer nodes
+ k) Marvell Discovery I2C nodes
+ l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
+ m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
+ n) Marvell Discovery GPP (General Purpose Pins) nodes
+ o) Marvell Discovery PCI host bridge node
+ p) Marvell Discovery CPU Error nodes
+ q) Marvell Discovery SRAM Controller nodes
+ r) Marvell Discovery PCI Error Handler nodes
+ s) Marvell Discovery Memory Controller nodes
+
+ VIII - Specifying interrupt information for devices
1) interrupts property
2) interrupt-parent property
3) OpenPIC Interrupt Controllers
4) ISA Interrupt Controllers
- VIII - Specifying device power management information (sleep property)
+ IX - Specifying GPIO information for devices
+ 1) gpios property
+ 2) gpio-controller nodes
+
+ X - Specifying device power management information (sleep property)
Appendix A - Sample SOC node for MPC8540
diff --git a/trunk/Documentation/powerpc/hvcs.txt b/trunk/Documentation/powerpc/hvcs.txt
index 6d8be3468d7d..f93462c5db25 100644
--- a/trunk/Documentation/powerpc/hvcs.txt
+++ b/trunk/Documentation/powerpc/hvcs.txt
@@ -560,7 +560,7 @@ The proper channel for reporting bugs is either through the Linux OS
distribution company that provided your OS or by posting issues to the
PowerPC development mailing list at:
-linuxppc-dev@lists.ozlabs.org
+linuxppc-dev@ozlabs.org
This request is to provide a documented and searchable public exchange
of the problems and solutions surrounding this driver for the benefit of
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 433f35385756..b5b8baa1d70e 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -456,7 +456,7 @@ F: drivers/infiniband/hw/amso1100/
AOA (Apple Onboard Audio) ALSA DRIVER
M: Johannes Berg
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: sound/aoa/
@@ -1472,8 +1472,8 @@ F: include/linux/can/platform/
CELL BROADBAND ENGINE ARCHITECTURE
M: Arnd Bergmann
-L: linuxppc-dev@lists.ozlabs.org
-L: cbe-oss-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
+L: cbe-oss-dev@ozlabs.org
W: http://www.ibm.com/developerworks/power/cell/
S: Supported
F: arch/powerpc/include/asm/cell*.h
@@ -2371,13 +2371,13 @@ F: include/linux/fb.h
FREESCALE DMA DRIVER
M: Li Yang
M: Zhang Wei
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: drivers/dma/fsldma.*
FREESCALE I2C CPM DRIVER
M: Jochen Friedrich
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-cpm.c
@@ -2393,7 +2393,7 @@ F: drivers/video/imxfb.c
FREESCALE SOC FS_ENET DRIVER
M: Pantelis Antoniou
M: Vitaly Bordug
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/fs_enet/
@@ -2401,7 +2401,7 @@ F: include/linux/fs_enet_pd.h
FREESCALE QUICC ENGINE LIBRARY
M: Timur Tabi
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Supported
F: arch/powerpc/sysdev/qe_lib/
F: arch/powerpc/include/asm/*qe.h
@@ -2409,27 +2409,27 @@ F: arch/powerpc/include/asm/*qe.h
FREESCALE USB PERIPHERAL DRIVERS
M: Li Yang
L: linux-usb@vger.kernel.org
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: drivers/usb/gadget/fsl*
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
M: Li Yang
L: netdev@vger.kernel.org
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: drivers/net/ucc_geth*
FREESCALE QUICC ENGINE UCC UART DRIVER
M: Timur Tabi
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Supported
F: drivers/serial/ucc_uart.c
FREESCALE SOC SOUND DRIVERS
M: Timur Tabi
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Supported
F: sound/soc/fsl/fsl*
F: sound/soc/fsl/mpc8610_hpcd.c
@@ -2564,7 +2564,7 @@ F: mm/memory-failure.c
F: mm/hwpoison-inject.c
HYPERVISOR VIRTUAL CONSOLE DRIVER
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Odd Fixes
F: drivers/char/hvc_*
@@ -3476,7 +3476,7 @@ F: drivers/usb/misc/legousbtower.c
LGUEST
M: Rusty Russell
-L: lguest@lists.ozlabs.org
+L: lguest@ozlabs.org
W: http://lguest.ozlabs.org/
S: Maintained
F: Documentation/lguest/
@@ -3495,7 +3495,7 @@ LINUX FOR POWERPC (32-BIT AND 64-BIT)
M: Benjamin Herrenschmidt
M: Paul Mackerras
W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
S: Supported
@@ -3505,14 +3505,14 @@ F: arch/powerpc/
LINUX FOR POWER MACINTOSH
M: Benjamin Herrenschmidt
W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: arch/powerpc/platforms/powermac/
F: drivers/macintosh/
LINUX FOR POWERPC EMBEDDED MPC5XXX
M: Grant Likely
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
T: git git://git.secretlab.ca/git/linux-2.6.git
S: Maintained
F: arch/powerpc/platforms/512x/
@@ -3522,7 +3522,7 @@ LINUX FOR POWERPC EMBEDDED PPC4XX
M: Josh Boyer
M: Matt Porter
W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git
S: Maintained
F: arch/powerpc/platforms/40x/
@@ -3531,7 +3531,7 @@ F: arch/powerpc/platforms/44x/
LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
M: Grant Likely
W: http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
T: git git://git.secretlab.ca/git/linux-2.6.git
S: Maintained
F: arch/powerpc/*/*virtex*
@@ -3541,20 +3541,20 @@ LINUX FOR POWERPC EMBEDDED PPC8XX
M: Vitaly Bordug
M: Marcelo Tosatti
W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: arch/powerpc/platforms/8xx/
LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
M: Kumar Gala
W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: arch/powerpc/platforms/83xx/
LINUX FOR POWERPC PA SEMI PWRFICIENT
M: Olof Johansson
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Maintained
F: arch/powerpc/platforms/pasemi/
F: drivers/*/*pasemi*
@@ -4601,14 +4601,14 @@ F: drivers/ata/sata_promise.*
PS3 NETWORK SUPPORT
M: Geoff Levand
L: netdev@vger.kernel.org
-L: cbe-oss-dev@lists.ozlabs.org
+L: cbe-oss-dev@ozlabs.org
S: Maintained
F: drivers/net/ps3_gelic_net.*
PS3 PLATFORM SUPPORT
M: Geoff Levand
-L: linuxppc-dev@lists.ozlabs.org
-L: cbe-oss-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
+L: cbe-oss-dev@ozlabs.org
S: Maintained
F: arch/powerpc/boot/ps3*
F: arch/powerpc/include/asm/lv1call.h
@@ -4622,7 +4622,7 @@ F: sound/ppc/snd_ps3*
PS3VRAM DRIVER
M: Jim Paris
-L: cbe-oss-dev@lists.ozlabs.org
+L: cbe-oss-dev@ozlabs.org
S: Maintained
F: drivers/block/ps3vram.c
@@ -5068,7 +5068,7 @@ F: drivers/mmc/host/sdhci.*
SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
M: Anton Vorontsov
-L: linuxppc-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
L: linux-mmc@vger.kernel.org
S: Maintained
F: drivers/mmc/host/sdhci-of.*
@@ -5485,8 +5485,8 @@ F: drivers/net/spider_net*
SPU FILE SYSTEM
M: Jeremy Kerr
-L: linuxppc-dev@lists.ozlabs.org
-L: cbe-oss-dev@lists.ozlabs.org
+L: linuxppc-dev@ozlabs.org
+L: cbe-oss-dev@ozlabs.org
W: http://www.ibm.com/developerworks/power/cell/
S: Supported
F: Documentation/filesystems/spufs.txt
diff --git a/trunk/Makefile b/trunk/Makefile
index 2c0299f18d71..f3bdff8c8d78 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 36
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc1
NAME = Sheep on Meth
# *DOCUMENTATION*
diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c
index 842dba308eab..88e608aebc8c 100644
--- a/trunk/arch/alpha/kernel/process.c
+++ b/trunk/arch/alpha/kernel/process.c
@@ -387,9 +387,8 @@ EXPORT_SYMBOL(dump_elf_task_fp);
* sys_execve() executes a new program.
*/
asmlinkage int
-do_sys_execve(const char __user *ufilename,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
+do_sys_execve(const char __user *ufilename, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
{
int error;
char *filename;
diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile
index 59c1ce858fc8..99b8200138d2 100644
--- a/trunk/arch/arm/Makefile
+++ b/trunk/arch/arm/Makefile
@@ -21,9 +21,6 @@ GZFLAGS :=-9
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
KBUILD_CFLAGS +=$(call cc-option,-marm,)
-# Never generate .eh_frame
-KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
-
# Do not use arch/arm/defconfig - it's always outdated.
# Select a platform tht is kept up-to-date
KBUILD_DEFCONFIG := versatile_defconfig
diff --git a/trunk/arch/arm/include/asm/ptrace.h b/trunk/arch/arm/include/asm/ptrace.h
index 7ce15eb15f72..c974be8913a7 100644
--- a/trunk/arch/arm/include/asm/ptrace.h
+++ b/trunk/arch/arm/include/asm/ptrace.h
@@ -158,24 +158,15 @@ struct pt_regs {
*/
static inline int valid_user_regs(struct pt_regs *regs)
{
- unsigned long mode = regs->ARM_cpsr & MODE_MASK;
-
- /*
- * Always clear the F (FIQ) and A (delayed abort) bits
- */
- regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
-
- if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
- if (mode == USR_MODE)
- return 1;
- if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
- return 1;
+ if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) {
+ regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
+ return 1;
}
/*
* Force CPSR to something logical...
*/
- regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
+ regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT;
if (!(elf_hwcap & HWCAP_26BIT))
regs->ARM_cpsr |= USR_MODE;
diff --git a/trunk/arch/arm/include/asm/unistd.h b/trunk/arch/arm/include/asm/unistd.h
index d02cfb683487..dd2bf53000fe 100644
--- a/trunk/arch/arm/include/asm/unistd.h
+++ b/trunk/arch/arm/include/asm/unistd.h
@@ -392,7 +392,6 @@
#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
-#define __NR_accept4 (__NR_SYSCALL_BASE+366)
/*
* The following SWIs are ARM private.
diff --git a/trunk/arch/arm/kernel/calls.S b/trunk/arch/arm/kernel/calls.S
index afeb71fa72cb..37ae301cc47c 100644
--- a/trunk/arch/arm/kernel/calls.S
+++ b/trunk/arch/arm/kernel/calls.S
@@ -375,7 +375,6 @@
CALL(sys_rt_tgsigqueueinfo)
CALL(sys_perf_event_open)
/* 365 */ CALL(sys_recvmmsg)
- CALL(sys_accept4)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/trunk/arch/arm/kernel/kgdb.c b/trunk/arch/arm/kernel/kgdb.c
index d6e8b4d2e60d..778c2f7024ff 100644
--- a/trunk/arch/arm/kernel/kgdb.c
+++ b/trunk/arch/arm/kernel/kgdb.c
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
return;
/* Initialize to zero */
- for (regno = 0; regno < DBG_MAX_REG_NUM; regno++)
+ for (regno = 0; regno < GDB_MAX_REGS; regno++)
gdb_regs[regno] = 0;
/* Otherwise, we have only some registers from switch_to() */
diff --git a/trunk/arch/arm/kernel/sys_arm.c b/trunk/arch/arm/kernel/sys_arm.c
index 62e7c61d0342..5b7c541a4c63 100644
--- a/trunk/arch/arm/kernel/sys_arm.c
+++ b/trunk/arch/arm/kernel/sys_arm.c
@@ -62,9 +62,8 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
/* sys_execve() executes a new program.
* This is called indirectly via a small wrapper
*/
-asmlinkage int sys_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
+asmlinkage int sys_execve(const char __user *filenamei, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
{
int error;
char * filename;
@@ -79,17 +78,14 @@ asmlinkage int sys_execve(const char __user *filenamei,
return error;
}
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
memset(®s, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, ®s);
+ ret = do_execve(filename, (char __user * __user *)argv,
+ (char __user * __user *)envp, ®s);
if (ret < 0)
goto out;
diff --git a/trunk/arch/arm/plat-samsung/dev-hsmmc.c b/trunk/arch/arm/plat-samsung/dev-hsmmc.c
index 9d2be0941410..b0f93f11e281 100644
--- a/trunk/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/trunk/arch/arm/plat-samsung/dev-hsmmc.c
@@ -70,6 +70,4 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
- if (pd->host_caps)
- set->host_caps = pd->host_caps;
}
diff --git a/trunk/arch/arm/plat-samsung/dev-hsmmc1.c b/trunk/arch/arm/plat-samsung/dev-hsmmc1.c
index a6c8295840af..1504fd802865 100644
--- a/trunk/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/trunk/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -70,6 +70,4 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
- if (pd->host_caps)
- set->host_caps = pd->host_caps;
}
diff --git a/trunk/arch/arm/plat-samsung/dev-hsmmc2.c b/trunk/arch/arm/plat-samsung/dev-hsmmc2.c
index cb0d7143381a..b28ef173444d 100644
--- a/trunk/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/trunk/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -71,6 +71,4 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
- if (pd->host_caps)
- set->host_caps = pd->host_caps;
}
diff --git a/trunk/arch/avr32/kernel/process.c b/trunk/arch/avr32/kernel/process.c
index 9c46aaad11ce..e5daddff397d 100644
--- a/trunk/arch/avr32/kernel/process.c
+++ b/trunk/arch/avr32/kernel/process.c
@@ -384,9 +384,8 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
}
asmlinkage int sys_execve(const char __user *ufilename,
- const char __user *const __user *uargv,
- const char __user *const __user *uenvp,
- struct pt_regs *regs)
+ char __user *__user *uargv,
+ char __user *__user *uenvp, struct pt_regs *regs)
{
int error;
char *filename;
diff --git a/trunk/arch/avr32/kernel/sys_avr32.c b/trunk/arch/avr32/kernel/sys_avr32.c
index 62635a09ae3e..459349b5ed5a 100644
--- a/trunk/arch/avr32/kernel/sys_avr32.c
+++ b/trunk/arch/avr32/kernel/sys_avr32.c
@@ -7,9 +7,7 @@
*/
#include
-int kernel_execve(const char *file,
- const char *const *argv,
- const char *const *envp)
+int kernel_execve(const char *file, char **argv, char **envp)
{
register long scno asm("r8") = __NR_execve;
register long sc1 asm("r12") = (long)file;
diff --git a/trunk/arch/blackfin/kernel/process.c b/trunk/arch/blackfin/kernel/process.c
index 01f98cb964d2..a566f61c002a 100644
--- a/trunk/arch/blackfin/kernel/process.c
+++ b/trunk/arch/blackfin/kernel/process.c
@@ -209,9 +209,7 @@ copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
+asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
{
int error;
char *filename;
diff --git a/trunk/arch/cris/arch-v10/kernel/process.c b/trunk/arch/cris/arch-v10/kernel/process.c
index 9a57db6907f5..93f0f64b1326 100644
--- a/trunk/arch/cris/arch-v10/kernel/process.c
+++ b/trunk/arch/cris/arch-v10/kernel/process.c
@@ -204,9 +204,7 @@ asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char *fname,
- const char *const *argv,
- const char *const *envp,
+asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
long r13, long mof, long srp,
struct pt_regs *regs)
{
diff --git a/trunk/arch/cris/arch-v32/kernel/process.c b/trunk/arch/cris/arch-v32/kernel/process.c
index 562f84718906..2661a9529d70 100644
--- a/trunk/arch/cris/arch-v32/kernel/process.c
+++ b/trunk/arch/cris/arch-v32/kernel/process.c
@@ -218,10 +218,8 @@ sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
/* sys_execve() executes a new program. */
asmlinkage int
-sys_execve(const char *fname,
- const char *const *argv,
- const char *const *envp, long r13, long mof, long srp,
- struct pt_regs *regs)
+sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
+ struct pt_regs *regs)
{
int error;
char *filename;
diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c
index 2b63b0191f52..428931cf2f0c 100644
--- a/trunk/arch/frv/kernel/process.c
+++ b/trunk/arch/frv/kernel/process.c
@@ -250,9 +250,8 @@ int copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
+asmlinkage int sys_execve(const char __user *name, char __user * __user *argv,
+ char __user * __user *envp)
{
int error;
char * filename;
diff --git a/trunk/arch/h8300/kernel/process.c b/trunk/arch/h8300/kernel/process.c
index 97478138e361..8b7b78d77d5c 100644
--- a/trunk/arch/h8300/kernel/process.c
+++ b/trunk/arch/h8300/kernel/process.c
@@ -212,10 +212,7 @@ int copy_thread(unsigned long clone_flags,
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char *name,
- const char *const *argv,
- const char *const *envp,
- int dummy, ...)
+asmlinkage int sys_execve(const char *name, char **argv, char **envp,int dummy,...)
{
int error;
char * filename;
diff --git a/trunk/arch/h8300/kernel/sys_h8300.c b/trunk/arch/h8300/kernel/sys_h8300.c
index dc1ac0243b78..f9b3f44da69f 100644
--- a/trunk/arch/h8300/kernel/sys_h8300.c
+++ b/trunk/arch/h8300/kernel/sys_h8300.c
@@ -51,9 +51,7 @@ asmlinkage void syscall_print(void *dummy,...)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register long res __asm__("er0");
register char *const *_c __asm__("er3") = envp;
diff --git a/trunk/arch/ia64/include/asm/unistd.h b/trunk/arch/ia64/include/asm/unistd.h
index 954d398a54b4..87f1bd1efc82 100644
--- a/trunk/arch/ia64/include/asm/unistd.h
+++ b/trunk/arch/ia64/include/asm/unistd.h
@@ -356,6 +356,8 @@ asmlinkage unsigned long sys_mmap2(
int fd, long pgoff);
struct pt_regs;
struct sigaction;
+long sys_execve(const char __user *filename, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs);
asmlinkage long sys_ia64_pipe(void);
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c
index 16f1c7b04c69..a879c03b7f1c 100644
--- a/trunk/arch/ia64/kernel/process.c
+++ b/trunk/arch/ia64/kernel/process.c
@@ -633,9 +633,7 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
}
long
-sys_execve (const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
+sys_execve (const char __user *filename, char __user * __user *argv, char __user * __user *envp,
struct pt_regs *regs)
{
char *fname;
diff --git a/trunk/arch/m32r/kernel/process.c b/trunk/arch/m32r/kernel/process.c
index 422bea9f1dbc..8665a4d868ec 100644
--- a/trunk/arch/m32r/kernel/process.c
+++ b/trunk/arch/m32r/kernel/process.c
@@ -289,8 +289,8 @@ asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2,
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *ufilename,
- const char __user *const __user *uargv,
- const char __user *const __user *uenvp,
+ char __user * __user *uargv,
+ char __user * __user *uenvp,
unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, struct pt_regs regs)
{
diff --git a/trunk/arch/m32r/kernel/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c
index d841fb6cc703..0a00f467edfa 100644
--- a/trunk/arch/m32r/kernel/sys_m32r.c
+++ b/trunk/arch/m32r/kernel/sys_m32r.c
@@ -93,9 +93,7 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register long __scno __asm__ ("r7") = __NR_execve;
register long __arg3 __asm__ ("r2") = (long)(envp);
diff --git a/trunk/arch/m68k/include/asm/ide.h b/trunk/arch/m68k/include/asm/ide.h
index 492fee8a1ab2..3958726664ba 100644
--- a/trunk/arch/m68k/include/asm/ide.h
+++ b/trunk/arch/m68k/include/asm/ide.h
@@ -1,4 +1,6 @@
/*
+ * linux/include/asm-m68k/ide.h
+ *
* Copyright (C) 1994-1996 Linus Torvalds & authors
*/
@@ -32,8 +34,6 @@
#include
#include
-#ifdef CONFIG_MMU
-
/*
* Get rid of defs from io.h - ide has its private and conflicting versions
* Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
@@ -53,14 +53,5 @@
#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
-#else
-
-#define __ide_mm_insw(port, addr, n) io_insw((unsigned int)port, addr, n)
-#define __ide_mm_insl(port, addr, n) io_insl((unsigned int)port, addr, n)
-#define __ide_mm_outsw(port, addr, n) io_outsw((unsigned int)port, addr, n)
-#define __ide_mm_outsl(port, addr, n) io_outsl((unsigned int)port, addr, n)
-
-#endif /* CONFIG_MMU */
-
#endif /* __KERNEL__ */
#endif /* _M68K_IDE_H */
diff --git a/trunk/arch/m68k/kernel/process.c b/trunk/arch/m68k/kernel/process.c
index 18732ab23292..221d0b71ce39 100644
--- a/trunk/arch/m68k/kernel/process.c
+++ b/trunk/arch/m68k/kernel/process.c
@@ -315,9 +315,7 @@ EXPORT_SYMBOL(dump_fpu);
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
+asmlinkage int sys_execve(const char __user *name, char __user * __user *argv, char __user * __user *envp)
{
int error;
char * filename;
diff --git a/trunk/arch/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c
index 2f431ece7b5f..77896692eb0a 100644
--- a/trunk/arch/m68k/kernel/sys_m68k.c
+++ b/trunk/arch/m68k/kernel/sys_m68k.c
@@ -459,9 +459,7 @@ asmlinkage int sys_getpagesize(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register long __res asm ("%d0") = __NR_execve;
register long __a asm ("%d1") = (long)(filename);
diff --git a/trunk/arch/m68knommu/kernel/process.c b/trunk/arch/m68knommu/kernel/process.c
index 6d3390590e5b..6350f68cd026 100644
--- a/trunk/arch/m68knommu/kernel/process.c
+++ b/trunk/arch/m68knommu/kernel/process.c
@@ -316,14 +316,14 @@ void dump(struct pt_regs *fp)
fp->d0, fp->d1, fp->d2, fp->d3);
printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
fp->d4, fp->d5, fp->a0, fp->a1);
- printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %p\n",
- (unsigned int) rdusp(), fp);
+ printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %08x\n",
+ (unsigned int) rdusp(), (unsigned int) fp);
printk(KERN_EMERG "\nCODE:");
tp = ((unsigned char *) fp->pc) - 0x20;
for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
printk(KERN_EMERG "\n");
@@ -332,7 +332,7 @@ void dump(struct pt_regs *fp)
tp = ((unsigned char *) fp) - 0x40;
for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
printk(KERN_EMERG "\n");
@@ -341,7 +341,7 @@ void dump(struct pt_regs *fp)
tp = (unsigned char *) (rdusp() - 0x10);
for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
printk(KERN_EMERG "\n");
@@ -350,9 +350,7 @@ void dump(struct pt_regs *fp)
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char *name,
- const char *const *argv,
- const char *const *envp)
+asmlinkage int sys_execve(const char *name, char **argv, char **envp)
{
int error;
char * filename;
diff --git a/trunk/arch/m68knommu/kernel/sys_m68k.c b/trunk/arch/m68knommu/kernel/sys_m68k.c
index 68488ae47f0a..d65e9c4c930c 100644
--- a/trunk/arch/m68knommu/kernel/sys_m68k.c
+++ b/trunk/arch/m68knommu/kernel/sys_m68k.c
@@ -44,9 +44,7 @@ asmlinkage int sys_getpagesize(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register long __res asm ("%d0") = __NR_execve;
register long __a asm ("%d1") = (long)(filename);
diff --git a/trunk/arch/microblaze/kernel/prom_parse.c b/trunk/arch/microblaze/kernel/prom_parse.c
index 99d9b61cccb5..d33ba17601fa 100644
--- a/trunk/arch/microblaze/kernel/prom_parse.c
+++ b/trunk/arch/microblaze/kernel/prom_parse.c
@@ -73,7 +73,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
/* We can only get here if we hit a P2P bridge with no node,
* let's do standard swizzling and try again
*/
- lspec = pci_swizzle_interrupt_pin(pdev, lspec);
+ lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
pdev = ppdev;
}
diff --git a/trunk/arch/microblaze/kernel/sys_microblaze.c b/trunk/arch/microblaze/kernel/sys_microblaze.c
index 2250fe9d269b..6abab6ebedbe 100644
--- a/trunk/arch/microblaze/kernel/sys_microblaze.c
+++ b/trunk/arch/microblaze/kernel/sys_microblaze.c
@@ -47,10 +47,8 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs
return do_fork(flags, stack, regs, 0, NULL, NULL);
}
-asmlinkage long microblaze_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs)
+asmlinkage long microblaze_execve(const char __user *filenamei, char __user *__user *argv,
+ char __user *__user *envp, struct pt_regs *regs)
{
int error;
char *filename;
@@ -79,9 +77,7 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register const char *__a __asm__("r5") = filename;
register const void *__b __asm__("r6") = argv;
diff --git a/trunk/arch/microblaze/pci/pci-common.c b/trunk/arch/microblaze/pci/pci-common.c
index 55ef532f32be..23be25fec4d6 100644
--- a/trunk/arch/microblaze/pci/pci-common.c
+++ b/trunk/arch/microblaze/pci/pci-common.c
@@ -27,11 +27,10 @@
#include
#include
#include
-#include
-#include
#include
#include
+#include
#include
#include
@@ -1078,7 +1077,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
struct dev_archdata *sd = &dev->dev.archdata;
/* Setup OF node pointer in archdata */
- dev->dev.of_node = pci_device_to_OF_node(dev);
+ sd->of_node = pci_device_to_OF_node(dev);
/* Fixup NUMA node as it may not be setup yet by the generic
* code and is needed by the DMA init
diff --git a/trunk/arch/microblaze/pci/xilinx_pci.c b/trunk/arch/microblaze/pci/xilinx_pci.c
index 0687a42a5bd4..7869a41b0f94 100644
--- a/trunk/arch/microblaze/pci/xilinx_pci.c
+++ b/trunk/arch/microblaze/pci/xilinx_pci.c
@@ -16,7 +16,6 @@
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c
index 1dc6edff45e0..bddce0bca195 100644
--- a/trunk/arch/mips/kernel/syscall.c
+++ b/trunk/arch/mips/kernel/syscall.c
@@ -258,10 +258,8 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
- (const char __user *const __user *) (long)regs.regs[5],
- (const char __user *const __user *) (long)regs.regs[6],
- ®s);
+ error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
+ (char __user *__user *) (long)regs.regs[6], ®s);
putname(filename);
out:
@@ -438,9 +436,7 @@ asmlinkage void bad_stack(void)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register unsigned long __a0 asm("$4") = (unsigned long) filename;
register unsigned long __a1 asm("$5") = (unsigned long) argv;
diff --git a/trunk/arch/mn10300/kernel/process.c b/trunk/arch/mn10300/kernel/process.c
index f48373e2bc1c..762eb325b949 100644
--- a/trunk/arch/mn10300/kernel/process.c
+++ b/trunk/arch/mn10300/kernel/process.c
@@ -269,8 +269,8 @@ asmlinkage long sys_vfork(void)
}
asmlinkage long sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
+ char __user * __user *argv,
+ char __user * __user *envp)
{
char *filename;
int error;
diff --git a/trunk/arch/parisc/hpux/fs.c b/trunk/arch/parisc/hpux/fs.c
index 0dc8543acb4f..1444875a7611 100644
--- a/trunk/arch/parisc/hpux/fs.c
+++ b/trunk/arch/parisc/hpux/fs.c
@@ -41,10 +41,8 @@ int hpux_execve(struct pt_regs *regs)
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
- (const char __user *const __user *) regs->gr[25],
- (const char __user *const __user *) regs->gr[24],
- regs);
+ error = do_execve(filename, (char __user * __user *) regs->gr[25],
+ (char __user * __user *) regs->gr[24], regs);
putname(filename);
diff --git a/trunk/arch/parisc/kernel/process.c b/trunk/arch/parisc/kernel/process.c
index 4b4b9181a1a0..76332dadc6e9 100644
--- a/trunk/arch/parisc/kernel/process.c
+++ b/trunk/arch/parisc/kernel/process.c
@@ -348,22 +348,17 @@ asmlinkage int sys_execve(struct pt_regs *regs)
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
- (const char __user *const __user *) regs->gr[25],
- (const char __user *const __user *) regs->gr[24],
- regs);
+ error = do_execve(filename, (char __user * __user *) regs->gr[25],
+ (char __user * __user *) regs->gr[24], regs);
putname(filename);
out:
return error;
}
-extern int __execve(const char *filename,
- const char *const argv[],
- const char *const envp[], struct task_struct *task);
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+extern int __execve(const char *filename, char *const argv[],
+ char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
return __execve(filename, argv, envp, current);
}
diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c
index 91356ffda2ca..feacfb789686 100644
--- a/trunk/arch/powerpc/kernel/process.c
+++ b/trunk/arch/powerpc/kernel/process.c
@@ -1034,9 +1034,8 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
flush_spe_to_thread(current);
- error = do_execve(filename,
- (const char __user *const __user *) a1,
- (const char __user *const __user *) a2, regs);
+ error = do_execve(filename, (char __user * __user *) a1,
+ (char __user * __user *) a2, regs);
putname(filename);
out:
return error;
diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c
index d3a2d1c6438e..7eafaf2662b9 100644
--- a/trunk/arch/s390/kernel/process.c
+++ b/trunk/arch/s390/kernel/process.c
@@ -267,9 +267,8 @@ asmlinkage void execve_tail(void)
/*
* sys_execve() executes a new program.
*/
-SYSCALL_DEFINE3(execve, const char __user *, name,
- const char __user *const __user *, argv,
- const char __user *const __user *, envp)
+SYSCALL_DEFINE3(execve, const char __user *, name, char __user * __user *, argv,
+ char __user * __user *, envp)
{
struct pt_regs *regs = task_pt_regs(current);
char *filename;
diff --git a/trunk/arch/score/kernel/sys_score.c b/trunk/arch/score/kernel/sys_score.c
index e478bf9a7e91..651096ff8db4 100644
--- a/trunk/arch/score/kernel/sys_score.c
+++ b/trunk/arch/score/kernel/sys_score.c
@@ -99,10 +99,8 @@ score_execve(struct pt_regs *regs)
if (IS_ERR(filename))
return error;
- error = do_execve(filename,
- (const char __user *const __user *)regs->regs[5],
- (const char __user *const __user *)regs->regs[6],
- regs);
+ error = do_execve(filename, (char __user *__user*)regs->regs[5],
+ (char __user *__user *) regs->regs[6], regs);
putname(filename);
return error;
@@ -112,9 +110,7 @@ score_execve(struct pt_regs *regs)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register unsigned long __r4 asm("r4") = (unsigned long) filename;
register unsigned long __r5 asm("r5") = (unsigned long) argv;
diff --git a/trunk/arch/sh/kernel/process_32.c b/trunk/arch/sh/kernel/process_32.c
index 762a13984bbd..052981972ae6 100644
--- a/trunk/arch/sh/kernel/process_32.c
+++ b/trunk/arch/sh/kernel/process_32.c
@@ -296,10 +296,9 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
/*
* sys_execve() executes a new program.
*/
-asmlinkage int sys_execve(const char __user *ufilename,
- const char __user *const __user *uargv,
- const char __user *const __user *uenvp,
- unsigned long r7, struct pt_regs __regs)
+asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
+ char __user * __user *uenvp, unsigned long r7,
+ struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int error;
diff --git a/trunk/arch/sh/kernel/process_64.c b/trunk/arch/sh/kernel/process_64.c
index 210c1cabcb7f..68d128d651b3 100644
--- a/trunk/arch/sh/kernel/process_64.c
+++ b/trunk/arch/sh/kernel/process_64.c
@@ -497,8 +497,8 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
goto out;
error = do_execve(filename,
- (const char __user *const __user *)uargv,
- (const char __user *const __user *)uenvp,
+ (char __user * __user *)uargv,
+ (char __user * __user *)uenvp,
pregs);
putname(filename);
out:
diff --git a/trunk/arch/sh/kernel/sys_sh32.c b/trunk/arch/sh/kernel/sys_sh32.c
index f56b6fe5c5d0..eb68bfdd86e6 100644
--- a/trunk/arch/sh/kernel/sys_sh32.c
+++ b/trunk/arch/sh/kernel/sys_sh32.c
@@ -71,9 +71,7 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register long __sc0 __asm__ ("r3") = __NR_execve;
register long __sc4 __asm__ ("r4") = (long) filename;
diff --git a/trunk/arch/sh/kernel/sys_sh64.c b/trunk/arch/sh/kernel/sys_sh64.c
index c5a38c4bf410..287235768bc5 100644
--- a/trunk/arch/sh/kernel/sys_sh64.c
+++ b/trunk/arch/sh/kernel/sys_sh64.c
@@ -33,9 +33,7 @@
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h
index f0c74227c737..2050ca02c423 100644
--- a/trunk/arch/sparc/include/asm/atomic_64.h
+++ b/trunk/arch/sparc/include/asm/atomic_64.h
@@ -25,9 +25,9 @@ extern void atomic_sub(int, atomic_t *);
extern void atomic64_sub(int, atomic64_t *);
extern int atomic_add_ret(int, atomic_t *);
-extern long atomic64_add_ret(int, atomic64_t *);
+extern int atomic64_add_ret(int, atomic64_t *);
extern int atomic_sub_ret(int, atomic_t *);
-extern long atomic64_sub_ret(int, atomic64_t *);
+extern int atomic64_sub_ret(int, atomic64_t *);
#define atomic_dec_return(v) atomic_sub_ret(1, v)
#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
@@ -91,7 +91,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
-static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
+static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
{
long c, old;
c = atomic64_read(v);
diff --git a/trunk/arch/sparc/include/asm/fb.h b/trunk/arch/sparc/include/asm/fb.h
index 2173432ad7f7..e834880be204 100644
--- a/trunk/arch/sparc/include/asm/fb.h
+++ b/trunk/arch/sparc/include/asm/fb.h
@@ -1,6 +1,5 @@
#ifndef _SPARC_FB_H_
#define _SPARC_FB_H_
-#include
#include
#include
#include
@@ -19,9 +18,6 @@ static inline int fb_is_primary_device(struct fb_info *info)
struct device *dev = info->device;
struct device_node *node;
- if (console_set_on_cmdline)
- return 0;
-
node = dev->of_node;
if (node &&
node == of_console_device)
diff --git a/trunk/arch/sparc/include/asm/rwsem-const.h b/trunk/arch/sparc/include/asm/rwsem-const.h
index e4c61a18bb28..a303c9d64d84 100644
--- a/trunk/arch/sparc/include/asm/rwsem-const.h
+++ b/trunk/arch/sparc/include/asm/rwsem-const.h
@@ -5,7 +5,7 @@
#define RWSEM_UNLOCKED_VALUE 0x00000000
#define RWSEM_ACTIVE_BIAS 0x00000001
#define RWSEM_ACTIVE_MASK 0x0000ffff
-#define RWSEM_WAITING_BIAS (-0x00010000)
+#define RWSEM_WAITING_BIAS 0xffff0000
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
diff --git a/trunk/arch/sparc/include/asm/unistd.h b/trunk/arch/sparc/include/asm/unistd.h
index 03eb5a8f6f93..d0b3b01ac9d4 100644
--- a/trunk/arch/sparc/include/asm/unistd.h
+++ b/trunk/arch/sparc/include/asm/unistd.h
@@ -397,11 +397,8 @@
#define __NR_rt_tgsigqueueinfo 326
#define __NR_perf_event_open 327
#define __NR_recvmmsg 328
-#define __NR_fanotify_init 329
-#define __NR_fanotify_mark 330
-#define __NR_prlimit64 331
-#define NR_syscalls 332
+#define NR_syscalls 329
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/trunk/arch/sparc/kernel/process_32.c b/trunk/arch/sparc/kernel/process_32.c
index 17529298c50a..40e29fc8a4d6 100644
--- a/trunk/arch/sparc/kernel/process_32.c
+++ b/trunk/arch/sparc/kernel/process_32.c
@@ -633,10 +633,8 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
if(IS_ERR(filename))
goto out;
error = do_execve(filename,
- (const char __user *const __user *)
- regs->u_regs[base + UREG_I1],
- (const char __user *const __user *)
- regs->u_regs[base + UREG_I2],
+ (char __user * __user *)regs->u_regs[base + UREG_I1],
+ (char __user * __user *)regs->u_regs[base + UREG_I2],
regs);
putname(filename);
out:
diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c
index 485f54748384..dbe81a368b45 100644
--- a/trunk/arch/sparc/kernel/process_64.c
+++ b/trunk/arch/sparc/kernel/process_64.c
@@ -739,9 +739,9 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
if (IS_ERR(filename))
goto out;
error = do_execve(filename,
- (const char __user *const __user *)
+ (char __user * __user *)
regs->u_regs[base + UREG_I1],
- (const char __user *const __user *)
+ (char __user * __user *)
regs->u_regs[base + UREG_I2], regs);
putname(filename);
if (!error) {
diff --git a/trunk/arch/sparc/kernel/sys32.S b/trunk/arch/sparc/kernel/sys32.S
index 44e5faf1ad5f..46a76ba3fb4b 100644
--- a/trunk/arch/sparc/kernel/sys32.S
+++ b/trunk/arch/sparc/kernel/sys32.S
@@ -330,15 +330,6 @@ do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */
nop
nop
- .globl sys32_fanotify_mark
-sys32_fanotify_mark:
- sethi %hi(sys_fanotify_mark), %g1
- sllx %o2, 32, %o2
- or %o2, %o3, %o2
- mov %o4, %o3
- jmpl %g1 + %lo(sys_fanotify_mark), %g0
- mov %o5, %o4
-
.section __ex_table,"a"
.align 4
.word 1b, __retl_efault, 2b, __retl_efault
diff --git a/trunk/arch/sparc/kernel/sys_sparc_32.c b/trunk/arch/sparc/kernel/sys_sparc_32.c
index 50794137d710..ee995b7dae7e 100644
--- a/trunk/arch/sparc/kernel/sys_sparc_32.c
+++ b/trunk/arch/sparc/kernel/sys_sparc_32.c
@@ -282,9 +282,7 @@ asmlinkage int sys_getdomainname(char __user *name, int len)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
long __res;
register long __g1 __asm__ ("g1") = __NR_execve;
diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c
index f836f4e93afe..3d435c42e6db 100644
--- a/trunk/arch/sparc/kernel/sys_sparc_64.c
+++ b/trunk/arch/sparc/kernel/sys_sparc_64.c
@@ -758,9 +758,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
long __res;
register long __g1 __asm__ ("g1") = __NR_execve;
diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S
index ec396e1916b9..801fc8e5a0e8 100644
--- a/trunk/arch/sparc/kernel/systbls_32.S
+++ b/trunk/arch/sparc/kernel/systbls_32.S
@@ -82,6 +82,5 @@ sys_call_table:
/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
-/*330*/ .long sys_fanotify_mark, sys_prlimit64
+/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S
index 8cfcaa549580..9db058dd039e 100644
--- a/trunk/arch/sparc/kernel/systbls_64.S
+++ b/trunk/arch/sparc/kernel/systbls_64.S
@@ -83,8 +83,7 @@ sys_call_table32:
/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
- .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
-/*330*/ .word sys32_fanotify_mark, sys_prlimit64
+ .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg
#endif /* CONFIG_COMPAT */
@@ -159,5 +158,4 @@ sys_call_table:
/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
- .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
-/*330*/ .word sys_fanotify_mark, sys_prlimit64
+ .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg
diff --git a/trunk/arch/tile/kernel/process.c b/trunk/arch/tile/kernel/process.c
index 985cc28c74c5..ed590ad0acdc 100644
--- a/trunk/arch/tile/kernel/process.c
+++ b/trunk/arch/tile/kernel/process.c
@@ -543,9 +543,8 @@ long _sys_vfork(struct pt_regs *regs)
/*
* sys_execve() executes a new program.
*/
-long _sys_execve(const char __user *path,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
+long _sys_execve(char __user *path, char __user *__user *argv,
+ char __user *__user *envp, struct pt_regs *regs)
{
long error;
char *filename;
diff --git a/trunk/arch/um/include/asm/dma-mapping.h b/trunk/arch/um/include/asm/dma-mapping.h
index 1f469e80fdd3..17a2cb5a4178 100644
--- a/trunk/arch/um/include/asm/dma-mapping.h
+++ b/trunk/arch/um/include/asm/dma-mapping.h
@@ -95,6 +95,13 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+static inline int
+dma_get_cache_alignment(void)
+{
+ BUG();
+ return(0);
+}
+
static inline void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c
index cd145eda3579..59b20d93b6d4 100644
--- a/trunk/arch/um/kernel/exec.c
+++ b/trunk/arch/um/kernel/exec.c
@@ -44,9 +44,8 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
PT_REGS_SP(regs) = esp;
}
-static long execve1(const char *file,
- const char __user *const __user *argv,
- const char __user *const __user *env)
+static long execve1(const char *file, char __user * __user *argv,
+ char __user *__user *env)
{
long error;
diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c
index 5ddb246626db..7427c0b1930c 100644
--- a/trunk/arch/um/kernel/syscall.c
+++ b/trunk/arch/um/kernel/syscall.c
@@ -51,9 +51,7 @@ long old_mmap(unsigned long addr, unsigned long len,
return err;
}
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
mm_segment_t fs;
int ret;
diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig
index cea0cd9a316f..a84fc34c8f77 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -245,11 +245,6 @@ config ARCH_HWEIGHT_CFLAGS
config KTIME_SCALAR
def_bool X86_32
-
-config ARCH_CPU_PROBE_RELEASE
- def_bool y
- depends on HOTPLUG_CPU
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -754,11 +749,11 @@ config IOMMU_API
def_bool (AMD_IOMMU || DMAR)
config MAXSMP
- bool "Enable Maximum number of SMP Processors and NUMA Nodes"
+ bool "Configure Maximum number of SMP Processors and NUMA Nodes"
depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
select CPUMASK_OFFSTACK
---help---
- Enable maximum number of CPUS and NUMA Nodes for this architecture.
+ Configure maximum number of CPUS and NUMA Nodes for this architecture.
If unsure, say N.
config NR_CPUS
diff --git a/trunk/arch/x86/include/asm/pgtable_32.h b/trunk/arch/x86/include/asm/pgtable_32.h
index f686f49e8b7b..2984a25ff383 100644
--- a/trunk/arch/x86/include/asm/pgtable_32.h
+++ b/trunk/arch/x86/include/asm/pgtable_32.h
@@ -26,7 +26,6 @@ struct mm_struct;
struct vm_area_struct;
extern pgd_t swapper_pg_dir[1024];
-extern pgd_t trampoline_pg_dir[1024];
static inline void pgtable_cache_init(void) { }
static inline void check_pgt_cache(void) { }
diff --git a/trunk/arch/x86/include/asm/syscalls.h b/trunk/arch/x86/include/asm/syscalls.h
index f1d8b441fc77..feb2ff9bfc2d 100644
--- a/trunk/arch/x86/include/asm/syscalls.h
+++ b/trunk/arch/x86/include/asm/syscalls.h
@@ -23,9 +23,8 @@ long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/process.c */
int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
-long sys_execve(const char __user *,
- const char __user *const __user *,
- const char __user *const __user *, struct pt_regs *);
+long sys_execve(const char __user *, char __user * __user *,
+ char __user * __user *, struct pt_regs *);
long sys_clone(unsigned long, unsigned long, void __user *,
void __user *, struct pt_regs *);
diff --git a/trunk/arch/x86/include/asm/trampoline.h b/trunk/arch/x86/include/asm/trampoline.h
index 4dde797c0578..cb507bb05d79 100644
--- a/trunk/arch/x86/include/asm/trampoline.h
+++ b/trunk/arch/x86/include/asm/trampoline.h
@@ -13,17 +13,14 @@ extern unsigned char *trampoline_base;
extern unsigned long init_rsp;
extern unsigned long initial_code;
-extern unsigned long initial_page_table;
extern unsigned long initial_gs;
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
extern unsigned long setup_trampoline(void);
-extern void __init setup_trampoline_page_table(void);
extern void __init reserve_trampoline_memory(void);
#else
-static inline void setup_trampoline_page_table(void) {}
-static inline void reserve_trampoline_memory(void) {}
+static inline void reserve_trampoline_memory(void) {};
#endif /* CONFIG_X86_TRAMPOLINE */
#endif /* __ASSEMBLY__ */
diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c
index f1efebaf5510..4dc0084ec1b1 100644
--- a/trunk/arch/x86/kernel/apic/io_apic.c
+++ b/trunk/arch/x86/kernel/apic/io_apic.c
@@ -1728,8 +1728,6 @@ __apicdebuginit(void) print_IO_APIC(void)
struct irq_pin_list *entry;
cfg = desc->chip_data;
- if (!cfg)
- continue;
entry = cfg->irq_2_pin;
if (!entry)
continue;
diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c
index ba5f62f45f01..60a57b13082d 100644
--- a/trunk/arch/x86/kernel/cpu/amd.c
+++ b/trunk/arch/x86/kernel/cpu/amd.c
@@ -669,7 +669,7 @@ bool cpu_has_amd_erratum(const int *erratum)
}
/* OSVW unavailable or ID unknown, match family-model-stepping range */
- ms = (cpu->x86_model << 4) | cpu->x86_mask;
+ ms = (cpu->x86_model << 8) | cpu->x86_mask;
while ((range = *erratum++))
if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
(ms >= AMD_MODEL_RANGE_START(range)) &&
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c
index d8d86d014008..214ac860ebe0 100644
--- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c
@@ -491,78 +491,33 @@ static void intel_pmu_enable_all(int added)
* Intel Errata AAP53 (model 30)
* Intel Errata BD53 (model 44)
*
- * The official story:
- * These chips need to be 'reset' when adding counters by programming the
- * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
- * in sequence on the same PMC or on different PMCs.
- *
- * In practise it appears some of these events do in fact count, and
- * we need to programm all 4 events.
+ * These chips need to be 'reset' when adding counters by programming
+ * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5
+ * either in sequence on the same PMC or on different PMCs.
*/
-static void intel_pmu_nhm_workaround(void)
+static void intel_pmu_nhm_enable_all(int added)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- static const unsigned long nhm_magic[4] = {
- 0x4300B5,
- 0x4300D2,
- 0x4300B1,
- 0x4300B1
- };
- struct perf_event *event;
- int i;
-
- /*
- * The Errata requires below steps:
- * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
- * 2) Configure 4 PERFEVTSELx with the magic events and clear
- * the corresponding PMCx;
- * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
- * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
- * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
- */
-
- /*
- * The real steps we choose are a little different from above.
- * A) To reduce MSR operations, we don't run step 1) as they
- * are already cleared before this function is called;
- * B) Call x86_perf_event_update to save PMCx before configuring
- * PERFEVTSELx with magic number;
- * C) With step 5), we do clear only when the PERFEVTSELx is
- * not used currently.
- * D) Call x86_perf_event_set_period to restore PMCx;
- */
+ if (added) {
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int i;
- /* We always operate 4 pairs of PERF Counters */
- for (i = 0; i < 4; i++) {
- event = cpuc->events[i];
- if (event)
- x86_perf_event_update(event);
- }
+ wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2);
+ wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1);
+ wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5);
- for (i = 0; i < 4; i++) {
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
- wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
- }
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
+ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
+ for (i = 0; i < 3; i++) {
+ struct perf_event *event = cpuc->events[i];
- for (i = 0; i < 4; i++) {
- event = cpuc->events[i];
+ if (!event)
+ continue;
- if (event) {
- x86_perf_event_set_period(event);
__x86_pmu_enable_event(&event->hw,
- ARCH_PERFMON_EVENTSEL_ENABLE);
- } else
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
+ ARCH_PERFMON_EVENTSEL_ENABLE);
+ }
}
-}
-
-static void intel_pmu_nhm_enable_all(int added)
-{
- if (added)
- intel_pmu_nhm_workaround();
intel_pmu_enable_all(added);
}
diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S
index fa8c1b8e09fb..ff4c453e13f3 100644
--- a/trunk/arch/x86/kernel/head_32.S
+++ b/trunk/arch/x86/kernel/head_32.S
@@ -334,7 +334,7 @@ ENTRY(startup_32_smp)
/*
* Enable paging
*/
- movl pa(initial_page_table), %eax
+ movl $pa(swapper_pg_dir),%eax
movl %eax,%cr3 /* set the page table pointer.. */
movl %cr0,%eax
orl $X86_CR0_PG,%eax
@@ -614,8 +614,6 @@ ignore_int:
.align 4
ENTRY(initial_code)
.long i386_start_kernel
-ENTRY(initial_page_table)
- .long pa(swapper_pg_dir)
/*
* BSS section
@@ -631,10 +629,6 @@ ENTRY(swapper_pg_dir)
#endif
swapper_pg_fixmap:
.fill 1024,4,0
-#ifdef CONFIG_X86_TRAMPOLINE
-ENTRY(trampoline_pg_dir)
- .fill 1024,4,0
-#endif
ENTRY(empty_zero_page)
.fill 4096,1,0
diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c
index a46cb3522c0c..1f11f5ce668f 100644
--- a/trunk/arch/x86/kernel/i387.c
+++ b/trunk/arch/x86/kernel/i387.c
@@ -40,7 +40,6 @@
static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
unsigned int xstate_size;
-EXPORT_SYMBOL_GPL(xstate_size);
unsigned int sig_xstate_ia32_size = sizeof(struct _fpstate_ia32);
static struct i387_fxsave_struct fx_scratch __cpuinitdata;
diff --git a/trunk/arch/x86/kernel/kgdb.c b/trunk/arch/x86/kernel/kgdb.c
index 852b81967a37..ef10940e1af0 100644
--- a/trunk/arch/x86/kernel/kgdb.c
+++ b/trunk/arch/x86/kernel/kgdb.c
@@ -194,7 +194,7 @@ static struct hw_breakpoint {
unsigned long addr;
int len;
int type;
- struct perf_event * __percpu *pev;
+ struct perf_event **pev;
} breakinfo[HBP_NUM];
static unsigned long early_dr7;
diff --git a/trunk/arch/x86/kernel/kprobes.c b/trunk/arch/x86/kernel/kprobes.c
index 770ebfb349e9..1bfb6cf4dd55 100644
--- a/trunk/arch/x86/kernel/kprobes.c
+++ b/trunk/arch/x86/kernel/kprobes.c
@@ -709,7 +709,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
struct hlist_node *node, *tmp;
unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
- kprobe_opcode_t *correct_ret_addr = NULL;
INIT_HLIST_HEAD(&empty_rp);
kretprobe_hash_lock(current, &head, &flags);
@@ -741,34 +740,14 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
/* another task is sharing our hash bucket */
continue;
- orig_ret_address = (unsigned long)ri->ret_addr;
-
- if (orig_ret_address != trampoline_address)
- /*
- * This is the real return address. Any other
- * instances associated with this task are for
- * other calls deeper on the call stack
- */
- break;
- }
-
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
-
- correct_ret_addr = ri->ret_addr;
- hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
- if (ri->task != current)
- /* another task is sharing our hash bucket */
- continue;
-
- orig_ret_address = (unsigned long)ri->ret_addr;
if (ri->rp && ri->rp->handler) {
__get_cpu_var(current_kprobe) = &ri->rp->kp;
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
- ri->ret_addr = correct_ret_addr;
ri->rp->handler(ri, regs);
__get_cpu_var(current_kprobe) = NULL;
}
+ orig_ret_address = (unsigned long)ri->ret_addr;
recycle_rp_inst(ri, &empty_rp);
if (orig_ret_address != trampoline_address)
@@ -780,6 +759,8 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
break;
}
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
kretprobe_hash_unlock(current, &flags);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c
index 57d1868a86aa..64ecaf0af9af 100644
--- a/trunk/arch/x86/kernel/process.c
+++ b/trunk/arch/x86/kernel/process.c
@@ -301,9 +301,8 @@ EXPORT_SYMBOL(kernel_thread);
/*
* sys_execve() executes a new program.
*/
-long sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
+long sys_execve(const char __user *name, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
{
long error;
char *filename;
diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c
index c3a4fbb2b996..b008e7883207 100644
--- a/trunk/arch/x86/kernel/setup.c
+++ b/trunk/arch/x86/kernel/setup.c
@@ -1014,8 +1014,6 @@ void __init setup_arch(char **cmdline_p)
paging_init();
x86_init.paging.pagetable_setup_done(swapper_pg_dir);
- setup_trampoline_page_table();
-
tboot_probe();
#ifdef CONFIG_X86_64
diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c
index 8b3bfc4dd708..a5e928b0cb5f 100644
--- a/trunk/arch/x86/kernel/smpboot.c
+++ b/trunk/arch/x86/kernel/smpboot.c
@@ -73,6 +73,7 @@
#ifdef CONFIG_X86_32
u8 apicid_2_node[MAX_APICID];
+static int low_mappings;
#endif
/* State of each CPU */
@@ -90,25 +91,6 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
-
-/*
- * We need this for trampoline_base protection from concurrent accesses when
- * off- and onlining cores wildly.
- */
-static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
-
-void cpu_hotplug_driver_lock()
-{
- mutex_lock(&x86_cpu_hotplug_driver_mutex);
-}
-
-void cpu_hotplug_driver_unlock()
-{
- mutex_unlock(&x86_cpu_hotplug_driver_mutex);
-}
-
-ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
-ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
#else
static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
#define get_idle_for_cpu(x) (idle_thread_array[(x)])
@@ -299,18 +281,6 @@ notrace static void __cpuinit start_secondary(void *unused)
* fragile that we want to limit the things done here to the
* most necessary things.
*/
-
-#ifdef CONFIG_X86_32
- /*
- * Switch away from the trampoline page-table
- *
- * Do this before cpu_init() because it needs to access per-cpu
- * data which may not be mapped in the trampoline page-table.
- */
- load_cr3(swapper_pg_dir);
- __flush_tlb_all();
-#endif
-
vmi_bringup();
cpu_init();
preempt_disable();
@@ -329,6 +299,12 @@ notrace static void __cpuinit start_secondary(void *unused)
legacy_pic->chip->unmask(0);
}
+#ifdef CONFIG_X86_32
+ while (low_mappings)
+ cpu_relax();
+ __flush_tlb_all();
+#endif
+
/* This must be done before setting cpu_online_mask */
set_cpu_sibling_map(raw_smp_processor_id());
wmb();
@@ -774,7 +750,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
#ifdef CONFIG_X86_32
/* Stack for startup_32 can be just as for start_secondary onwards */
irq_ctx_init(cpu);
- initial_page_table = __pa(&trampoline_pg_dir);
#else
clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
initial_gs = per_cpu_offset(cpu);
@@ -922,8 +897,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+#ifdef CONFIG_X86_32
+ /* init low mem mapping */
+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+ flush_tlb_all();
+ low_mappings = 1;
+
err = do_boot_cpu(apicid, cpu);
+ zap_low_mappings(false);
+ low_mappings = 0;
+#else
+ err = do_boot_cpu(apicid, cpu);
+#endif
if (err) {
pr_debug("do_boot_cpu failed %d\n", err);
return -EIO;
diff --git a/trunk/arch/x86/kernel/sys_i386_32.c b/trunk/arch/x86/kernel/sys_i386_32.c
index d5e06624e34a..196552bb412c 100644
--- a/trunk/arch/x86/kernel/sys_i386_32.c
+++ b/trunk/arch/x86/kernel/sys_i386_32.c
@@ -28,9 +28,7 @@
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
long __res;
asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
diff --git a/trunk/arch/x86/kernel/trampoline.c b/trunk/arch/x86/kernel/trampoline.c
index a874495b3673..c652ef62742d 100644
--- a/trunk/arch/x86/kernel/trampoline.c
+++ b/trunk/arch/x86/kernel/trampoline.c
@@ -1,7 +1,6 @@
#include
#include
-#include
#include
#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
@@ -38,20 +37,3 @@ unsigned long __trampinit setup_trampoline(void)
memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
return virt_to_phys(trampoline_base);
}
-
-void __init setup_trampoline_page_table(void)
-{
-#ifdef CONFIG_X86_32
- /* Copy kernel address range */
- clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY,
- swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- min_t(unsigned long, KERNEL_PGD_PTRS,
- KERNEL_PGD_BOUNDARY));
-
- /* Initialize low mappings */
- clone_pgd_range(trampoline_pg_dir,
- swapper_pg_dir + KERNEL_PGD_BOUNDARY,
- min_t(unsigned long, KERNEL_PGD_PTRS,
- KERNEL_PGD_BOUNDARY));
-#endif
-}
diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c
index ddeb2314b522..0fd6378981f4 100644
--- a/trunk/arch/x86/kvm/i8254.c
+++ b/trunk/arch/x86/kvm/i8254.c
@@ -697,7 +697,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
pit->wq = create_singlethread_workqueue("kvm-pit-wq");
if (!pit->wq) {
mutex_unlock(&pit->pit_state.lock);
- kvm_free_irq_source_id(kvm, pit->irq_source_id);
kfree(pit);
return NULL;
}
@@ -743,7 +742,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
kvm_free_irq_source_id(kvm, pit->irq_source_id);
- destroy_workqueue(pit->wq);
+
kfree(pit);
return NULL;
}
diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c
index 3a09c625d526..25f19078b321 100644
--- a/trunk/arch/x86/kvm/x86.c
+++ b/trunk/arch/x86/kvm/x86.c
@@ -2387,7 +2387,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
if (cpu_has_xsave)
memcpy(guest_xsave->region,
&vcpu->arch.guest_fpu.state->xsave,
- xstate_size);
+ sizeof(struct xsave_struct));
else {
memcpy(guest_xsave->region,
&vcpu->arch.guest_fpu.state->fxsave,
@@ -2405,7 +2405,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
if (cpu_has_xsave)
memcpy(&vcpu->arch.guest_fpu.state->xsave,
- guest_xsave->region, xstate_size);
+ guest_xsave->region, sizeof(struct xsave_struct));
else {
if (xstate_bv & ~XSTATE_FPSSE)
return -EINVAL;
diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c
index e3558b9a58ba..7c2f38f68ebb 100644
--- a/trunk/arch/xtensa/kernel/process.c
+++ b/trunk/arch/xtensa/kernel/process.c
@@ -318,9 +318,8 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp,
*/
asmlinkage
-long xtensa_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
+long xtensa_execve(const char __user *name, char __user * __user *argv,
+ char __user * __user *envp,
long a3, long a4, long a5,
struct pt_regs *regs)
{
diff --git a/trunk/drivers/ata/sata_dwc_460ex.c b/trunk/drivers/ata/sata_dwc_460ex.c
index 2673a3d14806..ea24c1e51be2 100644
--- a/trunk/drivers/ata/sata_dwc_460ex.c
+++ b/trunk/drivers/ata/sata_dwc_460ex.c
@@ -1588,7 +1588,7 @@ static const struct ata_port_info sata_dwc_port_info[] = {
},
};
-static int sata_dwc_probe(struct platform_device *ofdev,
+static int sata_dwc_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
struct sata_dwc_device *hsdev;
@@ -1702,7 +1702,7 @@ static int sata_dwc_probe(struct platform_device *ofdev,
return err;
}
-static int sata_dwc_remove(struct platform_device *ofdev)
+static int sata_dwc_remove(struct of_device *ofdev)
{
struct device *dev = &ofdev->dev;
struct ata_host *host = dev_get_drvdata(dev);
diff --git a/trunk/drivers/block/xsysace.c b/trunk/drivers/block/xsysace.c
index 057413bb16e2..2982b3ee9465 100644
--- a/trunk/drivers/block/xsysace.c
+++ b/trunk/drivers/block/xsysace.c
@@ -94,7 +94,6 @@
#include
#include
#if defined(CONFIG_OF)
-#include
#include
#include
#endif
diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c
index 710af89b176d..ddf5def1b0da 100644
--- a/trunk/drivers/char/agp/intel-agp.c
+++ b/trunk/drivers/char/agp/intel-agp.c
@@ -819,16 +819,13 @@ static const struct intel_driver_description {
"Sandybridge", NULL, &intel_gen6_driver },
{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
"Sandybridge", NULL, &intel_gen6_driver },
- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG,
- "Sandybridge", NULL, &intel_gen6_driver },
{ 0, 0, NULL, NULL, NULL }
};
static int __devinit intel_gmch_probe(struct pci_dev *pdev,
struct agp_bridge_data *bridge)
{
- int i, mask;
-
+ int i;
bridge->driver = NULL;
for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
@@ -848,19 +845,14 @@ static int __devinit intel_gmch_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
- if (bridge->driver->mask_memory == intel_gen6_mask_memory)
- mask = 40;
- else if (bridge->driver->mask_memory == intel_i965_mask_memory)
- mask = 36;
- else
- mask = 32;
-
- if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)))
- dev_err(&intel_private.pcidev->dev,
- "set gfx device dma mask %d-bit failed!\n", mask);
- else
- pci_set_consistent_dma_mask(intel_private.pcidev,
- DMA_BIT_MASK(mask));
+ if (bridge->driver->mask_memory == intel_i965_mask_memory) {
+ if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+ dev_err(&intel_private.pcidev->dev,
+ "set gfx device dma mask 36bit failed!\n");
+ else
+ pci_set_consistent_dma_mask(intel_private.pcidev,
+ DMA_BIT_MASK(36));
+ }
return 1;
}
diff --git a/trunk/drivers/char/agp/intel-agp.h b/trunk/drivers/char/agp/intel-agp.h
index 08d47532e605..c05e3e518268 100644
--- a/trunk/drivers/char/agp/intel-agp.h
+++ b/trunk/drivers/char/agp/intel-agp.h
@@ -204,7 +204,6 @@
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104
#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG 0x0126
/* cover 915 and 945 variants */
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c
index c350d01716bd..ad46eae1f9bb 100644
--- a/trunk/drivers/char/pty.c
+++ b/trunk/drivers/char/pty.c
@@ -675,8 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp)
}
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-
- tty_add_file(tty, filp);
+ filp->private_data = tty;
+ file_move(filp, &tty->tty_files);
retval = devpts_pty_new(inode, tty->link);
if (retval)
diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c
index 949067a0bd47..0350c42375a2 100644
--- a/trunk/drivers/char/tty_io.c
+++ b/trunk/drivers/char/tty_io.c
@@ -136,9 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
DEFINE_MUTEX(tty_mutex);
EXPORT_SYMBOL(tty_mutex);
-/* Spinlock to protect the tty->tty_files list */
-DEFINE_SPINLOCK(tty_files_lock);
-
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -188,41 +185,6 @@ void free_tty_struct(struct tty_struct *tty)
kfree(tty);
}
-static inline struct tty_struct *file_tty(struct file *file)
-{
- return ((struct tty_file_private *)file->private_data)->tty;
-}
-
-/* Associate a new file with the tty structure */
-void tty_add_file(struct tty_struct *tty, struct file *file)
-{
- struct tty_file_private *priv;
-
- /* XXX: must implement proper error handling in callers */
- priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
-
- priv->tty = tty;
- priv->file = file;
- file->private_data = priv;
-
- spin_lock(&tty_files_lock);
- list_add(&priv->list, &tty->tty_files);
- spin_unlock(&tty_files_lock);
-}
-
-/* Delete file from its tty */
-void tty_del_file(struct file *file)
-{
- struct tty_file_private *priv = file->private_data;
-
- spin_lock(&tty_files_lock);
- list_del(&priv->list);
- spin_unlock(&tty_files_lock);
- file->private_data = NULL;
- kfree(priv);
-}
-
-
#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
/**
@@ -273,11 +235,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
struct list_head *p;
int count = 0;
- spin_lock(&tty_files_lock);
+ file_list_lock();
list_for_each(p, &tty->tty_files) {
count++;
}
- spin_unlock(&tty_files_lock);
+ file_list_unlock();
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_SLAVE &&
tty->link && tty->link->count)
@@ -535,7 +497,6 @@ void __tty_hangup(struct tty_struct *tty)
struct file *cons_filp = NULL;
struct file *filp, *f = NULL;
struct task_struct *p;
- struct tty_file_private *priv;
int closecount = 0, n;
unsigned long flags;
int refs = 0;
@@ -545,7 +506,7 @@ void __tty_hangup(struct tty_struct *tty)
spin_lock(&redirect_lock);
- if (redirect && file_tty(redirect) == tty) {
+ if (redirect && redirect->private_data == tty) {
f = redirect;
redirect = NULL;
}
@@ -558,10 +519,9 @@ void __tty_hangup(struct tty_struct *tty)
workqueue with the lock held */
check_tty_count(tty, "tty_hangup");
- spin_lock(&tty_files_lock);
+ file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
- list_for_each_entry(priv, &tty->tty_files, list) {
- filp = priv->file;
+ list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
if (filp->f_op->write == redirected_tty_write)
cons_filp = filp;
if (filp->f_op->write != tty_write)
@@ -570,7 +530,7 @@ void __tty_hangup(struct tty_struct *tty)
__tty_fasync(-1, filp, 0); /* can't block */
filp->f_op = &hung_up_tty_fops;
}
- spin_unlock(&tty_files_lock);
+ file_list_unlock();
tty_ldisc_hangup(tty);
@@ -929,10 +889,12 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
int i;
- struct inode *inode = file->f_path.dentry->d_inode;
- struct tty_struct *tty = file_tty(file);
+ struct tty_struct *tty;
+ struct inode *inode;
struct tty_ldisc *ld;
+ tty = file->private_data;
+ inode = file->f_path.dentry->d_inode;
if (tty_paranoia_check(tty, inode, "tty_read"))
return -EIO;
if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -1103,11 +1065,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
static ssize_t tty_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
+ struct tty_struct *tty;
struct inode *inode = file->f_path.dentry->d_inode;
- struct tty_struct *tty = file_tty(file);
- struct tty_ldisc *ld;
ssize_t ret;
+ struct tty_ldisc *ld;
+ tty = file->private_data;
if (tty_paranoia_check(tty, inode, "tty_write"))
return -EIO;
if (!tty || !tty->ops->write ||
@@ -1461,9 +1424,9 @@ static void release_one_tty(struct work_struct *work)
tty_driver_kref_put(driver);
module_put(driver->owner);
- spin_lock(&tty_files_lock);
+ file_list_lock();
list_del_init(&tty->tty_files);
- spin_unlock(&tty_files_lock);
+ file_list_unlock();
put_pid(tty->pgrp);
put_pid(tty->session);
@@ -1544,13 +1507,13 @@ static void release_tty(struct tty_struct *tty, int idx)
int tty_release(struct inode *inode, struct file *filp)
{
- struct tty_struct *tty = file_tty(filp);
- struct tty_struct *o_tty;
+ struct tty_struct *tty, *o_tty;
int pty_master, tty_closing, o_tty_closing, do_sleep;
int devpts;
int idx;
char buf[64];
+ tty = filp->private_data;
if (tty_paranoia_check(tty, inode, "tty_release_dev"))
return 0;
@@ -1708,7 +1671,8 @@ int tty_release(struct inode *inode, struct file *filp)
* - do_tty_hangup no longer sees this file descriptor as
* something that needs to be handled for hangups.
*/
- tty_del_file(filp);
+ file_kill(filp);
+ filp->private_data = NULL;
/*
* Perform some housekeeping before deciding whether to return.
@@ -1875,8 +1839,8 @@ static int tty_open(struct inode *inode, struct file *filp)
return PTR_ERR(tty);
}
- tty_add_file(tty, filp);
-
+ filp->private_data = tty;
+ file_move(filp, &tty->tty_files);
check_tty_count(tty, "tty_open");
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER)
@@ -1952,10 +1916,11 @@ static int tty_open(struct inode *inode, struct file *filp)
static unsigned int tty_poll(struct file *filp, poll_table *wait)
{
- struct tty_struct *tty = file_tty(filp);
+ struct tty_struct *tty;
struct tty_ldisc *ld;
int ret = 0;
+ tty = filp->private_data;
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
return 0;
@@ -1968,10 +1933,11 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
static int __tty_fasync(int fd, struct file *filp, int on)
{
- struct tty_struct *tty = file_tty(filp);
+ struct tty_struct *tty;
unsigned long flags;
int retval = 0;
+ tty = filp->private_data;
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
goto out;
@@ -2525,13 +2491,13 @@ EXPORT_SYMBOL(tty_pair_get_pty);
*/
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- struct tty_struct *tty = file_tty(file);
- struct tty_struct *real_tty;
+ struct tty_struct *tty, *real_tty;
void __user *p = (void __user *)arg;
int retval;
struct tty_ldisc *ld;
struct inode *inode = file->f_dentry->d_inode;
+ tty = file->private_data;
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
return -EINVAL;
@@ -2653,7 +2619,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct inode *inode = file->f_dentry->d_inode;
- struct tty_struct *tty = file_tty(file);
+ struct tty_struct *tty = file->private_data;
struct tty_ldisc *ld;
int retval = -ENOIOCTLCMD;
@@ -2745,7 +2711,7 @@ void __do_SAK(struct tty_struct *tty)
if (!filp)
continue;
if (filp->f_op->read == tty_read &&
- file_tty(filp) == tty) {
+ filp->private_data == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): fd#%d opened to the tty\n",
task_pid_nr(p), p->comm, i);
diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c
index 50590c7f2c01..c734f9b1263a 100644
--- a/trunk/drivers/char/vt.c
+++ b/trunk/drivers/char/vt.c
@@ -194,11 +194,10 @@ static DECLARE_WORK(console_work, console_callback);
int fg_console;
int last_console;
int want_console = -1;
-static int saved_fg_console;
-static int saved_last_console;
-static int saved_want_console;
-static int saved_vc_mode;
-static int saved_console_blanked;
+int saved_fg_console;
+int saved_last_console;
+int saved_want_console;
+int saved_vc_mode;
/*
* For each existing display, we have a pointer to console currently visible
@@ -3450,7 +3449,6 @@ int con_debug_enter(struct vc_data *vc)
saved_last_console = last_console;
saved_want_console = want_console;
saved_vc_mode = vc->vc_mode;
- saved_console_blanked = console_blanked;
vc->vc_mode = KD_TEXT;
console_blanked = 0;
if (vc->vc_sw->con_debug_enter)
@@ -3494,7 +3492,6 @@ int con_debug_leave(void)
fg_console = saved_fg_console;
last_console = saved_last_console;
want_console = saved_want_console;
- console_blanked = saved_console_blanked;
vc_cons[fg_console].d->vc_mode = saved_vc_mode;
vc = vc_cons[fg_console].d;
diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index b663d573aad9..0ed763cd2e77 100644
--- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -94,7 +94,6 @@
#ifdef CONFIG_OF
/* For open firmware. */
-#include
#include
#include
#endif
diff --git a/trunk/drivers/gpu/drm/i915/Makefile b/trunk/drivers/gpu/drm/i915/Makefile
index 5c8e53458edb..da78f2c0d909 100644
--- a/trunk/drivers/gpu/drm/i915/Makefile
+++ b/trunk/drivers/gpu/drm/i915/Makefile
@@ -8,7 +8,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
i915_suspend.o \
i915_gem.o \
i915_gem_debug.o \
- i915_gem_evict.o \
i915_gem_tiling.o \
i915_trace_points.o \
intel_display.o \
@@ -19,7 +18,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_hdmi.o \
intel_sdvo.o \
intel_modes.o \
- intel_panel.o \
intel_i2c.o \
intel_fb.o \
intel_tv.o \
diff --git a/trunk/drivers/gpu/drm/i915/dvo.h b/trunk/drivers/gpu/drm/i915/dvo.h
index 8c2ad014c47f..0d6ff640e1c6 100644
--- a/trunk/drivers/gpu/drm/i915/dvo.h
+++ b/trunk/drivers/gpu/drm/i915/dvo.h
@@ -30,17 +30,20 @@
#include "intel_drv.h"
struct intel_dvo_device {
- const char *name;
+ char *name;
int type;
/* DVOA/B/C output register */
u32 dvo_reg;
/* GPIO register used for i2c bus to control this device */
u32 gpio;
int slave_addr;
+ struct i2c_adapter *i2c_bus;
const struct intel_dvo_dev_ops *dev_ops;
void *dev_priv;
- struct i2c_adapter *i2c_bus;
+
+ struct drm_display_mode *panel_fixed_mode;
+ bool panel_wants_dither;
};
struct intel_dvo_dev_ops {
diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c
index 92d5605a34d1..9214119c0154 100644
--- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c
@@ -467,9 +467,6 @@ static int i915_error_state(struct seq_file *m, void *unused)
}
}
- if (error->overlay)
- intel_overlay_print_error_state(m, error->overlay);
-
out:
spin_unlock_irqrestore(&dev_priv->error_lock, flags);
diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c
index 44af317731b6..f19ffe87af3c 100644
--- a/trunk/drivers/gpu/drm/i915/i915_dma.c
+++ b/trunk/drivers/gpu/drm/i915/i915_dma.c
@@ -499,13 +499,6 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
}
}
-
- if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
- BEGIN_LP_RING(2);
- OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP);
- OUT_RING(MI_NOOP);
- ADVANCE_LP_RING();
- }
i915_emit_breadcrumb(dev);
return 0;
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c
index 00befce8fbb7..5044f653e8ea 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.c
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.c
@@ -181,7 +181,6 @@ static const struct pci_device_id pciidlist[] = { /* aka */
INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
- INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
{0, 0, 0}
};
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h
index 047cd7ce7e1b..906663b9929e 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.h
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.h
@@ -113,9 +113,6 @@ struct intel_opregion {
int enabled;
};
-struct intel_overlay;
-struct intel_overlay_error_state;
-
struct drm_i915_master_private {
drm_local_map_t *sarea;
struct _drm_i915_sarea *sarea_priv;
@@ -169,7 +166,6 @@ struct drm_i915_error_state {
u32 purgeable:1;
} *active_bo;
u32 active_bo_count;
- struct intel_overlay_error_state *overlay;
};
struct drm_i915_display_funcs {
@@ -190,6 +186,8 @@ struct drm_i915_display_funcs {
/* clock gating init */
};
+struct intel_overlay;
+
struct intel_device_info {
u8 is_mobile : 1;
u8 is_i8xx : 1;
@@ -244,7 +242,6 @@ typedef struct drm_i915_private {
struct pci_dev *bridge_dev;
struct intel_ring_buffer render_ring;
struct intel_ring_buffer bsd_ring;
- uint32_t next_seqno;
drm_dma_handle_t *status_page_dmah;
void *seqno_page;
@@ -254,7 +251,6 @@ typedef struct drm_i915_private {
drm_local_map_t hws_map;
struct drm_gem_object *seqno_obj;
struct drm_gem_object *pwrctx;
- struct drm_gem_object *renderctx;
struct resource mch_res;
@@ -289,9 +285,6 @@ typedef struct drm_i915_private {
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
int vblank_pipe;
int num_pipe;
- u32 flush_rings;
-#define FLUSH_RENDER_RING 0x1
-#define FLUSH_BSD_RING 0x2
/* For hangcheck timer */
#define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */
@@ -575,6 +568,8 @@ typedef struct drm_i915_private {
*/
struct delayed_work retire_work;
+ uint32_t next_gem_seqno;
+
/**
* Waiting sequence number, if any
*/
@@ -615,8 +610,6 @@ typedef struct drm_i915_private {
struct sdvo_device_mapping sdvo_mappings[2];
/* indicate whether the LVDS_BORDER should be enabled or not */
unsigned int lvds_border_bits;
- /* Panel fitter placement and size for Ironlake+ */
- u32 pch_pf_pos, pch_pf_size;
struct drm_crtc *plane_to_crtc_mapping[2];
struct drm_crtc *pipe_to_crtc_mapping[2];
@@ -676,8 +669,6 @@ struct drm_i915_gem_object {
struct list_head list;
/** This object's place on GPU write list */
struct list_head gpu_write_list;
- /** This object's place on eviction list */
- struct list_head evict_list;
/**
* This is set if the object is on the active or flushing lists
@@ -987,7 +978,6 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
-int i915_gpu_idle(struct drm_device *dev);
int i915_gem_idle(struct drm_device *dev);
uint32_t i915_add_request(struct drm_device *dev,
struct drm_file *file_priv,
@@ -1001,9 +991,7 @@ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj);
int i915_gem_attach_phys_object(struct drm_device *dev,
- struct drm_gem_object *obj,
- int id,
- int align);
+ struct drm_gem_object *obj, int id);
void i915_gem_detach_phys_object(struct drm_device *dev,
struct drm_gem_object *obj);
void i915_gem_free_all_phys_object(struct drm_device *dev);
@@ -1015,11 +1003,6 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void);
-/* i915_gem_evict.c */
-int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment);
-int i915_gem_evict_everything(struct drm_device *dev);
-int i915_gem_evict_inactive(struct drm_device *dev);
-
/* i915_gem_tiling.c */
void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
@@ -1083,10 +1066,6 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
extern void intel_detect_pch (struct drm_device *dev);
extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
-/* overlay */
-extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
-
/**
* Lock test for when it's just for synchronization of ring access.
*
@@ -1113,26 +1092,26 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
#define I915_VERBOSE 0
#define BEGIN_LP_RING(n) do { \
- drm_i915_private_t *dev_priv__ = dev->dev_private; \
+ drm_i915_private_t *dev_priv = dev->dev_private; \
if (I915_VERBOSE) \
DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \
- intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \
+ intel_ring_begin(dev, &dev_priv->render_ring, (n)); \
} while (0)
#define OUT_RING(x) do { \
- drm_i915_private_t *dev_priv__ = dev->dev_private; \
+ drm_i915_private_t *dev_priv = dev->dev_private; \
if (I915_VERBOSE) \
DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \
- intel_ring_emit(dev, &dev_priv__->render_ring, x); \
+ intel_ring_emit(dev, &dev_priv->render_ring, x); \
} while (0)
#define ADVANCE_LP_RING() do { \
- drm_i915_private_t *dev_priv__ = dev->dev_private; \
+ drm_i915_private_t *dev_priv = dev->dev_private; \
if (I915_VERBOSE) \
DRM_DEBUG("ADVANCE_LP_RING %x\n", \
- dev_priv__->render_ring.tail); \
- intel_ring_advance(dev, &dev_priv__->render_ring); \
+ dev_priv->render_ring.tail); \
+ intel_ring_advance(dev, &dev_priv->render_ring); \
} while(0)
/**
diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c
index df5a7135c261..0758c7802e6b 100644
--- a/trunk/drivers/gpu/drm/i915/i915_gem.c
+++ b/trunk/drivers/gpu/drm/i915/i915_gem.c
@@ -35,7 +35,6 @@
#include
#include
-static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -49,6 +48,8 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
unsigned alignment);
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
+static int i915_gem_evict_something(struct drm_device *dev, int min_size);
+static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv);
@@ -57,14 +58,6 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj);
static LIST_HEAD(shrink_list);
static DEFINE_SPINLOCK(shrink_list_lock);
-static inline bool
-i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv)
-{
- return obj_priv->gtt_space &&
- !obj_priv->active &&
- obj_priv->pin_count == 0;
-}
-
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end)
{
@@ -320,8 +313,7 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj)
if (ret == -ENOMEM) {
struct drm_device *dev = obj->dev;
- ret = i915_gem_evict_something(dev, obj->size,
- i915_gem_get_gtt_alignment(obj));
+ ret = i915_gem_evict_something(dev, obj->size);
if (ret)
return ret;
@@ -1044,11 +1036,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
}
-
- /* Maintain LRU order of "inactive" objects */
- if (ret == 0 && i915_gem_object_is_inactive(obj_priv))
- list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
-
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -1150,7 +1137,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_gem_object *obj = vma->vm_private_data;
struct drm_device *dev = obj->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
pgoff_t page_offset;
unsigned long pfn;
@@ -1168,6 +1155,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (ret)
goto unlock;
+ list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
+
ret = i915_gem_object_set_to_gtt_domain(obj, write);
if (ret)
goto unlock;
@@ -1180,9 +1169,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
goto unlock;
}
- if (i915_gem_object_is_inactive(obj_priv))
- list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
-
pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
page_offset;
@@ -1377,6 +1363,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_i915_gem_mmap_gtt *args = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
int ret;
@@ -1422,6 +1409,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex);
return ret;
}
+ list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
}
drm_gem_object_unreference(obj);
@@ -1505,16 +1493,9 @@ i915_gem_object_truncate(struct drm_gem_object *obj)
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct inode *inode;
- /* Our goal here is to return as much of the memory as
- * is possible back to the system as we are called from OOM.
- * To do this we must instruct the shmfs to drop all of its
- * backing pages, *now*. Here we mirror the actions taken
- * when by shmem_delete_inode() to release the backing store.
- */
inode = obj->filp->f_path.dentry->d_inode;
- truncate_inode_pages(inode->i_mapping, 0);
- if (inode->i_op->truncate_range)
- inode->i_op->truncate_range(inode, 0, (loff_t)-1);
+ if (inode->i_op->truncate)
+ inode->i_op->truncate (inode);
obj_priv->madv = __I915_MADV_PURGED;
}
@@ -1906,6 +1887,19 @@ i915_gem_flush(struct drm_device *dev,
flush_domains);
}
+static void
+i915_gem_flush_ring(struct drm_device *dev,
+ uint32_t invalidate_domains,
+ uint32_t flush_domains,
+ struct intel_ring_buffer *ring)
+{
+ if (flush_domains & I915_GEM_DOMAIN_CPU)
+ drm_agp_chipset_flush(dev);
+ ring->flush(dev, ring,
+ invalidate_domains,
+ flush_domains);
+}
+
/**
* Ensures that all rendering to the object has completed and the object is
* safe to unbind from the GTT or access from the CPU.
@@ -1979,6 +1973,8 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
* cause memory corruption through use-after-free.
*/
+ BUG_ON(obj_priv->active);
+
/* release the fence reg _after_ flushing */
if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
i915_gem_clear_fence_reg(obj);
@@ -2014,7 +2010,34 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
return ret;
}
-int
+static struct drm_gem_object *
+i915_gem_find_inactive_object(struct drm_device *dev, int min_size)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ struct drm_gem_object *best = NULL;
+ struct drm_gem_object *first = NULL;
+
+ /* Try to find the smallest clean object */
+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
+ struct drm_gem_object *obj = &obj_priv->base;
+ if (obj->size >= min_size) {
+ if ((!obj_priv->dirty ||
+ i915_gem_object_is_purgeable(obj_priv)) &&
+ (!best || obj->size < best->size)) {
+ best = obj;
+ if (best->size == min_size)
+ return best;
+ }
+ if (!first)
+ first = obj;
+ }
+ }
+
+ return best ? best : first;
+}
+
+static int
i915_gpu_idle(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2055,6 +2078,155 @@ i915_gpu_idle(struct drm_device *dev)
return ret;
}
+static int
+i915_gem_evict_everything(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+ bool lists_empty;
+
+ spin_lock(&dev_priv->mm.active_list_lock);
+ lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
+ list_empty(&dev_priv->mm.flushing_list) &&
+ list_empty(&dev_priv->render_ring.active_list) &&
+ (!HAS_BSD(dev)
+ || list_empty(&dev_priv->bsd_ring.active_list)));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+
+ if (lists_empty)
+ return -ENOSPC;
+
+ /* Flush everything (on to the inactive lists) and evict */
+ ret = i915_gpu_idle(dev);
+ if (ret)
+ return ret;
+
+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+
+ ret = i915_gem_evict_from_inactive_list(dev);
+ if (ret)
+ return ret;
+
+ spin_lock(&dev_priv->mm.active_list_lock);
+ lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
+ list_empty(&dev_priv->mm.flushing_list) &&
+ list_empty(&dev_priv->render_ring.active_list) &&
+ (!HAS_BSD(dev)
+ || list_empty(&dev_priv->bsd_ring.active_list)));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+ BUG_ON(!lists_empty);
+
+ return 0;
+}
+
+static int
+i915_gem_evict_something(struct drm_device *dev, int min_size)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ int ret;
+
+ struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
+ struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring;
+ for (;;) {
+ i915_gem_retire_requests(dev);
+
+ /* If there's an inactive buffer available now, grab it
+ * and be done.
+ */
+ obj = i915_gem_find_inactive_object(dev, min_size);
+ if (obj) {
+ struct drm_i915_gem_object *obj_priv;
+
+#if WATCH_LRU
+ DRM_INFO("%s: evicting %p\n", __func__, obj);
+#endif
+ obj_priv = to_intel_bo(obj);
+ BUG_ON(obj_priv->pin_count != 0);
+ BUG_ON(obj_priv->active);
+
+ /* Wait on the rendering and unbind the buffer. */
+ return i915_gem_object_unbind(obj);
+ }
+
+ /* If we didn't get anything, but the ring is still processing
+ * things, wait for the next to finish and hopefully leave us
+ * a buffer to evict.
+ */
+ if (!list_empty(&render_ring->request_list)) {
+ struct drm_i915_gem_request *request;
+
+ request = list_first_entry(&render_ring->request_list,
+ struct drm_i915_gem_request,
+ list);
+
+ ret = i915_wait_request(dev,
+ request->seqno, request->ring);
+ if (ret)
+ return ret;
+
+ continue;
+ }
+
+ if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) {
+ struct drm_i915_gem_request *request;
+
+ request = list_first_entry(&bsd_ring->request_list,
+ struct drm_i915_gem_request,
+ list);
+
+ ret = i915_wait_request(dev,
+ request->seqno, request->ring);
+ if (ret)
+ return ret;
+
+ continue;
+ }
+
+ /* If we didn't have anything on the request list but there
+ * are buffers awaiting a flush, emit one and try again.
+ * When we wait on it, those buffers waiting for that flush
+ * will get moved to inactive.
+ */
+ if (!list_empty(&dev_priv->mm.flushing_list)) {
+ struct drm_i915_gem_object *obj_priv;
+
+ /* Find an object that we can immediately reuse */
+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) {
+ obj = &obj_priv->base;
+ if (obj->size >= min_size)
+ break;
+
+ obj = NULL;
+ }
+
+ if (obj != NULL) {
+ uint32_t seqno;
+
+ i915_gem_flush_ring(dev,
+ obj->write_domain,
+ obj->write_domain,
+ obj_priv->ring);
+ seqno = i915_add_request(dev, NULL,
+ obj->write_domain,
+ obj_priv->ring);
+ if (seqno == 0)
+ return -ENOMEM;
+ continue;
+ }
+ }
+
+ /* If we didn't do any of the above, there's no single buffer
+ * large enough to swap out for the new one, so just evict
+ * everything and start again. (This should be rare.)
+ */
+ if (!list_empty (&dev_priv->mm.inactive_list))
+ return i915_gem_evict_from_inactive_list(dev);
+ else
+ return i915_gem_evict_everything(dev);
+ }
+}
+
int
i915_gem_object_get_pages(struct drm_gem_object *obj,
gfp_t gfpmask)
@@ -2494,7 +2666,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
#if WATCH_LRU
DRM_INFO("%s: GTT full, evicting something\n", __func__);
#endif
- ret = i915_gem_evict_something(dev, obj->size, alignment);
+ ret = i915_gem_evict_something(dev, obj->size);
if (ret)
return ret;
@@ -2512,8 +2684,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
if (ret == -ENOMEM) {
/* first try to clear up some space from the GTT */
- ret = i915_gem_evict_something(dev, obj->size,
- alignment);
+ ret = i915_gem_evict_something(dev, obj->size);
if (ret) {
/* now try to shrink everyone else */
if (gfpmask) {
@@ -2543,7 +2714,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
drm_mm_put_block(obj_priv->gtt_space);
obj_priv->gtt_space = NULL;
- ret = i915_gem_evict_something(dev, obj->size, alignment);
+ ret = i915_gem_evict_something(dev, obj->size);
if (ret)
return ret;
@@ -2552,9 +2723,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
atomic_inc(&dev->gtt_count);
atomic_add(obj->size, &dev->gtt_memory);
- /* keep track of bounds object by adding it to the inactive list */
- list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
-
/* Assert that the object is not currently in any GPU domain. As it
* wasn't in the GTT, there shouldn't be any way it could have been in
* a GPU cache
@@ -2949,7 +3117,6 @@ static void
i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t invalidate_domains = 0;
uint32_t flush_domains = 0;
@@ -3012,13 +3179,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
obj->pending_write_domain = obj->write_domain;
obj->read_domains = obj->pending_read_domains;
- if (flush_domains & I915_GEM_GPU_DOMAINS) {
- if (obj_priv->ring == &dev_priv->render_ring)
- dev_priv->flush_rings |= FLUSH_RENDER_RING;
- else if (obj_priv->ring == &dev_priv->bsd_ring)
- dev_priv->flush_rings |= FLUSH_BSD_RING;
- }
-
dev->invalidate_domains |= invalidate_domains;
dev->flush_domains |= flush_domains;
#if WATCH_BUF
@@ -3558,6 +3718,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
ring = &dev_priv->render_ring;
}
+
if (args->buffer_count < 1) {
DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
return -EINVAL;
@@ -3731,7 +3892,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
*/
dev->invalidate_domains = 0;
dev->flush_domains = 0;
- dev_priv->flush_rings = 0;
for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];
@@ -3752,14 +3912,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
i915_gem_flush(dev,
dev->invalidate_domains,
dev->flush_domains);
- if (dev_priv->flush_rings & FLUSH_RENDER_RING)
- (void)i915_add_request(dev, file_priv,
- dev->flush_domains,
- &dev_priv->render_ring);
- if (dev_priv->flush_rings & FLUSH_BSD_RING)
+ if (dev->flush_domains & I915_GEM_GPU_DOMAINS) {
(void)i915_add_request(dev, file_priv,
- dev->flush_domains,
- &dev_priv->bsd_ring);
+ dev->flush_domains,
+ &dev_priv->render_ring);
+
+ if (HAS_BSD(dev))
+ (void)i915_add_request(dev, file_priv,
+ dev->flush_domains,
+ &dev_priv->bsd_ring);
+ }
}
for (i = 0; i < args->buffer_count; i++) {
@@ -4030,10 +4192,6 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
if (alignment == 0)
alignment = i915_gem_get_gtt_alignment(obj);
if (obj_priv->gtt_offset & (alignment - 1)) {
- WARN(obj_priv->pin_count,
- "bo is already pinned with incorrect alignment:"
- " offset=%x, req.alignment=%x\n",
- obj_priv->gtt_offset, alignment);
ret = i915_gem_object_unbind(obj);
if (ret)
return ret;
@@ -4055,7 +4213,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
atomic_inc(&dev->pin_count);
atomic_add(obj->size, &dev->pin_memory);
if (!obj_priv->active &&
- (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
+ (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0 &&
+ !list_empty(&obj_priv->list))
list_del_init(&obj_priv->list);
}
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4200,34 +4359,22 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
}
mutex_lock(&dev->struct_mutex);
-
- /* Count all active objects as busy, even if they are currently not used
- * by the gpu. Users of this interface expect objects to eventually
- * become non-busy without any further actions, therefore emit any
- * necessary flushes here.
+ /* Update the active list for the hardware's current position.
+ * Otherwise this only updates on a delayed timer or when irqs are
+ * actually unmasked, and our working set ends up being larger than
+ * required.
*/
- obj_priv = to_intel_bo(obj);
- args->busy = obj_priv->active;
- if (args->busy) {
- /* Unconditionally flush objects, even when the gpu still uses this
- * object. Userspace calling this function indicates that it wants to
- * use this buffer rather sooner than later, so issuing the required
- * flush earlier is beneficial.
- */
- if (obj->write_domain) {
- i915_gem_flush(dev, 0, obj->write_domain);
- (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring);
- }
-
- /* Update the active list for the hardware's current position.
- * Otherwise this only updates on a delayed timer or when irqs
- * are actually unmasked, and our working set ends up being
- * larger than required.
- */
- i915_gem_retire_requests_ring(dev, obj_priv->ring);
+ i915_gem_retire_requests(dev);
- args->busy = obj_priv->active;
- }
+ obj_priv = to_intel_bo(obj);
+ /* Don't count being on the flushing list against the object being
+ * done. Otherwise, a buffer left on the flushing list but not getting
+ * flushed (because nobody's flushing that domain) won't ever return
+ * unbusy and get reused by libdrm's bo cache. The other expected
+ * consumer of this interface, OpenGL's occlusion queries, also specs
+ * that the objects get unbusy "eventually" without any interference.
+ */
+ args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0;
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
@@ -4367,6 +4514,30 @@ void i915_gem_free_object(struct drm_gem_object *obj)
i915_gem_free_object_tail(obj);
}
+/** Unbinds all inactive objects. */
+static int
+i915_gem_evict_from_inactive_list(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ while (!list_empty(&dev_priv->mm.inactive_list)) {
+ struct drm_gem_object *obj;
+ int ret;
+
+ obj = &list_first_entry(&dev_priv->mm.inactive_list,
+ struct drm_i915_gem_object,
+ list)->base;
+
+ ret = i915_gem_object_unbind(obj);
+ if (ret != 0) {
+ DRM_ERROR("Error unbinding object: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
int
i915_gem_idle(struct drm_device *dev)
{
@@ -4391,7 +4562,7 @@ i915_gem_idle(struct drm_device *dev)
/* Under UMS, be paranoid and evict. */
if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = i915_gem_evict_inactive(dev);
+ ret = i915_gem_evict_from_inactive_list(dev);
if (ret) {
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -4509,8 +4680,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
goto cleanup_render_ring;
}
- dev_priv->next_seqno = 1;
-
return 0;
cleanup_render_ring:
@@ -4672,7 +4841,7 @@ i915_gem_load(struct drm_device *dev)
* e.g. for cursor + overlay regs
*/
int i915_gem_init_phys_object(struct drm_device *dev,
- int id, int size, int align)
+ int id, int size)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_phys_object *phys_obj;
@@ -4687,7 +4856,7 @@ int i915_gem_init_phys_object(struct drm_device *dev,
phys_obj->id = id;
- phys_obj->handle = drm_pci_alloc(dev, size, align);
+ phys_obj->handle = drm_pci_alloc(dev, size, 0);
if (!phys_obj->handle) {
ret = -ENOMEM;
goto kfree_obj;
@@ -4769,9 +4938,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
int
i915_gem_attach_phys_object(struct drm_device *dev,
- struct drm_gem_object *obj,
- int id,
- int align)
+ struct drm_gem_object *obj, int id)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv;
@@ -4790,10 +4957,11 @@ i915_gem_attach_phys_object(struct drm_device *dev,
i915_gem_detach_phys_object(dev, obj);
}
+
/* create a new object */
if (!dev_priv->mm.phys_objs[id - 1]) {
ret = i915_gem_init_phys_object(dev, id,
- obj->size, align);
+ obj->size);
if (ret) {
DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size);
goto out;
diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_evict.c b/trunk/drivers/gpu/drm/i915/i915_gem_evict.c
deleted file mode 100644
index 72cae3cccad8..000000000000
--- a/trunk/drivers/gpu/drm/i915/i915_gem_evict.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright © 2008-2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt
- * Chris Wilson
- *
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drv.h"
-#include "i915_drm.h"
-
-static struct drm_i915_gem_object *
-i915_gem_next_active_object(struct drm_device *dev,
- struct list_head **render_iter,
- struct list_head **bsd_iter)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL;
-
- if (*render_iter != &dev_priv->render_ring.active_list)
- render_obj = list_entry(*render_iter,
- struct drm_i915_gem_object,
- list);
-
- if (HAS_BSD(dev)) {
- if (*bsd_iter != &dev_priv->bsd_ring.active_list)
- bsd_obj = list_entry(*bsd_iter,
- struct drm_i915_gem_object,
- list);
-
- if (render_obj == NULL) {
- *bsd_iter = (*bsd_iter)->next;
- return bsd_obj;
- }
-
- if (bsd_obj == NULL) {
- *render_iter = (*render_iter)->next;
- return render_obj;
- }
-
- /* XXX can we handle seqno wrapping? */
- if (render_obj->last_rendering_seqno < bsd_obj->last_rendering_seqno) {
- *render_iter = (*render_iter)->next;
- return render_obj;
- } else {
- *bsd_iter = (*bsd_iter)->next;
- return bsd_obj;
- }
- } else {
- *render_iter = (*render_iter)->next;
- return render_obj;
- }
-}
-
-static bool
-mark_free(struct drm_i915_gem_object *obj_priv,
- struct list_head *unwind)
-{
- list_add(&obj_priv->evict_list, unwind);
- return drm_mm_scan_add_block(obj_priv->gtt_space);
-}
-
-#define i915_for_each_active_object(OBJ, R, B) \
- *(R) = dev_priv->render_ring.active_list.next; \
- *(B) = dev_priv->bsd_ring.active_list.next; \
- while (((OBJ) = i915_gem_next_active_object(dev, (R), (B))) != NULL)
-
-int
-i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct list_head eviction_list, unwind_list;
- struct drm_i915_gem_object *obj_priv, *tmp_obj_priv;
- struct list_head *render_iter, *bsd_iter;
- int ret = 0;
-
- i915_gem_retire_requests(dev);
-
- /* Re-check for free space after retiring requests */
- if (drm_mm_search_free(&dev_priv->mm.gtt_space,
- min_size, alignment, 0))
- return 0;
-
- /*
- * The goal is to evict objects and amalgamate space in LRU order.
- * The oldest idle objects reside on the inactive list, which is in
- * retirement order. The next objects to retire are those on the (per
- * ring) active list that do not have an outstanding flush. Once the
- * hardware reports completion (the seqno is updated after the
- * batchbuffer has been finished) the clean buffer objects would
- * be retired to the inactive list. Any dirty objects would be added
- * to the tail of the flushing list. So after processing the clean
- * active objects we need to emit a MI_FLUSH to retire the flushing
- * list, hence the retirement order of the flushing list is in
- * advance of the dirty objects on the active lists.
- *
- * The retirement sequence is thus:
- * 1. Inactive objects (already retired)
- * 2. Clean active objects
- * 3. Flushing list
- * 4. Dirty active objects.
- *
- * On each list, the oldest objects lie at the HEAD with the freshest
- * object on the TAIL.
- */
-
- INIT_LIST_HEAD(&unwind_list);
- drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment);
-
- /* First see if there is a large enough contiguous idle region... */
- list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
- if (mark_free(obj_priv, &unwind_list))
- goto found;
- }
-
- /* Now merge in the soon-to-be-expired objects... */
- i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) {
- /* Does the object require an outstanding flush? */
- if (obj_priv->base.write_domain || obj_priv->pin_count)
- continue;
-
- if (mark_free(obj_priv, &unwind_list))
- goto found;
- }
-
- /* Finally add anything with a pending flush (in order of retirement) */
- list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) {
- if (obj_priv->pin_count)
- continue;
-
- if (mark_free(obj_priv, &unwind_list))
- goto found;
- }
- i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) {
- if (! obj_priv->base.write_domain || obj_priv->pin_count)
- continue;
-
- if (mark_free(obj_priv, &unwind_list))
- goto found;
- }
-
- /* Nothing found, clean up and bail out! */
- list_for_each_entry(obj_priv, &unwind_list, evict_list) {
- ret = drm_mm_scan_remove_block(obj_priv->gtt_space);
- BUG_ON(ret);
- }
-
- /* We expect the caller to unpin, evict all and try again, or give up.
- * So calling i915_gem_evict_everything() is unnecessary.
- */
- return -ENOSPC;
-
-found:
- INIT_LIST_HEAD(&eviction_list);
- list_for_each_entry_safe(obj_priv, tmp_obj_priv,
- &unwind_list, evict_list) {
- if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
- /* drm_mm doesn't allow any other other operations while
- * scanning, therefore store to be evicted objects on a
- * temporary list. */
- list_move(&obj_priv->evict_list, &eviction_list);
- }
- }
-
- /* Unbinding will emit any required flushes */
- list_for_each_entry_safe(obj_priv, tmp_obj_priv,
- &eviction_list, evict_list) {
-#if WATCH_LRU
- DRM_INFO("%s: evicting %p\n", __func__, obj);
-#endif
- ret = i915_gem_object_unbind(&obj_priv->base);
- if (ret)
- return ret;
- }
-
- /* The just created free hole should be on the top of the free stack
- * maintained by drm_mm, so this BUG_ON actually executes in O(1).
- * Furthermore all accessed data has just recently been used, so it
- * should be really fast, too. */
- BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size,
- alignment, 0));
-
- return 0;
-}
-
-int
-i915_gem_evict_everything(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- int ret;
- bool lists_empty;
-
- spin_lock(&dev_priv->mm.active_list_lock);
- lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
- list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->render_ring.active_list) &&
- (!HAS_BSD(dev)
- || list_empty(&dev_priv->bsd_ring.active_list)));
- spin_unlock(&dev_priv->mm.active_list_lock);
-
- if (lists_empty)
- return -ENOSPC;
-
- /* Flush everything (on to the inactive lists) and evict */
- ret = i915_gpu_idle(dev);
- if (ret)
- return ret;
-
- BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
-
- ret = i915_gem_evict_inactive(dev);
- if (ret)
- return ret;
-
- spin_lock(&dev_priv->mm.active_list_lock);
- lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
- list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->render_ring.active_list) &&
- (!HAS_BSD(dev)
- || list_empty(&dev_priv->bsd_ring.active_list)));
- spin_unlock(&dev_priv->mm.active_list_lock);
- BUG_ON(!lists_empty);
-
- return 0;
-}
-
-/** Unbinds all inactive objects. */
-int
-i915_gem_evict_inactive(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
-
- while (!list_empty(&dev_priv->mm.inactive_list)) {
- struct drm_gem_object *obj;
- int ret;
-
- obj = &list_first_entry(&dev_priv->mm.inactive_list,
- struct drm_i915_gem_object,
- list)->base;
-
- ret = i915_gem_object_unbind(obj);
- if (ret != 0) {
- DRM_ERROR("Error unbinding object: %d\n", ret);
- return ret;
- }
- }
-
- return 0;
-}
diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c
index 16861b800fee..85785a8844ed 100644
--- a/trunk/drivers/gpu/drm/i915/i915_irq.c
+++ b/trunk/drivers/gpu/drm/i915/i915_irq.c
@@ -425,11 +425,9 @@ static struct drm_i915_error_object *
i915_error_object_create(struct drm_device *dev,
struct drm_gem_object *src)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_error_object *dst;
struct drm_i915_gem_object *src_priv;
int page, page_count;
- u32 reloc_offset;
if (src == NULL)
return NULL;
@@ -444,27 +442,18 @@ i915_error_object_create(struct drm_device *dev,
if (dst == NULL)
return NULL;
- reloc_offset = src_priv->gtt_offset;
for (page = 0; page < page_count; page++) {
+ void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
unsigned long flags;
- void __iomem *s;
- void *d;
- d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
if (d == NULL)
goto unwind;
-
local_irq_save(flags);
- s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
- reloc_offset,
- KM_IRQ0);
- memcpy_fromio(d, s, PAGE_SIZE);
- io_mapping_unmap_atomic(s, KM_IRQ0);
+ s = kmap_atomic(src_priv->pages[page], KM_IRQ0);
+ memcpy(d, s, PAGE_SIZE);
+ kunmap_atomic(s, KM_IRQ0);
local_irq_restore(flags);
-
dst->pages[page] = d;
-
- reloc_offset += PAGE_SIZE;
}
dst->page_count = page_count;
dst->gtt_offset = src_priv->gtt_offset;
@@ -500,7 +489,6 @@ i915_error_state_free(struct drm_device *dev,
i915_error_object_free(error->batchbuffer[1]);
i915_error_object_free(error->ringbuffer);
kfree(error->active_bo);
- kfree(error->overlay);
kfree(error);
}
@@ -624,57 +612,18 @@ static void i915_capture_error_state(struct drm_device *dev)
if (batchbuffer[1] == NULL &&
error->acthd >= obj_priv->gtt_offset &&
- error->acthd < obj_priv->gtt_offset + obj->size)
+ error->acthd < obj_priv->gtt_offset + obj->size &&
+ batchbuffer[0] != obj)
batchbuffer[1] = obj;
count++;
}
- /* Scan the other lists for completeness for those bizarre errors. */
- if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) {
- list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) {
- struct drm_gem_object *obj = &obj_priv->base;
-
- if (batchbuffer[0] == NULL &&
- bbaddr >= obj_priv->gtt_offset &&
- bbaddr < obj_priv->gtt_offset + obj->size)
- batchbuffer[0] = obj;
-
- if (batchbuffer[1] == NULL &&
- error->acthd >= obj_priv->gtt_offset &&
- error->acthd < obj_priv->gtt_offset + obj->size)
- batchbuffer[1] = obj;
-
- if (batchbuffer[0] && batchbuffer[1])
- break;
- }
- }
- if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) {
- list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
- struct drm_gem_object *obj = &obj_priv->base;
-
- if (batchbuffer[0] == NULL &&
- bbaddr >= obj_priv->gtt_offset &&
- bbaddr < obj_priv->gtt_offset + obj->size)
- batchbuffer[0] = obj;
-
- if (batchbuffer[1] == NULL &&
- error->acthd >= obj_priv->gtt_offset &&
- error->acthd < obj_priv->gtt_offset + obj->size)
- batchbuffer[1] = obj;
-
- if (batchbuffer[0] && batchbuffer[1])
- break;
- }
- }
/* We need to copy these to an anonymous buffer as the simplest
* method to avoid being overwritten by userpace.
*/
error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]);
- if (batchbuffer[1] != batchbuffer[0])
- error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]);
- else
- error->batchbuffer[1] = NULL;
+ error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]);
/* Record the ringbuffer */
error->ringbuffer = i915_error_object_create(dev,
@@ -718,8 +667,6 @@ static void i915_capture_error_state(struct drm_device *dev)
do_gettimeofday(&error->time);
- error->overlay = intel_overlay_capture_error_state(dev);
-
spin_lock_irqsave(&dev_priv->error_lock, flags);
if (dev_priv->first_error == NULL) {
dev_priv->first_error = error;
@@ -1304,16 +1251,6 @@ void i915_hangcheck_elapsed(unsigned long data)
&dev_priv->render_ring),
i915_get_tail_request(dev)->seqno)) {
dev_priv->hangcheck_count = 0;
-
- /* Issue a wake-up to catch stuck h/w. */
- if (dev_priv->render_ring.waiting_gem_seqno |
- dev_priv->bsd_ring.waiting_gem_seqno) {
- DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n");
- if (dev_priv->render_ring.waiting_gem_seqno)
- DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
- if (dev_priv->bsd_ring.waiting_gem_seqno)
- DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
- }
return;
}
@@ -1381,17 +1318,12 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
(void) I915_READ(DEIER);
- /* Gen6 only needs render pipe_control now */
- if (IS_GEN6(dev))
- render_mask = GT_PIPE_NOTIFY;
-
+ /* user interrupt should be enabled, but masked initial */
dev_priv->gt_irq_mask_reg = ~render_mask;
dev_priv->gt_irq_enable_reg = render_mask;
I915_WRITE(GTIIR, I915_READ(GTIIR));
I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
- if (IS_GEN6(dev))
- I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT);
I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
(void) I915_READ(GTIER);
diff --git a/trunk/drivers/gpu/drm/i915/i915_opregion.c b/trunk/drivers/gpu/drm/i915/i915_opregion.c
index ea5d3fea4b61..d1bf92b99788 100644
--- a/trunk/drivers/gpu/drm/i915/i915_opregion.c
+++ b/trunk/drivers/gpu/drm/i915/i915_opregion.c
@@ -114,6 +114,10 @@ struct opregion_asle {
#define ASLE_REQ_MSK 0xf
/* response bits of ASLE irq request */
+#define ASLE_ALS_ILLUM_FAIL (2<<10)
+#define ASLE_BACKLIGHT_FAIL (2<<12)
+#define ASLE_PFIT_FAIL (2<<14)
+#define ASLE_PWM_FREQ_FAIL (2<<16)
#define ASLE_ALS_ILLUM_FAILED (1<<10)
#define ASLE_BACKLIGHT_FAILED (1<<12)
#define ASLE_PFIT_FAILED (1<<14)
@@ -151,11 +155,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
u32 max_backlight, level, shift;
if (!(bclp & ASLE_BCLP_VALID))
- return ASLE_BACKLIGHT_FAILED;
+ return ASLE_BACKLIGHT_FAIL;
bclp &= ASLE_BCLP_MSK;
if (bclp < 0 || bclp > 255)
- return ASLE_BACKLIGHT_FAILED;
+ return ASLE_BACKLIGHT_FAIL;
blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
@@ -207,7 +211,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
/* Panel fitting is currently controlled by the X code, so this is a
noop until modesetting support works fully */
if (!(pfit & ASLE_PFIT_VALID))
- return ASLE_PFIT_FAILED;
+ return ASLE_PFIT_FAIL;
return 0;
}
diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h
index 67e3ec1a6af9..281db6e5403a 100644
--- a/trunk/drivers/gpu/drm/i915/i915_reg.h
+++ b/trunk/drivers/gpu/drm/i915/i915_reg.h
@@ -170,7 +170,6 @@
#define MI_NO_WRITE_FLUSH (1 << 2)
#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
-#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */
#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
#define MI_OVERLAY_FLIP MI_INSTR(0x11,0)
@@ -181,12 +180,6 @@
#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
-#define MI_SET_CONTEXT MI_INSTR(0x18, 0)
-#define MI_MM_SPACE_GTT (1<<8)
-#define MI_MM_SPACE_PHYSICAL (0<<8)
-#define MI_SAVE_EXT_STATE_EN (1<<3)
-#define MI_RESTORE_EXT_STATE_EN (1<<2)
-#define MI_RESTORE_INHIBIT (1<<0)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
@@ -1106,11 +1099,6 @@
#define DDRMPLL1 0X12c20
#define PEG_BAND_GAP_DATA 0x14d68
-/*
- * Logical Context regs
- */
-#define CCID 0x2180
-#define CCID_EN (1<<0)
/*
* Overlay regs
*/
@@ -2081,7 +2069,6 @@
#define PIPE_DITHER_TYPE_ST01 (1 << 2)
/* Pipe A */
#define PIPEADSL 0x70000
-#define DSL_LINEMASK 0x00000fff
#define PIPEACONF 0x70008
#define PIPEACONF_ENABLE (1<<31)
#define PIPEACONF_DISABLE 0
@@ -2941,7 +2928,6 @@
#define TRANS_DP_VSYNC_ACTIVE_LOW 0
#define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3)
#define TRANS_DP_HSYNC_ACTIVE_LOW 0
-#define TRANS_DP_SYNC_MASK (3<<3)
/* SNB eDP training params */
/* SNB A-stepping */
diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c
index 2c6b98f2440e..6e2025274db5 100644
--- a/trunk/drivers/gpu/drm/i915/i915_suspend.c
+++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c
@@ -34,7 +34,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll_reg;
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
} else {
dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
@@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe))
return;
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A)
@@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe))
return;
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A)
@@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
}
@@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
/* Pipe & plane A info */
dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
@@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveFPA1 = I915_READ(FPA1);
dev_priv->saveDPLL_A = I915_READ(DPLL_A);
}
- if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
- if (!HAS_PCH_SPLIT(dev))
+ if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
@@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
/* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
@@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveFPB1 = I915_READ(FPB1);
dev_priv->saveDPLL_B = I915_READ(DPLL_B);
}
- if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
- if (!HAS_PCH_SPLIT(dev))
+ if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
@@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dpll_a_reg = PCH_DPLL_A;
dpll_b_reg = PCH_DPLL_B;
fpa0_reg = PCH_FPA0;
@@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
fpb1_reg = FPB1;
}
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
}
@@ -395,20 +395,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A &
~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_a_reg);
- udelay(150);
+ DRM_UDELAY(150);
}
I915_WRITE(fpa0_reg, dev_priv->saveFPA0);
I915_WRITE(fpa1_reg, dev_priv->saveFPA1);
/* Actually enable it */
I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
- POSTING_READ(dpll_a_reg);
- udelay(150);
- if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) {
+ DRM_UDELAY(150);
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
- POSTING_READ(DPLL_A_MD);
- }
- udelay(150);
+ DRM_UDELAY(150);
/* Restore mode */
I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
@@ -417,10 +413,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
- if (!HAS_PCH_SPLIT(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
@@ -464,20 +460,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B &
~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_b_reg);
- udelay(150);
+ DRM_UDELAY(150);
}
I915_WRITE(fpb0_reg, dev_priv->saveFPB0);
I915_WRITE(fpb1_reg, dev_priv->saveFPB1);
/* Actually enable it */
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
- POSTING_READ(dpll_b_reg);
- udelay(150);
- if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) {
+ DRM_UDELAY(150);
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
- POSTING_READ(DPLL_B_MD);
- }
- udelay(150);
+ DRM_UDELAY(150);
/* Restore mode */
I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
@@ -486,10 +478,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
- if (!HAS_PCH_SPLIT(dev))
+ if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
@@ -554,14 +546,14 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveCURSIZE = I915_READ(CURSIZE);
/* CRT state */
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveADPA = I915_READ(PCH_ADPA);
} else {
dev_priv->saveADPA = I915_READ(ADPA);
}
/* LVDS state */
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
@@ -579,10 +571,10 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveLVDS = I915_READ(LVDS);
}
- if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
@@ -610,7 +602,7 @@ void i915_save_display(struct drm_device *dev)
/* Only save FBC state on the platform that supports FBC */
if (I915_HAS_FBC(dev)) {
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE_M(dev)) {
dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
} else if (IS_GM45(dev)) {
dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
@@ -626,7 +618,7 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveVGA0 = I915_READ(VGA0);
dev_priv->saveVGA1 = I915_READ(VGA1);
dev_priv->saveVGA_PD = I915_READ(VGA_PD);
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE(dev))
dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
else
dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
@@ -668,24 +660,24 @@ void i915_restore_display(struct drm_device *dev)
I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
/* CRT state */
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE(dev))
I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
else
I915_WRITE(ADPA, dev_priv->saveADPA);
/* LVDS state */
- if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev))
+ if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
} else if (IS_MOBILE(dev) && !IS_I830(dev))
I915_WRITE(LVDS, dev_priv->saveLVDS);
- if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
+ if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
@@ -716,7 +708,7 @@ void i915_restore_display(struct drm_device *dev)
/* only restore FBC info on the platform that supports FBC*/
if (I915_HAS_FBC(dev)) {
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE_M(dev)) {
ironlake_disable_fbc(dev);
I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
} else if (IS_GM45(dev)) {
@@ -731,15 +723,14 @@ void i915_restore_display(struct drm_device *dev)
}
}
/* VGA state */
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE(dev))
I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
else
I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
I915_WRITE(VGA0, dev_priv->saveVGA0);
I915_WRITE(VGA1, dev_priv->saveVGA1);
I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
- POSTING_READ(VGA_PD);
- udelay(150);
+ DRM_UDELAY(150);
i915_restore_vga(dev);
}
@@ -757,7 +748,7 @@ int i915_save_state(struct drm_device *dev)
i915_save_display(dev);
/* Interrupt state */
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
dev_priv->saveDEIER = I915_READ(DEIER);
dev_priv->saveDEIMR = I915_READ(DEIMR);
dev_priv->saveGTIER = I915_READ(GTIER);
@@ -771,7 +762,7 @@ int i915_save_state(struct drm_device *dev)
dev_priv->saveIMR = I915_READ(IMR);
}
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE_M(dev))
ironlake_disable_drps(dev);
/* Cache mode state */
@@ -829,7 +820,7 @@ int i915_restore_state(struct drm_device *dev)
i915_restore_display(dev);
/* Interrupt state */
- if (HAS_PCH_SPLIT(dev)) {
+ if (IS_IRONLAKE(dev)) {
I915_WRITE(DEIER, dev_priv->saveDEIER);
I915_WRITE(DEIMR, dev_priv->saveDEIMR);
I915_WRITE(GTIER, dev_priv->saveGTIER);
@@ -844,7 +835,7 @@ int i915_restore_state(struct drm_device *dev)
/* Clock gating state */
intel_init_clock_gating(dev);
- if (HAS_PCH_SPLIT(dev))
+ if (IS_IRONLAKE_M(dev))
ironlake_enable_drps(dev);
/* Cache mode state */
diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c
index 4b7735196cd5..ee0732b222a1 100644
--- a/trunk/drivers/gpu/drm/i915/intel_crt.c
+++ b/trunk/drivers/gpu/drm/i915/intel_crt.c
@@ -160,20 +160,19 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 adpa, temp;
bool ret;
- bool turn_off_dac = false;
temp = adpa = I915_READ(PCH_ADPA);
- if (HAS_PCH_SPLIT(dev))
- turn_off_dac = true;
-
- adpa &= ~ADPA_CRT_HOTPLUG_MASK;
- if (turn_off_dac)
- adpa &= ~ADPA_DAC_ENABLE;
-
- /* disable HPD first */
- I915_WRITE(PCH_ADPA, adpa);
- (void)I915_READ(PCH_ADPA);
+ if (HAS_PCH_CPT(dev)) {
+ /* Disable DAC before force detect */
+ I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE);
+ (void)I915_READ(PCH_ADPA);
+ } else {
+ adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+ /* disable HPD first */
+ I915_WRITE(PCH_ADPA, adpa);
+ (void)I915_READ(PCH_ADPA);
+ }
adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
ADPA_CRT_HOTPLUG_WARMUP_10MS |
@@ -186,11 +185,10 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
I915_WRITE(PCH_ADPA, adpa);
- if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
- 1000, 1))
- DRM_ERROR("timed out waiting for FORCE_TRIGGER");
+ while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
+ ;
- if (turn_off_dac) {
+ if (HAS_PCH_CPT(dev)) {
I915_WRITE(PCH_ADPA, temp);
(void)I915_READ(PCH_ADPA);
}
@@ -239,13 +237,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
for (i = 0; i < tries ; i++) {
+ unsigned long timeout;
/* turn on the FORCE_DETECT */
I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+ timeout = jiffies + msecs_to_jiffies(1000);
/* wait for FORCE_DETECT to go off */
- if (wait_for((I915_READ(PORT_HOTPLUG_EN) &
- CRT_HOTPLUG_FORCE_DETECT) == 0,
- 1000, 1))
- DRM_ERROR("timed out waiting for FORCE_DETECT to go off");
+ do {
+ if (!(I915_READ(PORT_HOTPLUG_EN) &
+ CRT_HOTPLUG_FORCE_DETECT))
+ break;
+ msleep(1);
+ } while (time_after(timeout, jiffies));
}
stat = I915_READ(PORT_HOTPLUG_STAT);
@@ -329,7 +331,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
/* Wait for next Vblank to substitue
* border color for Color info */
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev);
st00 = I915_READ8(VGA_MSR_WRITE);
status = ((st00 & (1 << 4)) != 0) ?
connector_status_connected :
@@ -506,8 +508,17 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs
.best_encoder = intel_attached_encoder,
};
+static void intel_crt_enc_destroy(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+
+ intel_i2c_destroy(intel_encoder->ddc_bus);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
+}
+
static const struct drm_encoder_funcs intel_crt_enc_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_crt_enc_destroy,
};
void intel_crt_init(struct drm_device *dev)
diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c
index 23157e1de3be..5ec10e02341b 100644
--- a/trunk/drivers/gpu/drm/i915/intel_display.c
+++ b/trunk/drivers/gpu/drm/i915/intel_display.c
@@ -29,7 +29,6 @@
#include
#include
#include
-#include
#include "drmP.h"
#include "intel_drv.h"
#include "i915_drm.h"
@@ -977,54 +976,14 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
return true;
}
-/**
- * intel_wait_for_vblank - wait for vblank on a given pipe
- * @dev: drm device
- * @pipe: pipe to wait for
- *
- * Wait for vblank to occur on a given pipe. Needed for various bits of
- * mode setting code.
- */
-void intel_wait_for_vblank(struct drm_device *dev, int pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
-
- /* Wait for vblank interrupt bit to set */
- if (wait_for((I915_READ(pipestat_reg) &
- PIPE_VBLANK_INTERRUPT_STATUS) == 0,
- 50, 0))
- DRM_DEBUG_KMS("vblank wait timed out\n");
-}
-
-/**
- * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
- * @dev: drm device
- * @pipe: pipe to wait for
- *
- * After disabling a pipe, we can't wait for vblank in the usual way,
- * spinning on the vblank interrupt status bit, since we won't actually
- * see an interrupt when the pipe is disabled.
- *
- * So this function waits for the display line value to settle (it
- * usually ends up stopping at the start of the next frame).
- */
-void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
+void
+intel_wait_for_vblank(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
- unsigned long timeout = jiffies + msecs_to_jiffies(100);
- u32 last_line;
-
- /* Wait for the display line to settle */
- do {
- last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
- mdelay(5);
- } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
- time_after(timeout, jiffies));
-
- if (time_after(jiffies, timeout))
- DRM_DEBUG_KMS("vblank wait timed out\n");
+ /* Wait for 20ms, i.e. one cycle at 50hz. */
+ if (in_dbg_master())
+ mdelay(20); /* The kernel debugger cannot call msleep() */
+ else
+ msleep(20);
}
/* Parameters have changed, update FBC info */
@@ -1078,6 +1037,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
void i8xx_disable_fbc(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long timeout = jiffies + msecs_to_jiffies(1);
u32 fbc_ctl;
if (!I915_HAS_FBC(dev))
@@ -1092,11 +1052,16 @@ void i8xx_disable_fbc(struct drm_device *dev)
I915_WRITE(FBC_CONTROL, fbc_ctl);
/* Wait for compressing bit to clear */
- if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) {
- DRM_DEBUG_KMS("FBC idle timed out\n");
- return;
+ while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) {
+ if (time_after(jiffies, timeout)) {
+ DRM_DEBUG_DRIVER("FBC idle timed out\n");
+ break;
+ }
+ ; /* do nothing */
}
+ intel_wait_for_vblank(dev);
+
DRM_DEBUG_KMS("disabled FBC\n");
}
@@ -1153,6 +1118,7 @@ void g4x_disable_fbc(struct drm_device *dev)
dpfc_ctl = I915_READ(DPFC_CONTROL);
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(DPFC_CONTROL, dpfc_ctl);
+ intel_wait_for_vblank(dev);
DRM_DEBUG_KMS("disabled FBC\n");
}
@@ -1213,6 +1179,7 @@ void ironlake_disable_fbc(struct drm_device *dev)
dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+ intel_wait_for_vblank(dev);
DRM_DEBUG_KMS("disabled FBC\n");
}
@@ -1511,7 +1478,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if ((IS_I965G(dev) || plane == 0))
intel_update_fbc(crtc, &crtc->mode);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
intel_increase_pllclock(crtc, true);
return 0;
@@ -1618,18 +1585,20 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
Start, Offset, x, y, crtc->fb->pitch);
I915_WRITE(dspstride, crtc->fb->pitch);
if (IS_I965G(dev)) {
+ I915_WRITE(dspbase, Offset);
+ I915_READ(dspbase);
I915_WRITE(dspsurf, Start);
+ I915_READ(dspsurf);
I915_WRITE(dsptileoff, (y << 16) | x);
- I915_WRITE(dspbase, Offset);
} else {
I915_WRITE(dspbase, Start + Offset);
+ I915_READ(dspbase);
}
- POSTING_READ(dspbase);
if ((IS_I965G(dev) || plane == 0))
intel_update_fbc(crtc, &crtc->mode);
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev);
if (old_fb) {
intel_fb = to_intel_framebuffer(old_fb);
@@ -1658,6 +1627,54 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
+/* Disable the VGA plane that we never use */
+static void i915_disable_vga (struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u8 sr1;
+ u32 vga_reg;
+
+ if (HAS_PCH_SPLIT(dev))
+ vga_reg = CPU_VGACNTRL;
+ else
+ vga_reg = VGACNTRL;
+
+ if (I915_READ(vga_reg) & VGA_DISP_DISABLE)
+ return;
+
+ I915_WRITE8(VGA_SR_INDEX, 1);
+ sr1 = I915_READ8(VGA_SR_DATA);
+ I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5));
+ udelay(100);
+
+ I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+}
+
+static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpa_ctl;
+
+ DRM_DEBUG_KMS("\n");
+ dpa_ctl = I915_READ(DP_A);
+ dpa_ctl &= ~DP_PLL_ENABLE;
+ I915_WRITE(DP_A, dpa_ctl);
+}
+
+static void ironlake_enable_pll_edp (struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpa_ctl;
+
+ dpa_ctl = I915_READ(DP_A);
+ dpa_ctl |= DP_PLL_ENABLE;
+ I915_WRITE(DP_A, dpa_ctl);
+ udelay(200);
+}
+
+
static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock)
{
struct drm_device *dev = crtc->dev;
@@ -1928,6 +1945,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B;
int trans_dpll_sel = (pipe == 0) ? 0 : 1;
u32 temp;
+ int n;
u32 pipe_bpc;
temp = I915_READ(pipeconf_reg);
@@ -1940,7 +1958,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
- DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane);
+ DRM_DEBUG_KMS("crtc %d dpms on\n", pipe);
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
temp = I915_READ(PCH_LVDS);
@@ -1950,7 +1968,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
}
}
- if (!HAS_eDP) {
+ if (HAS_eDP) {
+ /* enable eDP PLL */
+ ironlake_enable_pll_edp(crtc);
+ } else {
/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
temp = I915_READ(fdi_rx_reg);
@@ -1984,13 +2005,15 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Enable panel fitting for LVDS */
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
|| HAS_eDP || intel_pch_has_edp(crtc)) {
- if (dev_priv->pch_pf_size) {
- temp = I915_READ(pf_ctl_reg);
- I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
- I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos);
- I915_WRITE(pf_win_size, dev_priv->pch_pf_size);
- } else
- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+ temp = I915_READ(pf_ctl_reg);
+ I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
+
+ /* currently full aspect */
+ I915_WRITE(pf_win_pos, 0);
+
+ I915_WRITE(pf_win_size,
+ (dev_priv->panel_fixed_mode->hdisplay << 16) |
+ (dev_priv->panel_fixed_mode->vdisplay));
}
/* Enable CPU pipe */
@@ -2074,10 +2097,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
int reg;
reg = I915_READ(trans_dp_ctl);
- reg &= ~(TRANS_DP_PORT_SEL_MASK |
- TRANS_DP_SYNC_MASK);
- reg |= (TRANS_DP_OUTPUT_ENABLE |
- TRANS_DP_ENH_FRAMING);
+ reg &= ~TRANS_DP_PORT_SEL_MASK;
+ reg = TRANS_DP_OUTPUT_ENABLE |
+ TRANS_DP_ENH_FRAMING;
if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
reg |= TRANS_DP_HSYNC_ACTIVE_HIGH;
@@ -2115,17 +2137,18 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_WRITE(transconf_reg, temp | TRANS_ENABLE);
I915_READ(transconf_reg);
- if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0))
- DRM_ERROR("failed to enable transcoder\n");
+ while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0)
+ ;
+
}
intel_crtc_load_lut(crtc);
intel_update_fbc(crtc, &crtc->mode);
- break;
+ break;
case DRM_MODE_DPMS_OFF:
- DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane);
+ DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
drm_vblank_off(dev, pipe);
/* Disable display plane */
@@ -2141,14 +2164,26 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
+ i915_disable_vga(dev);
+
/* disable cpu pipe, disable after all planes disabled */
temp = I915_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-
+ I915_READ(pipeconf_reg);
+ n = 0;
/* wait for cpu pipe off, pipe state */
- if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1))
- DRM_ERROR("failed to turn off cpu pipe\n");
+ while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) {
+ n++;
+ if (n < 60) {
+ udelay(500);
+ continue;
+ } else {
+ DRM_DEBUG_KMS("pipe %d off delay\n",
+ pipe);
+ break;
+ }
+ }
} else
DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
@@ -2209,10 +2244,20 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
temp = I915_READ(transconf_reg);
if ((temp & TRANS_ENABLE) != 0) {
I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE);
-
+ I915_READ(transconf_reg);
+ n = 0;
/* wait for PCH transcoder off, transcoder state */
- if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1))
- DRM_ERROR("failed to disable transcoder\n");
+ while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) {
+ n++;
+ if (n < 60) {
+ udelay(500);
+ continue;
+ } else {
+ DRM_DEBUG_KMS("transcoder %d off "
+ "delay\n", pipe);
+ break;
+ }
+ }
}
temp = I915_READ(transconf_reg);
@@ -2249,6 +2294,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE);
I915_READ(pch_dpll_reg);
+ if (HAS_eDP) {
+ ironlake_disable_pll_edp(crtc);
+ }
+
/* Switch from PCDclk to Rawclk */
temp = I915_READ(fdi_rx_reg);
temp &= ~FDI_SEL_PCDCLK;
@@ -2323,6 +2372,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
+ intel_update_watermarks(dev);
+
/* Enable the DPLL */
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) == 0) {
@@ -2362,6 +2413,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
intel_crtc_dpms_overlay(intel_crtc, true);
break;
case DRM_MODE_DPMS_OFF:
+ intel_update_watermarks(dev);
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, false);
drm_vblank_off(dev, pipe);
@@ -2370,6 +2423,9 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
+ /* Disable the VGA plane that we never use */
+ i915_disable_vga(dev);
+
/* Disable display plane */
temp = I915_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -2379,8 +2435,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(dspbase_reg);
}
- /* Wait for vblank for the disable to take effect */
- intel_wait_for_vblank_off(dev, pipe);
+ if (!IS_I9XX(dev)) {
+ /* Wait for vblank for the disable to take effect */
+ intel_wait_for_vblank(dev);
+ }
/* Don't disable pipe A or pipe A PLLs if needed */
if (pipeconf_reg == PIPEACONF &&
@@ -2395,7 +2453,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
}
/* Wait for vblank for the disable to take effect. */
- intel_wait_for_vblank_off(dev, pipe);
+ intel_wait_for_vblank(dev);
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -2411,6 +2469,9 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
/**
* Sets the power management mode of the pipe and plane.
+ *
+ * This code should probably grow support for turning the cursor off and back
+ * on appropriately at the same time as we're turning the pipe off/on.
*/
static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
{
@@ -2421,26 +2482,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
int pipe = intel_crtc->pipe;
bool enabled;
- intel_crtc->dpms_mode = mode;
- intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON;
-
- /* When switching on the display, ensure that SR is disabled
- * with multiple pipes prior to enabling to new pipe.
- *
- * When switching off the display, make sure the cursor is
- * properly hidden prior to disabling the pipe.
- */
- if (mode == DRM_MODE_DPMS_ON)
- intel_update_watermarks(dev);
- else
- intel_crtc_update_cursor(crtc);
-
dev_priv->display.dpms(crtc, mode);
- if (mode == DRM_MODE_DPMS_ON)
- intel_crtc_update_cursor(crtc);
- else
- intel_update_watermarks(dev);
+ intel_crtc->dpms_mode = mode;
if (!dev->primary->master)
return;
@@ -2492,20 +2536,6 @@ void intel_encoder_commit (struct drm_encoder *encoder)
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
}
-void intel_encoder_destroy(struct drm_encoder *encoder)
-{
- struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
-
- if (intel_encoder->ddc_bus)
- intel_i2c_destroy(intel_encoder->ddc_bus);
-
- if (intel_encoder->i2c_bus)
- intel_i2c_destroy(intel_encoder->i2c_bus);
-
- drm_encoder_cleanup(encoder);
- kfree(intel_encoder);
-}
-
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -2837,7 +2867,7 @@ struct cxsr_latency {
unsigned long cursor_hpll_disable;
};
-static const struct cxsr_latency cxsr_latency_table[] = {
+static struct cxsr_latency cxsr_latency_table[] = {
{1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */
{1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */
{1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */
@@ -2875,13 +2905,11 @@ static const struct cxsr_latency cxsr_latency_table[] = {
{0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */
};
-static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop,
- int is_ddr3,
- int fsb,
- int mem)
+static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3,
+ int fsb, int mem)
{
- const struct cxsr_latency *latency;
int i;
+ struct cxsr_latency *latency;
if (fsb == 0 || mem == 0)
return NULL;
@@ -2902,9 +2930,13 @@ static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop,
static void pineview_disable_cxsr(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 reg;
/* deactivate cxsr */
- I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN);
+ reg = I915_READ(DSPFW3);
+ reg &= ~(PINEVIEW_SELF_REFRESH_EN);
+ I915_WRITE(DSPFW3, reg);
+ DRM_INFO("Big FIFO is disabled\n");
}
/*
@@ -2992,12 +3024,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
int pixel_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct cxsr_latency *latency;
u32 reg;
unsigned long wm;
+ struct cxsr_latency *latency;
int sr_clock;
- latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3,
+ latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3,
dev_priv->fsb_freq, dev_priv->mem_freq);
if (!latency) {
DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
@@ -3043,8 +3075,9 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock,
DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
/* activate cxsr */
- I915_WRITE(DSPFW3,
- I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN);
+ reg = I915_READ(DSPFW3);
+ reg |= PINEVIEW_SELF_REFRESH_EN;
+ I915_WRITE(DSPFW3, reg);
DRM_DEBUG_KMS("Self-refresh is enabled\n");
} else {
pineview_disable_cxsr(dev);
@@ -3321,11 +3354,12 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock,
int line_count;
int planea_htotal = 0, planeb_htotal = 0;
struct drm_crtc *crtc;
+ struct intel_crtc *intel_crtc;
/* Need htotal for all active display plane */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
+ intel_crtc = to_intel_crtc(crtc);
+ if (crtc->enabled) {
if (intel_crtc->plane == 0)
planea_htotal = crtc->mode.htotal;
else
@@ -3485,6 +3519,7 @@ static void intel_update_watermarks(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
+ struct intel_crtc *intel_crtc;
int sr_hdisplay = 0;
unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
int enabled = 0, pixel_size = 0;
@@ -3495,8 +3530,8 @@ static void intel_update_watermarks(struct drm_device *dev)
/* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
+ intel_crtc = to_intel_crtc(crtc);
+ if (crtc->enabled) {
enabled++;
if (intel_crtc->plane == 0) {
DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
@@ -3931,7 +3966,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
dpll_reg = pch_dpll_reg;
}
- if (!is_edp) {
+ if (is_edp) {
+ ironlake_disable_pll_edp(crtc);
+ } else if ((dpll & DPLL_VCO_ENABLE)) {
I915_WRITE(fp_reg, fp);
I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
I915_READ(dpll_reg);
@@ -4130,7 +4167,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(pipeconf_reg, pipeconf);
I915_READ(pipeconf_reg);
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev);
if (IS_IRONLAKE(dev)) {
/* enable address swizzle for tiling buffer */
@@ -4143,6 +4180,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* Flush the plane changes */
ret = intel_pipe_set_base(crtc, x, y, old_fb);
+ if ((IS_I965G(dev) || plane == 0))
+ intel_update_fbc(crtc, &crtc->mode);
+
intel_update_watermarks(dev);
drm_vblank_post_modeset(dev, pipe);
@@ -4176,62 +4216,6 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
}
}
-static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- bool visible = base != 0;
- u32 cntl;
-
- if (intel_crtc->cursor_visible == visible)
- return;
-
- cntl = I915_READ(CURACNTR);
- if (visible) {
- /* On these chipsets we can only modify the base whilst
- * the cursor is disabled.
- */
- I915_WRITE(CURABASE, base);
-
- cntl &= ~(CURSOR_FORMAT_MASK);
- /* XXX width must be 64, stride 256 => 0x00 << 28 */
- cntl |= CURSOR_ENABLE |
- CURSOR_GAMMA_ENABLE |
- CURSOR_FORMAT_ARGB;
- } else
- cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
- I915_WRITE(CURACNTR, cntl);
-
- intel_crtc->cursor_visible = visible;
-}
-
-static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
- bool visible = base != 0;
-
- if (intel_crtc->cursor_visible != visible) {
- uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
- if (base) {
- cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
- cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
- cntl |= pipe << 28; /* Connect to correct pipe */
- } else {
- cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
- cntl |= CURSOR_MODE_DISABLE;
- }
- I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);
-
- intel_crtc->cursor_visible = visible;
- }
- /* and commit changes on next vblank */
- I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);
-}
-
/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
static void intel_crtc_update_cursor(struct drm_crtc *crtc)
{
@@ -4241,12 +4225,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe;
int x = intel_crtc->cursor_x;
int y = intel_crtc->cursor_y;
- u32 base, pos;
+ uint32_t base, pos;
bool visible;
pos = 0;
- if (intel_crtc->cursor_on && crtc->fb) {
+ if (crtc->fb) {
base = intel_crtc->cursor_addr;
if (x > (int) crtc->fb->width)
base = 0;
@@ -4275,14 +4259,37 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc)
pos |= y << CURSOR_Y_SHIFT;
visible = base != 0;
- if (!visible && !intel_crtc->cursor_visible)
+ if (!visible && !intel_crtc->cursor_visble)
return;
I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos);
- if (IS_845G(dev) || IS_I865G(dev))
- i845_update_cursor(crtc, base);
- else
- i9xx_update_cursor(crtc, base);
+ if (intel_crtc->cursor_visble != visible) {
+ uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
+ if (base) {
+ /* Hooray for CUR*CNTR differences */
+ if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+ cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+ cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+ cntl |= pipe << 28; /* Connect to correct pipe */
+ } else {
+ cntl &= ~(CURSOR_FORMAT_MASK);
+ cntl |= CURSOR_ENABLE;
+ cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+ }
+ } else {
+ if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+ cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
+ cntl |= CURSOR_MODE_DISABLE;
+ } else {
+ cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
+ }
+ }
+ I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);
+
+ intel_crtc->cursor_visble = visible;
+ }
+ /* and commit changes on next vblank */
+ I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);
if (visible)
intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
@@ -4347,10 +4354,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
addr = obj_priv->gtt_offset;
} else {
- int align = IS_I830(dev) ? 16 * 1024 : 256;
ret = i915_gem_attach_phys_object(dev, bo,
- (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1,
- align);
+ (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
if (ret) {
DRM_ERROR("failed to attach phys object\n");
goto fail_locked;
@@ -4539,7 +4544,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
encoder_funcs->commit(encoder);
}
/* let the connector get through one full cycle before testing */
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
return crtc;
}
@@ -4744,7 +4749,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
dpll &= ~DISPLAY_RATE_SELECT_FPA1;
I915_WRITE(dpll_reg, dpll);
dpll = I915_READ(dpll_reg);
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev);
dpll = I915_READ(dpll_reg);
if (dpll & DISPLAY_RATE_SELECT_FPA1)
DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
@@ -4788,7 +4793,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
dpll |= DISPLAY_RATE_SELECT_FPA1;
I915_WRITE(dpll_reg, dpll);
dpll = I915_READ(dpll_reg);
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev);
dpll = I915_READ(dpll_reg);
if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
@@ -5078,16 +5083,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->pending_flip_obj = obj;
if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+ flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+ flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
- if (IS_GEN3(dev) || IS_GEN2(dev)) {
- BEGIN_LP_RING(2);
- OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
- OUT_RING(0);
- ADVANCE_LP_RING();
- }
+ /* Wait for any previous flip to finish */
+ if (IS_GEN3(dev))
+ while (I915_READ(ISR) & flip_mask)
+ ;
/* Offset into the new buffer for cases of shared fbs between CRTCs */
offset = obj_priv->gtt_offset;
@@ -5101,14 +5104,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
OUT_RING(offset | obj_priv->tiling_mode);
pipesrc = I915_READ(pipesrc_reg);
OUT_RING(pipesrc & 0x0fff0fff);
- } else if (IS_GEN3(dev)) {
- OUT_RING(MI_DISPLAY_FLIP_I915 |
- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
- OUT_RING(fb->pitch);
- OUT_RING(offset);
- OUT_RING(MI_NOOP);
} else {
- OUT_RING(MI_DISPLAY_FLIP |
+ OUT_RING(MI_DISPLAY_FLIP_I915 |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
OUT_RING(fb->pitch);
OUT_RING(offset);
@@ -5435,37 +5432,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
};
static struct drm_gem_object *
-intel_alloc_context_page(struct drm_device *dev)
+intel_alloc_power_context(struct drm_device *dev)
{
- struct drm_gem_object *ctx;
+ struct drm_gem_object *pwrctx;
int ret;
- ctx = i915_gem_alloc_object(dev, 4096);
- if (!ctx) {
+ pwrctx = i915_gem_alloc_object(dev, 4096);
+ if (!pwrctx) {
DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
return NULL;
}
mutex_lock(&dev->struct_mutex);
- ret = i915_gem_object_pin(ctx, 4096);
+ ret = i915_gem_object_pin(pwrctx, 4096);
if (ret) {
DRM_ERROR("failed to pin power context: %d\n", ret);
goto err_unref;
}
- ret = i915_gem_object_set_to_gtt_domain(ctx, 1);
+ ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1);
if (ret) {
DRM_ERROR("failed to set-domain on power context: %d\n", ret);
goto err_unpin;
}
mutex_unlock(&dev->struct_mutex);
- return ctx;
+ return pwrctx;
err_unpin:
- i915_gem_object_unpin(ctx);
+ i915_gem_object_unpin(pwrctx);
err_unref:
- drm_gem_object_unreference(ctx);
+ drm_gem_object_unreference(pwrctx);
mutex_unlock(&dev->struct_mutex);
return NULL;
}
@@ -5497,6 +5494,7 @@ void ironlake_enable_drps(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 rgvmodectl = I915_READ(MEMMODECTL);
u8 fmax, fmin, fstart, vstart;
+ int i = 0;
/* 100ms RC evaluation intervals */
I915_WRITE(RCUPEI, 100000);
@@ -5540,8 +5538,13 @@ void ironlake_enable_drps(struct drm_device *dev)
rgvmodectl |= MEMMODE_SWMODE_EN;
I915_WRITE(MEMMODECTL, rgvmodectl);
- if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0))
- DRM_ERROR("stuck trying to change perf mode\n");
+ while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) {
+ if (i++ > 100) {
+ DRM_ERROR("stuck trying to change perf mode\n");
+ break;
+ }
+ msleep(1);
+ }
msleep(1);
ironlake_set_drps(dev, fstart);
@@ -5722,8 +5725,7 @@ void intel_init_clock_gating(struct drm_device *dev)
ILK_DPFC_DIS2 |
ILK_CLK_FBC);
}
- if (IS_GEN6(dev))
- return;
+ return;
} else if (IS_G4X(dev)) {
uint32_t dspclk_gate;
I915_WRITE(RENCLK_GATE_D1, 0);
@@ -5766,31 +5768,6 @@ void intel_init_clock_gating(struct drm_device *dev)
* GPU can automatically power down the render unit if given a page
* to save state.
*/
- if (IS_IRONLAKE_M(dev)) {
- if (dev_priv->renderctx == NULL)
- dev_priv->renderctx = intel_alloc_context_page(dev);
- if (dev_priv->renderctx) {
- struct drm_i915_gem_object *obj_priv;
- obj_priv = to_intel_bo(dev_priv->renderctx);
- if (obj_priv) {
- BEGIN_LP_RING(4);
- OUT_RING(MI_SET_CONTEXT);
- OUT_RING(obj_priv->gtt_offset |
- MI_MM_SPACE_GTT |
- MI_SAVE_EXT_STATE_EN |
- MI_RESTORE_EXT_STATE_EN |
- MI_RESTORE_INHIBIT);
- OUT_RING(MI_NOOP);
- OUT_RING(MI_FLUSH);
- ADVANCE_LP_RING();
- }
- } else {
- DRM_DEBUG_KMS("Failed to allocate render context."
- "Disable RC6\n");
- return;
- }
- }
-
if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) {
struct drm_i915_gem_object *obj_priv = NULL;
@@ -5799,7 +5776,7 @@ void intel_init_clock_gating(struct drm_device *dev)
} else {
struct drm_gem_object *pwrctx;
- pwrctx = intel_alloc_context_page(dev);
+ pwrctx = intel_alloc_power_context(dev);
if (pwrctx) {
dev_priv->pwrctx = pwrctx;
obj_priv = to_intel_bo(pwrctx);
@@ -5971,29 +5948,6 @@ static void intel_init_quirks(struct drm_device *dev)
}
}
-/* Disable the VGA plane that we never use */
-static void i915_disable_vga(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u8 sr1;
- u32 vga_reg;
-
- if (HAS_PCH_SPLIT(dev))
- vga_reg = CPU_VGACNTRL;
- else
- vga_reg = VGACNTRL;
-
- vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
- outb(1, VGA_SR_INDEX);
- sr1 = inb(VGA_SR_DATA);
- outb(sr1 | 1<<5, VGA_SR_DATA);
- vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
- udelay(300);
-
- I915_WRITE(vga_reg, VGA_DISP_DISABLE);
- POSTING_READ(vga_reg);
-}
-
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6042,9 +5996,6 @@ void intel_modeset_init(struct drm_device *dev)
intel_init_clock_gating(dev);
- /* Just disable it once at startup */
- i915_disable_vga(dev);
-
if (IS_IRONLAKE_M(dev)) {
ironlake_enable_drps(dev);
intel_init_emon(dev);
@@ -6083,16 +6034,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
if (dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
- if (dev_priv->renderctx) {
- struct drm_i915_gem_object *obj_priv;
-
- obj_priv = to_intel_bo(dev_priv->renderctx);
- I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN);
- I915_READ(CCID);
- i915_gem_object_unpin(dev_priv->renderctx);
- drm_gem_object_unreference(dev_priv->renderctx);
- }
-
if (dev_priv->pwrctx) {
struct drm_i915_gem_object *obj_priv;
diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c
index 9caccd03dccb..40be1fa65be1 100644
--- a/trunk/drivers/gpu/drm/i915/intel_dp.c
+++ b/trunk/drivers/gpu/drm/i915/intel_dp.c
@@ -42,11 +42,10 @@
#define DP_LINK_CONFIGURATION_SIZE 9
-#define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP)
-#define IS_PCH_eDP(i) ((i)->is_pch_edp)
+#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
+#define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp)
-struct intel_dp {
- struct intel_encoder base;
+struct intel_dp_priv {
uint32_t output_reg;
uint32_t DP;
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
@@ -55,39 +54,40 @@ struct intel_dp {
uint8_t link_bw;
uint8_t lane_count;
uint8_t dpcd[4];
+ struct intel_encoder *intel_encoder;
struct i2c_adapter adapter;
struct i2c_algo_dp_aux_data algo;
bool is_pch_edp;
};
-static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base);
-}
+static void
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
+ uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
-static void intel_dp_link_train(struct intel_dp *intel_dp);
-static void intel_dp_link_down(struct intel_dp *intel_dp);
+static void
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
void
intel_edp_link_config (struct intel_encoder *intel_encoder,
- int *lane_num, int *link_bw)
+ int *lane_num, int *link_bw)
{
- struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
- *lane_num = intel_dp->lane_count;
- if (intel_dp->link_bw == DP_LINK_BW_1_62)
+ *lane_num = dp_priv->lane_count;
+ if (dp_priv->link_bw == DP_LINK_BW_1_62)
*link_bw = 162000;
- else if (intel_dp->link_bw == DP_LINK_BW_2_7)
+ else if (dp_priv->link_bw == DP_LINK_BW_2_7)
*link_bw = 270000;
}
static int
-intel_dp_max_lane_count(struct intel_dp *intel_dp)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
{
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int max_lane_count = 4;
- if (intel_dp->dpcd[0] >= 0x11) {
- max_lane_count = intel_dp->dpcd[2] & 0x1f;
+ if (dp_priv->dpcd[0] >= 0x11) {
+ max_lane_count = dp_priv->dpcd[2] & 0x1f;
switch (max_lane_count) {
case 1: case 2: case 4:
break;
@@ -99,9 +99,10 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp)
}
static int
-intel_dp_max_link_bw(struct intel_dp *intel_dp)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
{
- int max_link_bw = intel_dp->dpcd[1];
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ int max_link_bw = dp_priv->dpcd[1];
switch (max_link_bw) {
case DP_LINK_BW_1_62:
@@ -125,11 +126,13 @@ intel_dp_link_clock(uint8_t link_bw)
/* I think this is a fiction */
static int
-intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock)
+intel_dp_link_required(struct drm_device *dev,
+ struct intel_encoder *intel_encoder, int pixel_clock)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv))
return (pixel_clock * dev_priv->edp_bpp) / 8;
else
return pixel_clock * 3;
@@ -146,13 +149,14 @@ intel_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
- int max_lanes = intel_dp_max_lane_count(intel_dp);
+ int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+ int max_lanes = intel_dp_max_lane_count(intel_encoder);
- if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
+ if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
dev_priv->panel_fixed_mode) {
if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay)
return MODE_PANEL;
@@ -163,8 +167,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
/* only refuse the mode on non eDP since we have seen some wierd eDP panels
which are outside spec tolerances but somehow work by magic */
- if (!IS_eDP(intel_dp) &&
- (intel_dp_link_required(connector->dev, intel_dp, mode->clock)
+ if (!IS_eDP(intel_encoder) &&
+ (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
> intel_dp_max_data_rate(max_link_clock, max_lanes)))
return MODE_CLOCK_HIGH;
@@ -228,12 +232,13 @@ intel_hrawclk(struct drm_device *dev)
}
static int
-intel_dp_aux_ch(struct intel_dp *intel_dp,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
uint8_t *send, int send_bytes,
uint8_t *recv, int recv_size)
{
- uint32_t output_reg = intel_dp->output_reg;
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ uint32_t output_reg = dp_priv->output_reg;
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t ch_ctl = output_reg + 0x10;
uint32_t ch_data = ch_ctl + 4;
@@ -248,7 +253,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
* and would like to run at 2MHz. So, take the
* hrawclk value and divide by 2 and use that
*/
- if (IS_eDP(intel_dp)) {
+ if (IS_eDP(intel_encoder)) {
if (IS_GEN6(dev))
aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
else
@@ -339,7 +344,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
/* Write data to the aux channel in native mode */
static int
-intel_dp_aux_native_write(struct intel_dp *intel_dp,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t *send, int send_bytes)
{
int ret;
@@ -356,7 +361,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
memcpy(&msg[4], send, send_bytes);
msg_bytes = send_bytes + 4;
for (;;) {
- ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
+ ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -371,15 +376,15 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
/* Write a single byte to the aux channel in native mode */
static int
-intel_dp_aux_native_write_1(struct intel_dp *intel_dp,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t byte)
{
- return intel_dp_aux_native_write(intel_dp, address, &byte, 1);
+ return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
}
/* read bytes from a native aux channel */
static int
-intel_dp_aux_native_read(struct intel_dp *intel_dp,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t *recv, int recv_bytes)
{
uint8_t msg[4];
@@ -398,7 +403,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp,
reply_bytes = recv_bytes + 1;
for (;;) {
- ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
+ ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
reply, reply_bytes);
if (ret == 0)
return -EPROTO;
@@ -421,9 +426,10 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
- struct intel_dp *intel_dp = container_of(adapter,
- struct intel_dp,
- adapter);
+ struct intel_dp_priv *dp_priv = container_of(adapter,
+ struct intel_dp_priv,
+ adapter);
+ struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
uint16_t address = algo_data->address;
uint8_t msg[5];
uint8_t reply[2];
@@ -462,7 +468,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
for (;;) {
- ret = intel_dp_aux_ch(intel_dp,
+ ret = intel_dp_aux_ch(intel_encoder,
msg, msg_bytes,
reply, reply_bytes);
if (ret < 0) {
@@ -490,42 +496,57 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
static int
-intel_dp_i2c_init(struct intel_dp *intel_dp,
+intel_dp_i2c_init(struct intel_encoder *intel_encoder,
struct intel_connector *intel_connector, const char *name)
{
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+
DRM_DEBUG_KMS("i2c_init %s\n", name);
- intel_dp->algo.running = false;
- intel_dp->algo.address = 0;
- intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch;
-
- memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter));
- intel_dp->adapter.owner = THIS_MODULE;
- intel_dp->adapter.class = I2C_CLASS_DDC;
- strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
- intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
- intel_dp->adapter.algo_data = &intel_dp->algo;
- intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
-
- return i2c_dp_aux_add_bus(&intel_dp->adapter);
+ dp_priv->algo.running = false;
+ dp_priv->algo.address = 0;
+ dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch;
+
+ memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter));
+ dp_priv->adapter.owner = THIS_MODULE;
+ dp_priv->adapter.class = I2C_CLASS_DDC;
+ strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
+ dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
+ dp_priv->adapter.algo_data = &dp_priv->algo;
+ dp_priv->adapter.dev.parent = &intel_connector->base.kdev;
+
+ return i2c_dp_aux_add_bus(&dp_priv->adapter);
}
static bool
intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
int lane_count, clock;
- int max_lane_count = intel_dp_max_lane_count(intel_dp);
- int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
+ int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+ int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
- if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
+ if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
dev_priv->panel_fixed_mode) {
- intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
- intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN,
- mode, adjusted_mode);
+ struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
+
+ adjusted_mode->hdisplay = fixed_mode->hdisplay;
+ adjusted_mode->hsync_start = fixed_mode->hsync_start;
+ adjusted_mode->hsync_end = fixed_mode->hsync_end;
+ adjusted_mode->htotal = fixed_mode->htotal;
+
+ adjusted_mode->vdisplay = fixed_mode->vdisplay;
+ adjusted_mode->vsync_start = fixed_mode->vsync_start;
+ adjusted_mode->vsync_end = fixed_mode->vsync_end;
+ adjusted_mode->vtotal = fixed_mode->vtotal;
+
+ adjusted_mode->clock = fixed_mode->clock;
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+
/*
* the mode->clock is used to calculate the Data&Link M/N
* of the pipe. For the eDP the fixed clock should be used.
@@ -537,33 +558,31 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
- if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock)
+ if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
<= link_avail) {
- intel_dp->link_bw = bws[clock];
- intel_dp->lane_count = lane_count;
- adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+ dp_priv->link_bw = bws[clock];
+ dp_priv->lane_count = lane_count;
+ adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
DRM_DEBUG_KMS("Display port link bw %02x lane "
"count %d clock %d\n",
- intel_dp->link_bw, intel_dp->lane_count,
+ dp_priv->link_bw, dp_priv->lane_count,
adjusted_mode->clock);
return true;
}
}
}
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
/* okay we failed just pick the highest */
- intel_dp->lane_count = max_lane_count;
- intel_dp->link_bw = bws[max_clock];
- adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+ dp_priv->lane_count = max_lane_count;
+ dp_priv->link_bw = bws[max_clock];
+ adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
"count %d clock %d\n",
- intel_dp->link_bw, intel_dp->lane_count,
+ dp_priv->link_bw, dp_priv->lane_count,
adjusted_mode->clock);
-
return true;
}
-
return false;
}
@@ -607,14 +626,17 @@ bool intel_pch_has_edp(struct drm_crtc *crtc)
struct drm_encoder *encoder;
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
- struct intel_dp *intel_dp;
+ struct intel_encoder *intel_encoder;
+ struct intel_dp_priv *dp_priv;
- if (encoder->crtc != crtc)
+ if (!encoder || encoder->crtc != crtc)
continue;
- intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
- return intel_dp->is_pch_edp;
+ intel_encoder = enc_to_intel_encoder(encoder);
+ dp_priv = intel_encoder->dev_priv;
+
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT)
+ return dp_priv->is_pch_edp;
}
return false;
}
@@ -635,15 +657,18 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
* Find the lane count in the intel_encoder private
*/
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
- struct intel_dp *intel_dp;
+ struct intel_encoder *intel_encoder;
+ struct intel_dp_priv *dp_priv;
if (encoder->crtc != crtc)
continue;
- intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
- lane_count = intel_dp->lane_count;
- if (IS_PCH_eDP(intel_dp))
+ intel_encoder = enc_to_intel_encoder(encoder);
+ dp_priv = intel_encoder->dev_priv;
+
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+ lane_count = dp_priv->lane_count;
+ if (IS_PCH_eDP(dp_priv))
bpp = dev_priv->edp_bpp;
break;
}
@@ -699,114 +724,107 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_crtc *crtc = intel_dp->base.enc.crtc;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct drm_crtc *crtc = intel_encoder->enc.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- intel_dp->DP = (DP_VOLTAGE_0_4 |
+ dp_priv->DP = (DP_VOLTAGE_0_4 |
DP_PRE_EMPHASIS_0);
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
- intel_dp->DP |= DP_SYNC_HS_HIGH;
+ dp_priv->DP |= DP_SYNC_HS_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
- intel_dp->DP |= DP_SYNC_VS_HIGH;
+ dp_priv->DP |= DP_SYNC_VS_HIGH;
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
- intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
+ dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT;
else
- intel_dp->DP |= DP_LINK_TRAIN_OFF;
+ dp_priv->DP |= DP_LINK_TRAIN_OFF;
- switch (intel_dp->lane_count) {
+ switch (dp_priv->lane_count) {
case 1:
- intel_dp->DP |= DP_PORT_WIDTH_1;
+ dp_priv->DP |= DP_PORT_WIDTH_1;
break;
case 2:
- intel_dp->DP |= DP_PORT_WIDTH_2;
+ dp_priv->DP |= DP_PORT_WIDTH_2;
break;
case 4:
- intel_dp->DP |= DP_PORT_WIDTH_4;
+ dp_priv->DP |= DP_PORT_WIDTH_4;
break;
}
- if (intel_dp->has_audio)
- intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
+ if (dp_priv->has_audio)
+ dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE;
- memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
- intel_dp->link_configuration[0] = intel_dp->link_bw;
- intel_dp->link_configuration[1] = intel_dp->lane_count;
+ memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+ dp_priv->link_configuration[0] = dp_priv->link_bw;
+ dp_priv->link_configuration[1] = dp_priv->lane_count;
/*
* Check for DPCD version > 1.1 and enhanced framing support
*/
- if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
- intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
- intel_dp->DP |= DP_ENHANCED_FRAMING;
+ if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) {
+ dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+ dp_priv->DP |= DP_ENHANCED_FRAMING;
}
/* CPT DP's pipe select is decided in TRANS_DP_CTL */
if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
- intel_dp->DP |= DP_PIPEB_SELECT;
+ dp_priv->DP |= DP_PIPEB_SELECT;
- if (IS_eDP(intel_dp)) {
+ if (IS_eDP(intel_encoder)) {
/* don't miss out required setting for eDP */
- intel_dp->DP |= DP_PLL_ENABLE;
+ dp_priv->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
- intel_dp->DP |= DP_PLL_FREQ_160MHZ;
+ dp_priv->DP |= DP_PLL_FREQ_160MHZ;
else
- intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+ dp_priv->DP |= DP_PLL_FREQ_270MHZ;
}
}
static void ironlake_edp_panel_on (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 pp;
+ unsigned long timeout = jiffies + msecs_to_jiffies(5000);
+ u32 pp, pp_status;
- if (I915_READ(PCH_PP_STATUS) & PP_ON)
+ pp_status = I915_READ(PCH_PP_STATUS);
+ if (pp_status & PP_ON)
return;
pp = I915_READ(PCH_PP_CONTROL);
-
- /* ILK workaround: disable reset around power sequence */
- pp &= ~PANEL_POWER_RESET;
- I915_WRITE(PCH_PP_CONTROL, pp);
- POSTING_READ(PCH_PP_CONTROL);
-
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
+ do {
+ pp_status = I915_READ(PCH_PP_STATUS);
+ } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout));
- if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10))
- DRM_ERROR("panel on wait timed out: 0x%08x\n",
- I915_READ(PCH_PP_STATUS));
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status);
pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
- pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
- POSTING_READ(PCH_PP_CONTROL);
}
static void ironlake_edp_panel_off (struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 pp;
+ unsigned long timeout = jiffies + msecs_to_jiffies(5000);
+ u32 pp, pp_status;
pp = I915_READ(PCH_PP_CONTROL);
-
- /* ILK workaround: disable reset around power sequence */
- pp &= ~PANEL_POWER_RESET;
- I915_WRITE(PCH_PP_CONTROL, pp);
- POSTING_READ(PCH_PP_CONTROL);
-
pp &= ~POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
+ do {
+ pp_status = I915_READ(PCH_PP_STATUS);
+ } while ((pp_status & PP_ON) && !time_after(jiffies, timeout));
- if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10))
- DRM_ERROR("panel off wait timed out: 0x%08x\n",
- I915_READ(PCH_PP_STATUS));
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("panel off wait timed out\n");
/* Make sure VDD is enabled so DP AUX will work */
- pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */
+ pp |= EDP_FORCE_VDD;
I915_WRITE(PCH_PP_CONTROL, pp);
- POSTING_READ(PCH_PP_CONTROL);
}
static void ironlake_edp_backlight_on (struct drm_device *dev)
@@ -831,87 +849,33 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
I915_WRITE(PCH_PP_CONTROL, pp);
}
-static void ironlake_edp_pll_on(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpa_ctl;
-
- DRM_DEBUG_KMS("\n");
- dpa_ctl = I915_READ(DP_A);
- dpa_ctl &= ~DP_PLL_ENABLE;
- I915_WRITE(DP_A, dpa_ctl);
-}
-
-static void ironlake_edp_pll_off(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpa_ctl;
-
- dpa_ctl = I915_READ(DP_A);
- dpa_ctl |= DP_PLL_ENABLE;
- I915_WRITE(DP_A, dpa_ctl);
- udelay(200);
-}
-
-static void intel_dp_prepare(struct drm_encoder *encoder)
-{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t dp_reg = I915_READ(intel_dp->output_reg);
-
- if (IS_eDP(intel_dp)) {
- ironlake_edp_backlight_off(dev);
- ironlake_edp_panel_on(dev);
- ironlake_edp_pll_on(encoder);
- }
- if (dp_reg & DP_PORT_EN)
- intel_dp_link_down(intel_dp);
-}
-
-static void intel_dp_commit(struct drm_encoder *encoder)
-{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t dp_reg = I915_READ(intel_dp->output_reg);
-
- if (!(dp_reg & DP_PORT_EN)) {
- intel_dp_link_train(intel_dp);
- }
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
- ironlake_edp_backlight_on(dev);
-}
-
static void
intel_dp_dpms(struct drm_encoder *encoder, int mode)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t dp_reg = I915_READ(intel_dp->output_reg);
+ uint32_t dp_reg = I915_READ(dp_priv->output_reg);
if (mode != DRM_MODE_DPMS_ON) {
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
- ironlake_edp_backlight_off(dev);
- ironlake_edp_panel_off(dev);
+ if (dp_reg & DP_PORT_EN) {
+ intel_dp_link_down(intel_encoder, dp_priv->DP);
+ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
+ ironlake_edp_backlight_off(dev);
+ ironlake_edp_panel_off(dev);
+ }
}
- if (dp_reg & DP_PORT_EN)
- intel_dp_link_down(intel_dp);
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
- ironlake_edp_pll_off(encoder);
} else {
if (!(dp_reg & DP_PORT_EN)) {
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
+ intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
ironlake_edp_panel_on(dev);
- intel_dp_link_train(intel_dp);
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp))
ironlake_edp_backlight_on(dev);
+ }
}
}
- intel_dp->dpms_mode = mode;
+ dp_priv->dpms_mode = mode;
}
/*
@@ -919,12 +883,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
* link status information
*/
static bool
-intel_dp_get_link_status(struct intel_dp *intel_dp,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
uint8_t link_status[DP_LINK_STATUS_SIZE])
{
int ret;
- ret = intel_dp_aux_native_read(intel_dp,
+ ret = intel_dp_aux_native_read(intel_encoder,
DP_LANE0_1_STATUS,
link_status, DP_LINK_STATUS_SIZE);
if (ret != DP_LINK_STATUS_SIZE)
@@ -1001,7 +965,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
}
static void
-intel_get_adjust_train(struct intel_dp *intel_dp,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane_count,
uint8_t train_set[4])
@@ -1137,27 +1101,27 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
}
static bool
-intel_dp_set_link_train(struct intel_dp *intel_dp,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
uint32_t dp_reg_value,
uint8_t dp_train_pat,
uint8_t train_set[4],
bool first)
{
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int ret;
- I915_WRITE(intel_dp->output_reg, dp_reg_value);
- POSTING_READ(intel_dp->output_reg);
+ I915_WRITE(dp_priv->output_reg, dp_reg_value);
+ POSTING_READ(dp_priv->output_reg);
if (first)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
- intel_dp_aux_native_write_1(intel_dp,
+ intel_dp_aux_native_write_1(intel_encoder,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
- ret = intel_dp_aux_native_write(intel_dp,
+ ret = intel_dp_aux_native_write(intel_encoder,
DP_TRAINING_LANE0_SET, train_set, 4);
if (ret != 4)
return false;
@@ -1166,10 +1130,12 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
}
static void
-intel_dp_link_train(struct intel_dp *intel_dp)
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
+ uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
{
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t train_set[4];
uint8_t link_status[DP_LINK_STATUS_SIZE];
int i;
@@ -1179,15 +1145,13 @@ intel_dp_link_train(struct intel_dp *intel_dp)
bool first = true;
int tries;
u32 reg;
- uint32_t DP = intel_dp->DP;
/* Write the link configuration data */
- intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
- intel_dp->link_configuration,
- DP_LINK_CONFIGURATION_SIZE);
+ intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET,
+ link_configuration, DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
DP &= ~DP_LINK_TRAIN_MASK_CPT;
else
DP &= ~DP_LINK_TRAIN_MASK;
@@ -1198,39 +1162,39 @@ intel_dp_link_train(struct intel_dp *intel_dp)
for (;;) {
/* Use train_set[0] to set the voltage and pre emphasis values */
uint32_t signal_levels;
- if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
+ if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count);
+ signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_1;
- if (!intel_dp_set_link_train(intel_dp, reg,
+ if (!intel_dp_set_link_train(intel_encoder, reg,
DP_TRAINING_PATTERN_1, train_set, first))
break;
first = false;
/* Set training pattern 1 */
udelay(100);
- if (!intel_dp_get_link_status(intel_dp, link_status))
+ if (!intel_dp_get_link_status(intel_encoder, link_status))
break;
- if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+ if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
clock_recovery = true;
break;
}
/* Check to see if we've tried the max voltage */
- for (i = 0; i < intel_dp->lane_count; i++)
+ for (i = 0; i < dp_priv->lane_count; i++)
if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
- if (i == intel_dp->lane_count)
+ if (i == dp_priv->lane_count)
break;
/* Check to see if we've tried the same voltage 5 times */
@@ -1243,7 +1207,7 @@ intel_dp_link_train(struct intel_dp *intel_dp)
voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Compute new train_set as requested by target */
- intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
+ intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
}
/* channel equalization */
@@ -1253,30 +1217,30 @@ intel_dp_link_train(struct intel_dp *intel_dp)
/* Use train_set[0] to set the voltage and pre emphasis values */
uint32_t signal_levels;
- if (IS_GEN6(dev) && IS_eDP(intel_dp)) {
+ if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count);
+ signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
else
reg = DP | DP_LINK_TRAIN_PAT_2;
/* channel eq pattern */
- if (!intel_dp_set_link_train(intel_dp, reg,
+ if (!intel_dp_set_link_train(intel_encoder, reg,
DP_TRAINING_PATTERN_2, train_set,
false))
break;
udelay(400);
- if (!intel_dp_get_link_status(intel_dp, link_status))
+ if (!intel_dp_get_link_status(intel_encoder, link_status))
break;
- if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) {
+ if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
channel_eq = true;
break;
}
@@ -1286,53 +1250,53 @@ intel_dp_link_train(struct intel_dp *intel_dp)
break;
/* Compute new train_set as requested by target */
- intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set);
+ intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
++tries;
}
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp))
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
reg = DP | DP_LINK_TRAIN_OFF;
- I915_WRITE(intel_dp->output_reg, reg);
- POSTING_READ(intel_dp->output_reg);
- intel_dp_aux_native_write_1(intel_dp,
+ I915_WRITE(dp_priv->output_reg, reg);
+ POSTING_READ(dp_priv->output_reg);
+ intel_dp_aux_native_write_1(intel_encoder,
DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
}
static void
-intel_dp_link_down(struct intel_dp *intel_dp)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
{
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t DP = intel_dp->DP;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
DRM_DEBUG_KMS("\n");
- if (IS_eDP(intel_dp)) {
+ if (IS_eDP(intel_encoder)) {
DP &= ~DP_PLL_ENABLE;
- I915_WRITE(intel_dp->output_reg, DP);
- POSTING_READ(intel_dp->output_reg);
+ I915_WRITE(dp_priv->output_reg, DP);
+ POSTING_READ(dp_priv->output_reg);
udelay(100);
}
- if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) {
+ if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) {
DP &= ~DP_LINK_TRAIN_MASK_CPT;
- I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
- POSTING_READ(intel_dp->output_reg);
+ I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
+ POSTING_READ(dp_priv->output_reg);
} else {
DP &= ~DP_LINK_TRAIN_MASK;
- I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
- POSTING_READ(intel_dp->output_reg);
+ I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
+ POSTING_READ(dp_priv->output_reg);
}
udelay(17000);
- if (IS_eDP(intel_dp))
+ if (IS_eDP(intel_encoder))
DP |= DP_LINK_TRAIN_OFF;
- I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
- POSTING_READ(intel_dp->output_reg);
+ I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
+ POSTING_READ(dp_priv->output_reg);
}
/*
@@ -1345,39 +1309,41 @@ intel_dp_link_down(struct intel_dp *intel_dp)
*/
static void
-intel_dp_check_link_status(struct intel_dp *intel_dp)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
{
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t link_status[DP_LINK_STATUS_SIZE];
- if (!intel_dp->base.enc.crtc)
+ if (!intel_encoder->enc.crtc)
return;
- if (!intel_dp_get_link_status(intel_dp, link_status)) {
- intel_dp_link_down(intel_dp);
+ if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+ intel_dp_link_down(intel_encoder, dp_priv->DP);
return;
}
- if (!intel_channel_eq_ok(link_status, intel_dp->lane_count))
- intel_dp_link_train(intel_dp);
+ if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
+ intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
}
static enum drm_connector_status
ironlake_dp_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
enum drm_connector_status status;
status = connector_status_disconnected;
- if (intel_dp_aux_native_read(intel_dp,
- 0x000, intel_dp->dpcd,
- sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
+ if (intel_dp_aux_native_read(intel_encoder,
+ 0x000, dp_priv->dpcd,
+ sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
{
- if (intel_dp->dpcd[0] != 0)
+ if (dp_priv->dpcd[0] != 0)
status = connector_status_connected;
}
- DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
- intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
+ DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0],
+ dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]);
return status;
}
@@ -1391,18 +1357,19 @@ static enum drm_connector_status
intel_dp_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t temp, bit;
enum drm_connector_status status;
- intel_dp->has_audio = false;
+ dp_priv->has_audio = false;
if (HAS_PCH_SPLIT(dev))
return ironlake_dp_detect(connector);
- switch (intel_dp->output_reg) {
+ switch (dp_priv->output_reg) {
case DP_B:
bit = DPB_HOTPLUG_INT_STATUS;
break;
@@ -1422,11 +1389,11 @@ intel_dp_detect(struct drm_connector *connector)
return connector_status_disconnected;
status = connector_status_disconnected;
- if (intel_dp_aux_native_read(intel_dp,
- 0x000, intel_dp->dpcd,
- sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
+ if (intel_dp_aux_native_read(intel_encoder,
+ 0x000, dp_priv->dpcd,
+ sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
{
- if (intel_dp->dpcd[0] != 0)
+ if (dp_priv->dpcd[0] != 0)
status = connector_status_connected;
}
return status;
@@ -1435,17 +1402,18 @@ intel_dp_detect(struct drm_connector *connector)
static int intel_dp_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = intel_dp->base.enc.dev;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int ret;
/* We should parse the EDID data and find out if it has an audio sink
*/
- ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus);
+ ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
if (ret) {
- if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) &&
+ if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) &&
!dev_priv->panel_fixed_mode) {
struct drm_display_mode *newmode;
list_for_each_entry(newmode, &connector->probed_modes,
@@ -1462,7 +1430,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
}
/* if eDP has no EDID, try to use fixed panel mode from VBT */
- if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) {
+ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) {
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1484,9 +1452,9 @@ intel_dp_destroy (struct drm_connector *connector)
static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
.dpms = intel_dp_dpms,
.mode_fixup = intel_dp_mode_fixup,
- .prepare = intel_dp_prepare,
+ .prepare = intel_encoder_prepare,
.mode_set = intel_dp_mode_set,
- .commit = intel_dp_commit,
+ .commit = intel_encoder_commit,
};
static const struct drm_connector_funcs intel_dp_connector_funcs = {
@@ -1502,17 +1470,27 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
.best_encoder = intel_attached_encoder,
};
+static void intel_dp_enc_destroy(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
+}
+
static const struct drm_encoder_funcs intel_dp_enc_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_dp_enc_destroy,
};
void
intel_dp_hot_plug(struct intel_encoder *intel_encoder)
{
- struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
- if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON)
- intel_dp_check_link_status(intel_dp);
+ if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
+ intel_dp_check_link_status(intel_encoder);
}
/* Return which DP Port should be selected for Transcoder DP control */
@@ -1522,18 +1500,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_encoder *encoder;
+ struct intel_encoder *intel_encoder = NULL;
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
- struct intel_dp *intel_dp;
-
if (encoder->crtc != crtc)
continue;
- intel_dp = enc_to_intel_dp(encoder);
- if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
- return intel_dp->output_reg;
+ intel_encoder = enc_to_intel_encoder(encoder);
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ return dp_priv->output_reg;
+ }
}
-
return -1;
}
@@ -1562,28 +1540,30 @@ intel_dp_init(struct drm_device *dev, int output_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_dp *intel_dp;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
+ struct intel_dp_priv *dp_priv;
const char *name = NULL;
int type;
- intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL);
- if (!intel_dp)
+ intel_encoder = kcalloc(sizeof(struct intel_encoder) +
+ sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
+ if (!intel_encoder)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_dp);
+ kfree(intel_encoder);
return;
}
- intel_encoder = &intel_dp->base;
- if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
+ dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
+
+ if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D))
if (intel_dpd_is_edp(dev))
- intel_dp->is_pch_edp = true;
+ dp_priv->is_pch_edp = true;
- if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
+ if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
type = DRM_MODE_CONNECTOR_eDP;
intel_encoder->type = INTEL_OUTPUT_EDP;
} else {
@@ -1604,16 +1584,18 @@ intel_dp_init(struct drm_device *dev, int output_reg)
else if (output_reg == DP_D || output_reg == PCH_DP_D)
intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
- if (IS_eDP(intel_dp))
+ if (IS_eDP(intel_encoder))
intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
- intel_dp->output_reg = output_reg;
- intel_dp->has_audio = false;
- intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
+ dp_priv->intel_encoder = intel_encoder;
+ dp_priv->output_reg = output_reg;
+ dp_priv->has_audio = false;
+ dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
+ intel_encoder->dev_priv = dp_priv;
drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
DRM_MODE_ENCODER_TMDS);
@@ -1648,12 +1630,12 @@ intel_dp_init(struct drm_device *dev, int output_reg)
break;
}
- intel_dp_i2c_init(intel_dp, intel_connector, name);
+ intel_dp_i2c_init(intel_encoder, intel_connector, name);
- intel_encoder->ddc_bus = &intel_dp->adapter;
+ intel_encoder->ddc_bus = &dp_priv->adapter;
intel_encoder->hot_plug = intel_dp_hot_plug;
- if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) {
+ if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) {
/* initialize panel mode from VBT if available for eDP */
if (dev_priv->lfp_lvds_vbt_mode) {
dev_priv->panel_fixed_mode =
diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h
index 0e92aa07b382..b2190148703a 100644
--- a/trunk/drivers/gpu/drm/i915/intel_drv.h
+++ b/trunk/drivers/gpu/drm/i915/intel_drv.h
@@ -32,20 +32,6 @@
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
-
-#define wait_for(COND, MS, W) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
- int ret__ = 0; \
- while (! (COND)) { \
- if (time_after(jiffies, timeout__)) { \
- ret__ = -ETIMEDOUT; \
- break; \
- } \
- if (W) msleep(W); \
- } \
- ret__; \
-})
-
/*
* Display related stuff
*/
@@ -116,6 +102,7 @@ struct intel_encoder {
struct i2c_adapter *ddc_bus;
bool load_detect_temp;
bool needs_tv_clock;
+ void *dev_priv;
void (*hot_plug)(struct intel_encoder *);
int crtc_mask;
int clone_mask;
@@ -123,6 +110,7 @@ struct intel_encoder {
struct intel_connector {
struct drm_connector base;
+ void *dev_priv;
};
struct intel_crtc;
@@ -168,7 +156,7 @@ struct intel_crtc {
uint32_t cursor_addr;
int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height;
- bool cursor_visible, cursor_on;
+ bool cursor_visble;
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -200,18 +188,10 @@ extern bool intel_dpd_is_edp(struct drm_device *dev);
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
-extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
- struct drm_display_mode *adjusted_mode);
-extern void intel_pch_panel_fitting(struct drm_device *dev,
- int fitting_mode,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-
extern int intel_panel_fitter_pipe (struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
extern void intel_encoder_prepare (struct drm_encoder *encoder);
extern void intel_encoder_commit (struct drm_encoder *encoder);
-extern void intel_encoder_destroy(struct drm_encoder *encoder);
extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector);
@@ -219,8 +199,7 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
struct drm_crtc *crtc);
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
-extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
+extern void intel_wait_for_vblank(struct drm_device *dev);
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
struct drm_connector *connector,
diff --git a/trunk/drivers/gpu/drm/i915/intel_dvo.c b/trunk/drivers/gpu/drm/i915/intel_dvo.c
index a399f4b2c1c5..227feca7cf8d 100644
--- a/trunk/drivers/gpu/drm/i915/intel_dvo.c
+++ b/trunk/drivers/gpu/drm/i915/intel_dvo.c
@@ -38,7 +38,7 @@
#define CH7xxx_ADDR 0x76
#define TFP410_ADDR 0x38
-static const struct intel_dvo_device intel_dvo_devices[] = {
+static struct intel_dvo_device intel_dvo_devices[] = {
{
.type = INTEL_DVO_CHIP_TMDS,
.name = "sil164",
@@ -77,33 +77,20 @@ static const struct intel_dvo_device intel_dvo_devices[] = {
}
};
-struct intel_dvo {
- struct intel_encoder base;
-
- struct intel_dvo_device dev;
-
- struct drm_display_mode *panel_fixed_mode;
- bool panel_wants_dither;
-};
-
-static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base);
-}
-
static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_i915_private *dev_priv = encoder->dev->dev_private;
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
- u32 dvo_reg = intel_dvo->dev.dvo_reg;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
+ u32 dvo_reg = dvo->dvo_reg;
u32 temp = I915_READ(dvo_reg);
if (mode == DRM_MODE_DPMS_ON) {
I915_WRITE(dvo_reg, temp | DVO_ENABLE);
I915_READ(dvo_reg);
- intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
+ dvo->dev_ops->dpms(dvo, mode);
} else {
- intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
+ dvo->dev_ops->dpms(dvo, mode);
I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
I915_READ(dvo_reg);
}
@@ -113,36 +100,38 @@ static int intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
/* XXX: Validate clock range */
- if (intel_dvo->panel_fixed_mode) {
- if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay)
+ if (dvo->panel_fixed_mode) {
+ if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay)
return MODE_PANEL;
- if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay)
+ if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay)
return MODE_PANEL;
}
- return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
+ return dvo->dev_ops->mode_valid(dvo, mode);
}
static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
/* If we have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
* with the panel scaling set up to source from the H/VDisplay
* of the original mode.
*/
- if (intel_dvo->panel_fixed_mode != NULL) {
-#define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x
+ if (dvo->panel_fixed_mode != NULL) {
+#define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x
C(hdisplay);
C(hsync_start);
C(hsync_end);
@@ -156,8 +145,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
#undef C
}
- if (intel_dvo->dev.dev_ops->mode_fixup)
- return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode);
+ if (dvo->dev_ops->mode_fixup)
+ return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode);
return true;
}
@@ -169,10 +158,11 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
int pipe = intel_crtc->pipe;
u32 dvo_val;
- u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg;
+ u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
switch (dvo_reg) {
@@ -188,7 +178,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
break;
}
- intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode);
+ dvo->dev_ops->mode_set(dvo, mode, adjusted_mode);
/* Save the data order, since I don't know what it should be set to. */
dvo_val = I915_READ(dvo_reg) &
@@ -224,38 +214,40 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
- return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
+ return dvo->dev_ops->detect(dvo);
}
static int intel_dvo_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
/* We should probably have an i2c driver get_modes function for those
* devices which will have a fixed set of modes determined by the chip
* (TV-out, for example), but for now with just TMDS and LVDS,
* that's not the case.
*/
- intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus);
+ intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
if (!list_empty(&connector->probed_modes))
return 1;
- if (intel_dvo->panel_fixed_mode != NULL) {
+
+ if (dvo->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
- mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode);
+ mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
if (mode) {
drm_mode_probed_add(connector, mode);
return 1;
}
}
-
return 0;
}
-static void intel_dvo_destroy(struct drm_connector *connector)
+static void intel_dvo_destroy (struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
@@ -285,20 +277,28 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs
static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
{
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
-
- if (intel_dvo->dev.dev_ops->destroy)
- intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
-
- kfree(intel_dvo->panel_fixed_mode);
-
- intel_encoder_destroy(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
+
+ if (dvo) {
+ if (dvo->dev_ops->destroy)
+ dvo->dev_ops->destroy(dvo);
+ if (dvo->panel_fixed_mode)
+ kfree(dvo->panel_fixed_mode);
+ }
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
.destroy = intel_dvo_enc_destroy,
};
+
/**
* Attempts to get a fixed panel timing for LVDS (currently only the i830).
*
@@ -306,13 +306,15 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
* chip being on DVOB/C and having multiple pipes.
*/
static struct drm_display_mode *
-intel_dvo_get_current_mode(struct drm_connector *connector)
+intel_dvo_get_current_mode (struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
- uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
+ uint32_t dvo_reg = dvo->dvo_reg;
+ uint32_t dvo_val = I915_READ(dvo_reg);
struct drm_display_mode *mode = NULL;
/* If the DVO port is active, that'll be the LVDS, so we can pull out
@@ -325,6 +327,7 @@ intel_dvo_get_current_mode(struct drm_connector *connector)
crtc = intel_get_crtc_from_pipe(dev, pipe);
if (crtc) {
mode = intel_crtc_mode_get(dev, crtc);
+
if (mode) {
mode->type |= DRM_MODE_TYPE_PREFERRED;
if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
@@ -334,32 +337,28 @@ intel_dvo_get_current_mode(struct drm_connector *connector)
}
}
}
-
return mode;
}
void intel_dvo_init(struct drm_device *dev)
{
struct intel_encoder *intel_encoder;
- struct intel_dvo *intel_dvo;
struct intel_connector *intel_connector;
+ struct intel_dvo_device *dvo;
struct i2c_adapter *i2cbus = NULL;
int ret = 0;
int i;
int encoder_type = DRM_MODE_ENCODER_NONE;
-
- intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL);
- if (!intel_dvo)
+ intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+ if (!intel_encoder)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_dvo);
+ kfree(intel_encoder);
return;
}
- intel_encoder = &intel_dvo->base;
-
/* Set up the DDC bus */
intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
if (!intel_encoder->ddc_bus)
@@ -368,9 +367,10 @@ void intel_dvo_init(struct drm_device *dev)
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
struct drm_connector *connector = &intel_connector->base;
- const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
int gpio;
+ dvo = &intel_dvo_devices[i];
+
/* Allow the I2C driver info to specify the GPIO to be used in
* special cases, but otherwise default to what's defined
* in the spec.
@@ -393,8 +393,11 @@ void intel_dvo_init(struct drm_device *dev)
continue;
}
- intel_dvo->dev = *dvo;
- ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus);
+ if (dvo->dev_ops!= NULL)
+ ret = dvo->dev_ops->init(dvo, i2cbus);
+ else
+ ret = false;
+
if (!ret)
continue;
@@ -426,6 +429,9 @@ void intel_dvo_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
+ intel_encoder->dev_priv = dvo;
+ intel_encoder->i2c_bus = i2cbus;
+
drm_encoder_init(dev, &intel_encoder->enc,
&intel_dvo_enc_funcs, encoder_type);
drm_encoder_helper_add(&intel_encoder->enc,
@@ -441,9 +447,9 @@ void intel_dvo_init(struct drm_device *dev)
* headers, likely), so for now, just get the current
* mode being output through DVO.
*/
- intel_dvo->panel_fixed_mode =
+ dvo->panel_fixed_mode =
intel_dvo_get_current_mode(connector);
- intel_dvo->panel_wants_dither = true;
+ dvo->panel_wants_dither = true;
}
drm_sysfs_connector_add(connector);
@@ -455,6 +461,6 @@ void intel_dvo_init(struct drm_device *dev)
if (i2cbus != NULL)
intel_i2c_destroy(i2cbus);
free_intel:
- kfree(intel_dvo);
+ kfree(intel_encoder);
kfree(intel_connector);
}
diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c
index ccd4c97e6524..197887ed1823 100644
--- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c
@@ -37,17 +37,11 @@
#include "i915_drm.h"
#include "i915_drv.h"
-struct intel_hdmi {
- struct intel_encoder base;
+struct intel_hdmi_priv {
u32 sdvox_reg;
bool has_hdmi_sink;
};
-static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base);
-}
-
static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -56,7 +50,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
u32 sdvox;
sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE;
@@ -65,7 +60,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
- if (intel_hdmi->has_hdmi_sink) {
+ if (hdmi_priv->has_hdmi_sink) {
sdvox |= SDVO_AUDIO_ENABLE;
if (HAS_PCH_CPT(dev))
sdvox |= HDMI_MODE_SELECT;
@@ -78,25 +73,26 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
sdvox |= SDVO_PIPE_B_SELECT;
}
- I915_WRITE(intel_hdmi->sdvox_reg, sdvox);
- POSTING_READ(intel_hdmi->sdvox_reg);
+ I915_WRITE(hdmi_priv->sdvox_reg, sdvox);
+ POSTING_READ(hdmi_priv->sdvox_reg);
}
static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
u32 temp;
- temp = I915_READ(intel_hdmi->sdvox_reg);
+ temp = I915_READ(hdmi_priv->sdvox_reg);
/* HW workaround, need to toggle enable bit off and on for 12bpc, but
* we do this anyway which shows more stable in testing.
*/
if (HAS_PCH_SPLIT(dev)) {
- I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
- POSTING_READ(intel_hdmi->sdvox_reg);
+ I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
+ POSTING_READ(hdmi_priv->sdvox_reg);
}
if (mode != DRM_MODE_DPMS_ON) {
@@ -105,15 +101,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
temp |= SDVO_ENABLE;
}
- I915_WRITE(intel_hdmi->sdvox_reg, temp);
- POSTING_READ(intel_hdmi->sdvox_reg);
+ I915_WRITE(hdmi_priv->sdvox_reg, temp);
+ POSTING_READ(hdmi_priv->sdvox_reg);
/* HW workaround, need to write this twice for issue that may result
* in first write getting masked.
*/
if (HAS_PCH_SPLIT(dev)) {
- I915_WRITE(intel_hdmi->sdvox_reg, temp);
- POSTING_READ(intel_hdmi->sdvox_reg);
+ I915_WRITE(hdmi_priv->sdvox_reg, temp);
+ POSTING_READ(hdmi_priv->sdvox_reg);
}
}
@@ -142,17 +138,19 @@ static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
- intel_hdmi->has_hdmi_sink = false;
- edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus);
+ hdmi_priv->has_hdmi_sink = false;
+ edid = drm_get_edid(connector,
+ intel_encoder->ddc_bus);
if (edid) {
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
- intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+ hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
}
connector->display_info.raw_edid = NULL;
kfree(edid);
@@ -164,13 +162,13 @@ intel_hdmi_detect(struct drm_connector *connector)
static int intel_hdmi_get_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
/* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it.
*/
- return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus);
+ return intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
}
static void intel_hdmi_destroy(struct drm_connector *connector)
@@ -201,8 +199,18 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs
.best_encoder = intel_attached_encoder,
};
+static void intel_hdmi_enc_destroy(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
+}
+
static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_hdmi_enc_destroy,
};
void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
@@ -211,19 +219,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
struct drm_connector *connector;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
- struct intel_hdmi *intel_hdmi;
+ struct intel_hdmi_priv *hdmi_priv;
- intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL);
- if (!intel_hdmi)
+ intel_encoder = kcalloc(sizeof(struct intel_encoder) +
+ sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
+ if (!intel_encoder)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_hdmi);
+ kfree(intel_encoder);
return;
}
- intel_encoder = &intel_hdmi->base;
+ hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
+
connector = &intel_connector->base;
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
@@ -264,7 +274,8 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
if (!intel_encoder->ddc_bus)
goto err_connector;
- intel_hdmi->sdvox_reg = sdvox_reg;
+ hdmi_priv->sdvox_reg = sdvox_reg;
+ intel_encoder->dev_priv = hdmi_priv;
drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
DRM_MODE_ENCODER_TMDS);
@@ -287,7 +298,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
err_connector:
drm_connector_cleanup(connector);
- kfree(intel_hdmi);
+ kfree(intel_encoder);
kfree(intel_connector);
return;
diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c
index b819c1081147..0a2e60059fb3 100644
--- a/trunk/drivers/gpu/drm/i915/intel_lvds.c
+++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c
@@ -41,18 +41,12 @@
#include
/* Private structure for the integrated LVDS support */
-struct intel_lvds {
- struct intel_encoder base;
+struct intel_lvds_priv {
int fitting_mode;
u32 pfit_control;
u32 pfit_pgm_ratios;
};
-static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base);
-}
-
/**
* Sets the backlight level.
*
@@ -96,7 +90,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
static void intel_lvds_set_power(struct drm_device *dev, bool on)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 ctl_reg, status_reg, lvds_reg;
+ u32 pp_status, ctl_reg, status_reg, lvds_reg;
if (HAS_PCH_SPLIT(dev)) {
ctl_reg = PCH_PP_CONTROL;
@@ -114,8 +108,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
POWER_TARGET_ON);
- if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0))
- DRM_ERROR("timed out waiting to enable LVDS pipe");
+ do {
+ pp_status = I915_READ(status_reg);
+ } while ((pp_status & PP_ON) == 0);
intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
} else {
@@ -123,8 +118,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
I915_WRITE(ctl_reg, I915_READ(ctl_reg) &
~POWER_TARGET_ON);
- if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0))
- DRM_ERROR("timed out waiting for LVDS pipe to turn off");
+ do {
+ pp_status = I915_READ(status_reg);
+ } while (pp_status & PP_ON);
I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
POSTING_READ(lvds_reg);
@@ -223,8 +219,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
struct drm_encoder *tmp_encoder;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
/* Should never happen!! */
@@ -244,20 +241,26 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
/* If we don't have a panel mode, there is nothing we can do */
if (dev_priv->panel_fixed_mode == NULL)
return true;
-
/*
* We have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
* with the panel scaling set up to source from the H/VDisplay
* of the original mode.
*/
- intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
-
- if (HAS_PCH_SPLIT(dev)) {
- intel_pch_panel_fitting(dev, intel_lvds->fitting_mode,
- mode, adjusted_mode);
- return true;
- }
+ adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
+ adjusted_mode->hsync_start =
+ dev_priv->panel_fixed_mode->hsync_start;
+ adjusted_mode->hsync_end =
+ dev_priv->panel_fixed_mode->hsync_end;
+ adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
+ adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
+ adjusted_mode->vsync_start =
+ dev_priv->panel_fixed_mode->vsync_start;
+ adjusted_mode->vsync_end =
+ dev_priv->panel_fixed_mode->vsync_end;
+ adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
+ adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
/* Make sure pre-965s set dither correctly */
if (!IS_I965G(dev)) {
@@ -270,6 +273,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
adjusted_mode->vdisplay == mode->vdisplay)
goto out;
+ /* full screen scale for now */
+ if (HAS_PCH_SPLIT(dev))
+ goto out;
+
/* 965+ wants fuzzy fitting */
if (IS_I965G(dev))
pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
@@ -281,10 +288,12 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
* to register description and PRM.
* Change the value here to see the borders for debugging
*/
- I915_WRITE(BCLRPAT_A, 0);
- I915_WRITE(BCLRPAT_B, 0);
+ if (!HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(BCLRPAT_A, 0);
+ I915_WRITE(BCLRPAT_B, 0);
+ }
- switch (intel_lvds->fitting_mode) {
+ switch (lvds_priv->fitting_mode) {
case DRM_MODE_SCALE_CENTER:
/*
* For centered modes, we have to calculate border widths &
@@ -369,8 +378,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
}
out:
- intel_lvds->pfit_control = pfit_control;
- intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios;
+ lvds_priv->pfit_control = pfit_control;
+ lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
dev_priv->lvds_border_bits = border;
/*
@@ -418,7 +427,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
/*
* The LVDS pin pair will already have been turned on in the
@@ -434,8 +444,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
* screen. Should be enabled before the pipe is enabled, according to
* register description and PRM.
*/
- I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
- I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
+ I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios);
+ I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
}
/**
@@ -590,17 +600,18 @@ static int intel_lvds_set_property(struct drm_connector *connector,
connector->encoder) {
struct drm_crtc *crtc = connector->encoder->crtc;
struct drm_encoder *encoder = connector->encoder;
- struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
if (value == DRM_MODE_SCALE_NONE) {
DRM_DEBUG_KMS("no scaling not supported\n");
return 0;
}
- if (intel_lvds->fitting_mode == value) {
+ if (lvds_priv->fitting_mode == value) {
/* the LVDS scaling property is not changed */
return 0;
}
- intel_lvds->fitting_mode = value;
+ lvds_priv->fitting_mode = value;
if (crtc && crtc->enabled) {
/*
* If the CRTC is enabled, the display will be changed
@@ -636,8 +647,19 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.destroy = intel_lvds_destroy,
};
+
+static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
+}
+
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_lvds_enc_destroy,
};
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
@@ -821,13 +843,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
void intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_lvds *intel_lvds;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc;
+ struct intel_lvds_priv *lvds_priv;
u32 lvds;
int pipe, gpio = GPIOC;
@@ -850,20 +872,20 @@ void intel_lvds_init(struct drm_device *dev)
gpio = PCH_GPIOC;
}
- intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
- if (!intel_lvds) {
+ intel_encoder = kzalloc(sizeof(struct intel_encoder) +
+ sizeof(struct intel_lvds_priv), GFP_KERNEL);
+ if (!intel_encoder) {
return;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_lvds);
+ kfree(intel_encoder);
return;
}
- intel_encoder = &intel_lvds->base;
- encoder = &intel_encoder->enc;
connector = &intel_connector->base;
+ encoder = &intel_encoder->enc;
drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
DRM_MODE_CONNECTOR_LVDS);
@@ -883,6 +905,8 @@ void intel_lvds_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
+ lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+ intel_encoder->dev_priv = lvds_priv;
/* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev);
/*
@@ -892,7 +916,7 @@ void intel_lvds_init(struct drm_device *dev)
drm_connector_attach_property(&intel_connector->base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_ASPECT);
- intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT;
+ lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT;
/*
* LVDS discovery:
* 1) check for EDID on DDC
@@ -1000,6 +1024,6 @@ void intel_lvds_init(struct drm_device *dev)
intel_i2c_destroy(intel_encoder->ddc_bus);
drm_connector_cleanup(connector);
drm_encoder_cleanup(encoder);
- kfree(intel_lvds);
+ kfree(intel_encoder);
kfree(intel_connector);
}
diff --git a/trunk/drivers/gpu/drm/i915/intel_overlay.c b/trunk/drivers/gpu/drm/i915/intel_overlay.c
index 4f00390d7c61..d39aea24eabe 100644
--- a/trunk/drivers/gpu/drm/i915/intel_overlay.c
+++ b/trunk/drivers/gpu/drm/i915/intel_overlay.c
@@ -1367,8 +1367,7 @@ void intel_setup_overlay(struct drm_device *dev)
overlay->flip_addr = overlay->reg_bo->gtt_offset;
} else {
ret = i915_gem_attach_phys_object(dev, reg_bo,
- I915_GEM_PHYS_OVERLAY_REGS,
- 0);
+ I915_GEM_PHYS_OVERLAY_REGS);
if (ret) {
DRM_ERROR("failed to attach phys overlay regs\n");
goto out_free_bo;
@@ -1417,99 +1416,3 @@ void intel_cleanup_overlay(struct drm_device *dev)
kfree(dev_priv->overlay);
}
}
-
-struct intel_overlay_error_state {
- struct overlay_registers regs;
- unsigned long base;
- u32 dovsta;
- u32 isr;
-};
-
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_overlay *overlay = dev_priv->overlay;
- struct intel_overlay_error_state *error;
- struct overlay_registers __iomem *regs;
-
- if (!overlay || !overlay->active)
- return NULL;
-
- error = kmalloc(sizeof(*error), GFP_ATOMIC);
- if (error == NULL)
- return NULL;
-
- error->dovsta = I915_READ(DOVSTA);
- error->isr = I915_READ(ISR);
- if (OVERLAY_NONPHYSICAL(overlay->dev))
- error->base = (long) overlay->reg_bo->gtt_offset;
- else
- error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
-
- regs = intel_overlay_map_regs_atomic(overlay);
- if (!regs)
- goto err;
-
- memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
- intel_overlay_unmap_regs_atomic(overlay);
-
- return error;
-
-err:
- kfree(error);
- return NULL;
-}
-
-void
-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
-{
- seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
- error->dovsta, error->isr);
- seq_printf(m, " Register file at 0x%08lx:\n",
- error->base);
-
-#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)
- P(OBUF_0Y);
- P(OBUF_1Y);
- P(OBUF_0U);
- P(OBUF_0V);
- P(OBUF_1U);
- P(OBUF_1V);
- P(OSTRIDE);
- P(YRGB_VPH);
- P(UV_VPH);
- P(HORZ_PH);
- P(INIT_PHS);
- P(DWINPOS);
- P(DWINSZ);
- P(SWIDTH);
- P(SWIDTHSW);
- P(SHEIGHT);
- P(YRGBSCALE);
- P(UVSCALE);
- P(OCLRC0);
- P(OCLRC1);
- P(DCLRKV);
- P(DCLRKM);
- P(SCLRKVH);
- P(SCLRKVL);
- P(SCLRKEN);
- P(OCONFIG);
- P(OCMD);
- P(OSTART_0Y);
- P(OSTART_1Y);
- P(OSTART_0U);
- P(OSTART_0V);
- P(OSTART_1U);
- P(OSTART_1V);
- P(OTILEOFF_0Y);
- P(OTILEOFF_1Y);
- P(OTILEOFF_0U);
- P(OTILEOFF_0V);
- P(OTILEOFF_1U);
- P(OTILEOFF_1V);
- P(FASTHSCALE);
- P(UVSCALEV);
-#undef P
-}
diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c
deleted file mode 100644
index e7f5299d9d57..000000000000
--- a/trunk/drivers/gpu/drm/i915/intel_panel.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright © 2006-2010 Intel Corporation
- * Copyright (c) 2006 Dave Airlie
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt
- * Dave Airlie
- * Jesse Barnes
- * Chris Wilson
- */
-
-#include "intel_drv.h"
-
-void
-intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
- struct drm_display_mode *adjusted_mode)
-{
- adjusted_mode->hdisplay = fixed_mode->hdisplay;
- adjusted_mode->hsync_start = fixed_mode->hsync_start;
- adjusted_mode->hsync_end = fixed_mode->hsync_end;
- adjusted_mode->htotal = fixed_mode->htotal;
-
- adjusted_mode->vdisplay = fixed_mode->vdisplay;
- adjusted_mode->vsync_start = fixed_mode->vsync_start;
- adjusted_mode->vsync_end = fixed_mode->vsync_end;
- adjusted_mode->vtotal = fixed_mode->vtotal;
-
- adjusted_mode->clock = fixed_mode->clock;
-
- drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-}
-
-/* adjusted_mode has been preset to be the panel's fixed mode */
-void
-intel_pch_panel_fitting(struct drm_device *dev,
- int fitting_mode,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int x, y, width, height;
-
- x = y = width = height = 0;
-
- /* Native modes don't need fitting */
- if (adjusted_mode->hdisplay == mode->hdisplay &&
- adjusted_mode->vdisplay == mode->vdisplay)
- goto done;
-
- switch (fitting_mode) {
- case DRM_MODE_SCALE_CENTER:
- width = mode->hdisplay;
- height = mode->vdisplay;
- x = (adjusted_mode->hdisplay - width + 1)/2;
- y = (adjusted_mode->vdisplay - height + 1)/2;
- break;
-
- case DRM_MODE_SCALE_ASPECT:
- /* Scale but preserve the aspect ratio */
- {
- u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
- u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
- if (scaled_width > scaled_height) { /* pillar */
- width = scaled_height / mode->vdisplay;
- x = (adjusted_mode->hdisplay - width + 1) / 2;
- y = 0;
- height = adjusted_mode->vdisplay;
- } else if (scaled_width < scaled_height) { /* letter */
- height = scaled_width / mode->hdisplay;
- y = (adjusted_mode->vdisplay - height + 1) / 2;
- x = 0;
- width = adjusted_mode->hdisplay;
- } else {
- x = y = 0;
- width = adjusted_mode->hdisplay;
- height = adjusted_mode->vdisplay;
- }
- }
- break;
-
- default:
- case DRM_MODE_SCALE_FULLSCREEN:
- x = y = 0;
- width = adjusted_mode->hdisplay;
- height = adjusted_mode->vdisplay;
- break;
- }
-
-done:
- dev_priv->pch_pf_pos = (x << 16) | y;
- dev_priv->pch_pf_size = (width << 16) | height;
-}
diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
index 51e9c9e718c4..26362f8495a8 100644
--- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -33,35 +33,18 @@
#include "i915_drm.h"
#include "i915_trace.h"
-static u32 i915_gem_get_seqno(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- u32 seqno;
-
- seqno = dev_priv->next_seqno;
-
- /* reserve 0 for non-seqno */
- if (++dev_priv->next_seqno == 0)
- dev_priv->next_seqno = 1;
-
- return seqno;
-}
-
static void
render_ring_flush(struct drm_device *dev,
struct intel_ring_buffer *ring,
u32 invalidate_domains,
u32 flush_domains)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- u32 cmd;
-
#if WATCH_EXEC
DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
invalidate_domains, flush_domains);
#endif
-
- trace_i915_gem_request_flush(dev, dev_priv->next_seqno,
+ u32 cmd;
+ trace_i915_gem_request_flush(dev, ring->next_seqno,
invalidate_domains, flush_domains);
if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
@@ -250,10 +233,9 @@ render_ring_add_request(struct drm_device *dev,
struct drm_file *file_priv,
u32 flush_domains)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
u32 seqno;
-
- seqno = i915_gem_get_seqno(dev);
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ seqno = intel_ring_get_seqno(dev, ring);
if (IS_GEN6(dev)) {
BEGIN_LP_RING(6);
@@ -423,9 +405,7 @@ bsd_ring_add_request(struct drm_device *dev,
u32 flush_domains)
{
u32 seqno;
-
- seqno = i915_gem_get_seqno(dev);
-
+ seqno = intel_ring_get_seqno(dev, ring);
intel_ring_begin(dev, ring, 4);
intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(dev, ring,
@@ -499,7 +479,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
exec_len = (uint32_t) exec->batch_len;
- trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1);
+ trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
count = nbox ? nbox : 1;
@@ -535,16 +515,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
intel_ring_advance(dev, ring);
}
- if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
- intel_ring_begin(dev, ring, 2);
- intel_ring_emit(dev, ring, MI_FLUSH |
- MI_NO_WRITE_FLUSH |
- MI_INVALIDATE_ISP );
- intel_ring_emit(dev, ring, MI_NOOP);
- intel_ring_advance(dev, ring);
- }
/* XXX breadcrumb */
-
return 0;
}
@@ -617,10 +588,9 @@ static int init_status_page(struct drm_device *dev,
int intel_init_ring_buffer(struct drm_device *dev,
struct intel_ring_buffer *ring)
{
+ int ret;
struct drm_i915_gem_object *obj_priv;
struct drm_gem_object *obj;
- int ret;
-
ring->dev = dev;
if (I915_NEED_GFX_HWS(dev)) {
@@ -633,14 +603,16 @@ int intel_init_ring_buffer(struct drm_device *dev,
if (obj == NULL) {
DRM_ERROR("Failed to allocate ringbuffer\n");
ret = -ENOMEM;
- goto err_hws;
+ goto cleanup;
}
ring->gem_object = obj;
ret = i915_gem_object_pin(obj, ring->alignment);
- if (ret)
- goto err_unref;
+ if (ret != 0) {
+ drm_gem_object_unreference(obj);
+ goto cleanup;
+ }
obj_priv = to_intel_bo(obj);
ring->map.size = ring->size;
@@ -652,14 +624,18 @@ int intel_init_ring_buffer(struct drm_device *dev,
drm_core_ioremap_wc(&ring->map, dev);
if (ring->map.handle == NULL) {
DRM_ERROR("Failed to map ringbuffer.\n");
+ i915_gem_object_unpin(obj);
+ drm_gem_object_unreference(obj);
ret = -EINVAL;
- goto err_unpin;
+ goto cleanup;
}
ring->virtual_start = ring->map.handle;
ret = ring->init(dev, ring);
- if (ret)
- goto err_unmap;
+ if (ret != 0) {
+ intel_cleanup_ring_buffer(dev, ring);
+ return ret;
+ }
if (!drm_core_check_feature(dev, DRIVER_MODESET))
i915_kernel_lost_context(dev);
@@ -673,15 +649,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
return ret;
-
-err_unmap:
- drm_core_ioremapfree(&ring->map, dev);
-err_unpin:
- i915_gem_object_unpin(obj);
-err_unref:
- drm_gem_object_unreference(obj);
- ring->gem_object = NULL;
-err_hws:
+cleanup:
cleanup_status_page(dev, ring);
return ret;
}
@@ -714,11 +682,9 @@ int intel_wrap_ring_buffer(struct drm_device *dev,
}
virt = (unsigned int *)(ring->virtual_start + ring->tail);
- rem /= 8;
- while (rem--) {
- *virt++ = MI_NOOP;
+ rem /= 4;
+ while (rem--)
*virt++ = MI_NOOP;
- }
ring->tail = 0;
ring->space = ring->head - 8;
@@ -763,14 +729,21 @@ void intel_ring_begin(struct drm_device *dev,
intel_wrap_ring_buffer(dev, ring);
if (unlikely(ring->space < n))
intel_wait_ring_buffer(dev, ring, n);
+}
- ring->space -= n;
+void intel_ring_emit(struct drm_device *dev,
+ struct intel_ring_buffer *ring, unsigned int data)
+{
+ unsigned int *virt = ring->virtual_start + ring->tail;
+ *virt = data;
+ ring->tail += 4;
+ ring->tail &= ring->size - 1;
+ ring->space -= 4;
}
void intel_ring_advance(struct drm_device *dev,
struct intel_ring_buffer *ring)
{
- ring->tail &= ring->size - 1;
ring->advance_ring(dev, ring);
}
@@ -789,6 +762,18 @@ void intel_fill_struct(struct drm_device *dev,
intel_ring_advance(dev, ring);
}
+u32 intel_ring_get_seqno(struct drm_device *dev,
+ struct intel_ring_buffer *ring)
+{
+ u32 seqno;
+ seqno = ring->next_seqno;
+
+ /* reserve 0 for non-seqno */
+ if (++ring->next_seqno == 0)
+ ring->next_seqno = 1;
+ return seqno;
+}
+
struct intel_ring_buffer render_ring = {
.name = "render ring",
.regs = {
@@ -806,6 +791,7 @@ struct intel_ring_buffer render_ring = {
.head = 0,
.tail = 0,
.space = 0,
+ .next_seqno = 1,
.user_irq_refcount = 0,
.irq_gem_seqno = 0,
.waiting_gem_seqno = 0,
@@ -844,6 +830,7 @@ struct intel_ring_buffer bsd_ring = {
.head = 0,
.tail = 0,
.space = 0,
+ .next_seqno = 1,
.user_irq_refcount = 0,
.irq_gem_seqno = 0,
.waiting_gem_seqno = 0,
diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h
index 525e7d3edda8..d5568d3766de 100644
--- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -26,6 +26,7 @@ struct intel_ring_buffer {
unsigned int head;
unsigned int tail;
unsigned int space;
+ u32 next_seqno;
struct intel_hw_status_page status_page;
u32 irq_gem_seqno; /* last seq seem at irq time */
@@ -105,16 +106,8 @@ int intel_wrap_ring_buffer(struct drm_device *dev,
struct intel_ring_buffer *ring);
void intel_ring_begin(struct drm_device *dev,
struct intel_ring_buffer *ring, int n);
-
-static inline void intel_ring_emit(struct drm_device *dev,
- struct intel_ring_buffer *ring,
- unsigned int data)
-{
- unsigned int *virt = ring->virtual_start + ring->tail;
- *virt = data;
- ring->tail += 4;
-}
-
+void intel_ring_emit(struct drm_device *dev,
+ struct intel_ring_buffer *ring, u32 data);
void intel_fill_struct(struct drm_device *dev,
struct intel_ring_buffer *ring,
void *data,
diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c
index 093e914e8a41..d9d4d51aa89e 100644
--- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c
@@ -31,8 +31,8 @@
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
-#include "drm_edid.h"
#include "intel_drv.h"
+#include "drm_edid.h"
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_sdvo_regs.h"
@@ -47,10 +47,9 @@
#define IS_TV(c) (c->output_flag & SDVO_TV_MASK)
#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK)
-#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
-static const char *tv_format_names[] = {
+static char *tv_format_names[] = {
"NTSC_M" , "NTSC_J" , "NTSC_443",
"PAL_B" , "PAL_D" , "PAL_G" ,
"PAL_H" , "PAL_I" , "PAL_M" ,
@@ -62,9 +61,7 @@ static const char *tv_format_names[] = {
#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
-struct intel_sdvo {
- struct intel_encoder base;
-
+struct intel_sdvo_priv {
u8 slave_addr;
/* Register for the SDVO device: SDVOB or SDVOC */
@@ -98,7 +95,7 @@ struct intel_sdvo {
bool is_tv;
/* This is for current tv format name */
- int tv_format_index;
+ char *tv_format_name;
/**
* This is set if we treat the device as HDMI, instead of DVI.
@@ -135,40 +132,37 @@ struct intel_sdvo {
};
struct intel_sdvo_connector {
- struct intel_connector base;
-
/* Mark the type of connector */
uint16_t output_flag;
/* This contains all current supported TV format */
- u8 tv_format_supported[TV_FORMAT_NUM];
+ char *tv_format_supported[TV_FORMAT_NUM];
int format_supported_num;
- struct drm_property *tv_format;
+ struct drm_property *tv_format_property;
+ struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
+
+ /**
+ * Returned SDTV resolutions allowed for the current format, if the
+ * device reported it.
+ */
+ struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
/* add the property for the SDVO-TV */
- struct drm_property *left;
- struct drm_property *right;
- struct drm_property *top;
- struct drm_property *bottom;
- struct drm_property *hpos;
- struct drm_property *vpos;
- struct drm_property *contrast;
- struct drm_property *saturation;
- struct drm_property *hue;
- struct drm_property *sharpness;
- struct drm_property *flicker_filter;
- struct drm_property *flicker_filter_adaptive;
- struct drm_property *flicker_filter_2d;
- struct drm_property *tv_chroma_filter;
- struct drm_property *tv_luma_filter;
- struct drm_property *dot_crawl;
+ struct drm_property *left_property;
+ struct drm_property *right_property;
+ struct drm_property *top_property;
+ struct drm_property *bottom_property;
+ struct drm_property *hpos_property;
+ struct drm_property *vpos_property;
/* add the property for the SDVO-TV/LVDS */
- struct drm_property *brightness;
+ struct drm_property *brightness_property;
+ struct drm_property *contrast_property;
+ struct drm_property *saturation_property;
+ struct drm_property *hue_property;
/* Add variable to record current setting for the above property */
u32 left_margin, right_margin, top_margin, bottom_margin;
-
/* this is to get the range of margin.*/
u32 max_hscan, max_vscan;
u32 max_hpos, cur_hpos;
@@ -177,54 +171,36 @@ struct intel_sdvo_connector {
u32 cur_contrast, max_contrast;
u32 cur_saturation, max_saturation;
u32 cur_hue, max_hue;
- u32 cur_sharpness, max_sharpness;
- u32 cur_flicker_filter, max_flicker_filter;
- u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive;
- u32 cur_flicker_filter_2d, max_flicker_filter_2d;
- u32 cur_tv_chroma_filter, max_tv_chroma_filter;
- u32 cur_tv_luma_filter, max_tv_luma_filter;
- u32 cur_dot_crawl, max_dot_crawl;
};
-static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base);
-}
-
-static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector)
-{
- return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base);
-}
-
-static bool
-intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags);
-static bool
-intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector,
- int type);
static bool
-intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder,
+ uint16_t flags);
+static void
+intel_sdvo_tv_create_property(struct drm_connector *connector, int type);
+static void
+intel_sdvo_create_enhance_property(struct drm_connector *connector);
/**
* Writes the SDVOB or SDVOC with the given value, but always writes both
* SDVOB and SDVOC to work around apparent hardware issues (according to
* comments in the BIOS).
*/
-static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
{
- struct drm_device *dev = intel_sdvo->base.enc.dev;
+ struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 bval = val, cval = val;
int i;
- if (intel_sdvo->sdvo_reg == PCH_SDVOB) {
- I915_WRITE(intel_sdvo->sdvo_reg, val);
- I915_READ(intel_sdvo->sdvo_reg);
+ if (sdvo_priv->sdvo_reg == PCH_SDVOB) {
+ I915_WRITE(sdvo_priv->sdvo_reg, val);
+ I915_READ(sdvo_priv->sdvo_reg);
return;
}
- if (intel_sdvo->sdvo_reg == SDVOB) {
+ if (sdvo_priv->sdvo_reg == SDVOB) {
cval = I915_READ(SDVOC);
} else {
bval = I915_READ(SDVOB);
@@ -243,27 +219,33 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
}
}
-static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
+ u8 *ch)
{
- u8 out_buf[2] = { addr, 0 };
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ u8 out_buf[2];
u8 buf[2];
+ int ret;
+
struct i2c_msg msgs[] = {
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = I2C_M_RD,
.len = 1,
.buf = buf,
}
};
- int ret;
- if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2)
+ out_buf[0] = addr;
+ out_buf[1] = 0;
+
+ if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
{
*ch = buf[0];
return true;
@@ -273,26 +255,35 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
return false;
}
-static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch)
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
+ u8 ch)
{
- u8 out_buf[2] = { addr, ch };
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ u8 out_buf[2];
struct i2c_msg msgs[] = {
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = 0,
.len = 2,
.buf = out_buf,
}
};
- return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1;
+ out_buf[0] = addr;
+ out_buf[1] = ch;
+
+ if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
+ {
+ return true;
+ }
+ return false;
}
#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
/** Mapping of command numbers to names, for debug output */
static const struct _sdvo_cmd_name {
u8 cmd;
- const char *name;
+ char *name;
} sdvo_cmd_names[] = {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
@@ -337,14 +328,13 @@ static const struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
-
/* Add the op code for SDVO enhancements */
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION),
@@ -363,27 +353,6 @@ static const struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER),
-
/* HDMI op code */
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
@@ -408,15 +377,17 @@ static const struct _sdvo_cmd_name {
};
#define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB)
-#define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC")
+#define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv)
-static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
- const void *args, int args_len)
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
+ void *args, int args_len)
{
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
DRM_DEBUG_KMS("%s: W: %02X ",
- SDVO_NAME(intel_sdvo), cmd);
+ SDVO_NAME(sdvo_priv), cmd);
for (i = 0; i < args_len; i++)
DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
for (; i < 8; i++)
@@ -432,20 +403,19 @@ static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
DRM_LOG_KMS("\n");
}
-static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
- const void *args, int args_len)
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
+ void *args, int args_len)
{
int i;
- intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
+ intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
for (i = 0; i < args_len; i++) {
- if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i,
- ((u8*)args)[i]))
- return false;
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
+ ((u8*)args)[i]);
}
- return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd);
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
}
static const char *cmd_status_names[] = {
@@ -458,13 +428,14 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
-static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
void *response, int response_len,
u8 status)
{
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
- DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));
+ DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
for (i = 0; i < response_len; i++)
DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
for (; i < 8; i++)
@@ -476,8 +447,8 @@ static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo,
DRM_LOG_KMS("\n");
}
-static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
- void *response, int response_len)
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
+ void *response, int response_len)
{
int i;
u8 status;
@@ -486,26 +457,24 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
while (retry--) {
/* Read the command response */
for (i = 0; i < response_len; i++) {
- if (!intel_sdvo_read_byte(intel_sdvo,
- SDVO_I2C_RETURN_0 + i,
- &((u8 *)response)[i]))
- return false;
+ intel_sdvo_read_byte(intel_encoder,
+ SDVO_I2C_RETURN_0 + i,
+ &((u8 *)response)[i]);
}
/* read the return status */
- if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS,
- &status))
- return false;
+ intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
+ &status);
- intel_sdvo_debug_response(intel_sdvo, response, response_len,
+ intel_sdvo_debug_response(intel_encoder, response, response_len,
status);
if (status != SDVO_CMD_STATUS_PENDING)
- break;
+ return status;
mdelay(50);
}
- return status == SDVO_CMD_STATUS_SUCCESS;
+ return status;
}
static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
@@ -525,36 +494,37 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
* another I2C transaction after issuing the DDC bus switch, it will be
* switched to the internal SDVO register.
*/
-static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
u8 target)
{
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
struct i2c_msg msgs[] = {
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = 0,
.len = 2,
.buf = out_buf,
},
/* the following two are to read the response */
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = 0,
.len = 1,
.buf = cmd_buf,
},
{
- .addr = intel_sdvo->slave_addr >> 1,
+ .addr = sdvo_priv->slave_addr >> 1,
.flags = I2C_M_RD,
.len = 1,
.buf = ret_value,
},
};
- intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+ intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
&target, 1);
/* write the DDC switch command argument */
- intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target);
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
out_buf[0] = SDVO_I2C_OPCODE;
out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -563,7 +533,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
ret_value[0] = 0;
ret_value[1] = 0;
- ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3);
+ ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
if (ret != 3) {
/* failure in I2C transfer */
DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -577,29 +547,23 @@ static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
return;
}
-static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
{
- if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len))
- return false;
+ struct intel_sdvo_set_target_input_args targets = {0};
+ u8 status;
- return intel_sdvo_read_response(intel_sdvo, NULL, 0);
-}
+ if (target_0 && target_1)
+ return SDVO_CMD_STATUS_NOTSUPP;
-static bool
-intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len)
-{
- if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0))
- return false;
+ if (target_1)
+ targets.target_1 = 1;
- return intel_sdvo_read_response(intel_sdvo, value, len);
-}
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
+ sizeof(targets));
-static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo)
-{
- struct intel_sdvo_set_target_input_args targets = {0};
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_TARGET_INPUT,
- &targets, sizeof(targets));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
/**
@@ -608,12 +572,14 @@ static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo)
* This function is making an assumption about the layout of the response,
* which should be checked against the docs.
*/
-static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
{
struct intel_sdvo_get_trained_inputs_response response;
+ u8 status;
- if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS,
- &response, sizeof(response)))
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
*input_1 = response.input0_trained;
@@ -621,18 +587,21 @@ static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *i
return true;
}
-static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
u16 outputs)
{
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_ACTIVE_OUTPUTS,
- &outputs, sizeof(outputs));
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+ sizeof(outputs));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
int mode)
{
- u8 state = SDVO_ENCODER_STATE_ON;
+ u8 status, state = SDVO_ENCODER_STATE_ON;
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -649,63 +618,88 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
break;
}
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state));
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+ sizeof(state));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
int *clock_min,
int *clock_max)
{
struct intel_sdvo_pixel_clock_range clocks;
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
- &clocks, sizeof(clocks)))
+ if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
/* Convert the values from units of 10 kHz to kHz. */
*clock_min = clocks.min * 10;
*clock_max = clocks.max * 10;
+
return true;
}
-static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
u16 outputs)
{
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_TARGET_OUTPUT,
- &outputs, sizeof(outputs));
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+ sizeof(outputs));
+
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
- intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
}
-static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(intel_sdvo,
+ return intel_sdvo_set_timing(intel_encoder,
SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(intel_sdvo,
+ return intel_sdvo_set_timing(intel_encoder,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
static bool
-intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
uint16_t clock,
uint16_t width,
uint16_t height)
{
struct intel_sdvo_preferred_input_timing_args args;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ uint8_t status;
memset(&args, 0, sizeof(args));
args.clock = clock;
@@ -713,32 +707,59 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
args.height = height;
args.interlace = 0;
- if (intel_sdvo->is_lvds &&
- (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
- intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
+ if (sdvo_priv->is_lvds &&
+ (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width ||
+ sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
args.scaled = 1;
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
- &args, sizeof(args));
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+ &args, sizeof(args));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
}
-static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
- &dtd->part1, sizeof(dtd->part1)) &&
- intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
- &dtd->part2, sizeof(dtd->part2));
+ bool status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
+ sizeof(dtd->part1));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
+ sizeof(dtd->part2));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return false;
}
-static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
{
- return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
}
static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
- const struct drm_display_mode *mode)
+ struct drm_display_mode *mode)
{
uint16_t width, height;
uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
@@ -787,7 +808,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
}
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
- const struct intel_sdvo_dtd *dtd)
+ struct intel_sdvo_dtd *dtd)
{
mode->hdisplay = dtd->part1.h_active;
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
@@ -819,33 +840,45 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->flags |= DRM_MODE_FLAG_PVSYNC;
}
-static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
struct intel_sdvo_encode *encode)
{
- if (intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_SUPP_ENCODE,
- encode, sizeof(*encode)))
- return true;
+ uint8_t status;
- /* non-support means DVI */
- memset(encode, 0, sizeof(*encode));
- return false;
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
+ if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
+ memset(encode, 0, sizeof(*encode));
+ return false;
+ }
+
+ return true;
}
-static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
uint8_t mode)
{
- return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1);
+ uint8_t status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
uint8_t mode)
{
- return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ uint8_t status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
}
#if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
{
int i, j;
uint8_t set_buf_index[2];
@@ -854,7 +887,8 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
uint8_t buf[48];
uint8_t *pos;
- intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1);
+ intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+ intel_sdvo_read_response(encoder, &av_split, 1);
for (i = 0; i <= av_split; i++) {
set_buf_index[0] = i; set_buf_index[1] = 0;
@@ -874,7 +908,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
}
#endif
-static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo,
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
int index,
uint8_t *data, int8_t size, uint8_t tx_rate)
{
@@ -883,18 +917,15 @@ static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo,
set_buf_index[0] = index;
set_buf_index[1] = 0;
- if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX,
- set_buf_index, 2))
- return false;
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+ set_buf_index, 2);
for (; size > 0; size -= 8) {
- if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8))
- return false;
-
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
data += 8;
}
- return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
}
static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -969,7 +1000,7 @@ struct dip_infoframe {
} __attribute__ ((packed)) u;
} __attribute__((packed));
-static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
struct drm_display_mode * mode)
{
struct dip_infoframe avi_if = {
@@ -980,105 +1011,133 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
4 + avi_if.len);
- return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if,
- 4 + avi_if.len,
- SDVO_HBUF_TX_VSYNC);
+ intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+ 4 + avi_if.len,
+ SDVO_HBUF_TX_VSYNC);
}
-static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
{
+
struct intel_sdvo_tv_format format;
- uint32_t format_map;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ uint32_t format_map, i;
+ uint8_t status;
- format_map = 1 << intel_sdvo->tv_format_index;
+ for (i = 0; i < TV_FORMAT_NUM; i++)
+ if (tv_format_names[i] == sdvo_priv->tv_format_name)
+ break;
+
+ format_map = 1 << i;
memset(&format, 0, sizeof(format));
- memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map)));
+ memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
+ sizeof(format) : sizeof(format_map));
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format,
+ sizeof(format));
- BUILD_BUG_ON(sizeof(format) != 6);
- return intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_TV_FORMAT,
- &format, sizeof(format));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ DRM_DEBUG_KMS("%s: Failed to set TV format\n",
+ SDVO_NAME(sdvo_priv));
}
-static bool
-intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
- struct drm_display_mode *mode)
+static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- struct intel_sdvo_dtd output_dtd;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
- if (!intel_sdvo_set_target_output(intel_sdvo,
- intel_sdvo->attached_output))
- return false;
+ if (dev_priv->is_tv) {
+ struct intel_sdvo_dtd output_dtd;
+ bool success;
- intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
- if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
- return false;
+ /* We need to construct preferred input timings based on our
+ * output timings. To do that, we have to set the output
+ * timings, even though this isn't really the right place in
+ * the sequence to do it. Oh well.
+ */
- return true;
-}
-static bool
-intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct intel_sdvo_dtd input_dtd;
+ /* Set output timings */
+ intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+ intel_sdvo_set_target_output(intel_encoder,
+ dev_priv->attached_output);
+ intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
- /* Reset the input timing to the screen. Assume always input 0. */
- if (!intel_sdvo_set_target_input(intel_sdvo))
- return false;
+ /* Set the input timing to the screen. Assume always input 0. */
+ intel_sdvo_set_target_input(intel_encoder, true, false);
- if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
- mode->clock / 10,
- mode->hdisplay,
- mode->vdisplay))
- return false;
- if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
- &input_dtd))
- return false;
+ success = intel_sdvo_create_preferred_input_timing(intel_encoder,
+ mode->clock / 10,
+ mode->hdisplay,
+ mode->vdisplay);
+ if (success) {
+ struct intel_sdvo_dtd input_dtd;
- intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
- intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags;
+ intel_sdvo_get_preferred_input_timing(intel_encoder,
+ &input_dtd);
+ intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+ dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
- drm_mode_set_crtcinfo(adjusted_mode, 0);
- mode->clock = adjusted_mode->clock;
- return true;
-}
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
-static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ mode->clock = adjusted_mode->clock;
- /* We need to construct preferred input timings based on our
- * output timings. To do that, we have to set the output
- * timings, even though this isn't really the right place in
- * the sequence to do it. Oh well.
- */
- if (intel_sdvo->is_tv) {
- if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
+ adjusted_mode->clock *=
+ intel_sdvo_get_pixel_multiplier(mode);
+ } else {
return false;
+ }
+ } else if (dev_priv->is_lvds) {
+ struct intel_sdvo_dtd output_dtd;
+ bool success;
- if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
- return false;
- } else if (intel_sdvo->is_lvds) {
- drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0);
+ drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0);
+ /* Set output timings */
+ intel_sdvo_get_dtd_from_mode(&output_dtd,
+ dev_priv->sdvo_lvds_fixed_mode);
- if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
- intel_sdvo->sdvo_lvds_fixed_mode))
- return false;
+ intel_sdvo_set_target_output(intel_encoder,
+ dev_priv->attached_output);
+ intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
- if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
- return false;
- }
+ /* Set the input timing to the screen. Assume always input 0. */
+ intel_sdvo_set_target_input(intel_encoder, true, false);
- /* Make the CRTC code factor in the SDVO pixel multiplier. The
- * SDVO device will be told of the multiplier during mode_set.
- */
- adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
+ success = intel_sdvo_create_preferred_input_timing(
+ intel_encoder,
+ mode->clock / 10,
+ mode->hdisplay,
+ mode->vdisplay);
+
+ if (success) {
+ struct intel_sdvo_dtd input_dtd;
+
+ intel_sdvo_get_preferred_input_timing(intel_encoder,
+ &input_dtd);
+ intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+ dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
+
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+ mode->clock = adjusted_mode->clock;
+
+ adjusted_mode->clock *=
+ intel_sdvo_get_pixel_multiplier(mode);
+ } else {
+ return false;
+ }
+
+ } else {
+ /* Make the CRTC code factor in the SDVO pixel multiplier. The
+ * SDVO device will be told of the multiplier during mode_set.
+ */
+ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
+ }
return true;
}
@@ -1090,11 +1149,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 sdvox = 0;
- int sdvo_pixel_multiply, rate;
+ int sdvo_pixel_multiply;
struct intel_sdvo_in_out_map in_out;
struct intel_sdvo_dtd input_dtd;
+ u8 status;
if (!mode)
return;
@@ -1105,50 +1166,41 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
* channel on the motherboard. In a two-input device, the first input
* will be SDVOB and the second SDVOC.
*/
- in_out.in0 = intel_sdvo->attached_output;
+ in_out.in0 = sdvo_priv->attached_output;
in_out.in1 = 0;
- if (!intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_IN_OUT_MAP,
- &in_out, sizeof(in_out)))
- return;
-
- if (intel_sdvo->is_hdmi) {
- if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode))
- return;
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
+ &in_out, sizeof(in_out));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
+ if (sdvo_priv->is_hdmi) {
+ intel_sdvo_set_avi_infoframe(intel_encoder, mode);
sdvox |= SDVO_AUDIO_ENABLE;
}
/* We have tried to get input timing in mode_fixup, and filled into
adjusted_mode */
- if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
+ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
- input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags;
+ input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags;
} else
intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
/* If it's a TV, we already set the output timing in mode_fixup.
* Otherwise, the output timing is equal to the input timing.
*/
- if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) {
+ if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
/* Set the output timing to the screen */
- if (!intel_sdvo_set_target_output(intel_sdvo,
- intel_sdvo->attached_output))
- return;
-
- if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd))
- return;
+ intel_sdvo_set_target_output(intel_encoder,
+ sdvo_priv->attached_output);
+ intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
}
/* Set the input timing to the screen. Assume always input 0. */
- if (!intel_sdvo_set_target_input(intel_sdvo))
- return;
+ intel_sdvo_set_target_input(intel_encoder, true, false);
- if (intel_sdvo->is_tv) {
- if (!intel_sdvo_set_tv_format(intel_sdvo))
- return;
- }
+ if (sdvo_priv->is_tv)
+ intel_sdvo_set_tv_format(intel_encoder);
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
@@ -1165,18 +1217,23 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo_set_input_timing(encoder, &input_dtd);
}
#else
- if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
- return;
+ intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
#endif
- sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
- switch (sdvo_pixel_multiply) {
- case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
- case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
- case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
+ switch (intel_sdvo_get_pixel_multiplier(mode)) {
+ case 1:
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
+ SDVO_CLOCK_RATE_MULT_1X);
+ break;
+ case 2:
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
+ SDVO_CLOCK_RATE_MULT_2X);
+ break;
+ case 4:
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
+ SDVO_CLOCK_RATE_MULT_4X);
+ break;
}
- if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate))
- return;
/* Set the SDVO control regs. */
if (IS_I965G(dev)) {
@@ -1186,8 +1243,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
} else {
- sdvox |= I915_READ(intel_sdvo->sdvo_reg);
- switch (intel_sdvo->sdvo_reg) {
+ sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+ switch (sdvo_priv->sdvo_reg) {
case SDVOB:
sdvox &= SDVOB_PRESERVE_MASK;
break;
@@ -1200,6 +1257,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
+ sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
if (IS_I965G(dev)) {
/* done in crtc_mode_set as the dpll_md reg must be written early */
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
@@ -1208,28 +1266,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
}
- if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL)
+ if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
sdvox |= SDVO_STALL_SELECT;
- intel_sdvo_write_sdvox(intel_sdvo, sdvox);
+ intel_sdvo_write_sdvox(intel_encoder, sdvox);
}
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 temp;
if (mode != DRM_MODE_DPMS_ON) {
- intel_sdvo_set_active_outputs(intel_sdvo, 0);
+ intel_sdvo_set_active_outputs(intel_encoder, 0);
if (0)
- intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
+ intel_sdvo_set_encoder_power_state(intel_encoder, mode);
if (mode == DRM_MODE_DPMS_OFF) {
- temp = I915_READ(intel_sdvo->sdvo_reg);
+ temp = I915_READ(sdvo_priv->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
- intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
}
}
} else {
@@ -1237,25 +1295,28 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
int i;
u8 status;
- temp = I915_READ(intel_sdvo->sdvo_reg);
+ temp = I915_READ(sdvo_priv->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
- intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
+
+ status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
+ &input2);
+
- status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
/* Warn if the device reported failure to sync.
* A lot of SDVO devices fail to notify of sync, but it's
* a given it the status is a success, we succeeded.
*/
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
DRM_DEBUG_KMS("First %s output reported failure to "
- "sync\n", SDVO_NAME(intel_sdvo));
+ "sync\n", SDVO_NAME(sdvo_priv));
}
if (0)
- intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
- intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
+ intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+ intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output);
}
return;
}
@@ -1264,31 +1325,42 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
- if (intel_sdvo->pixel_clock_min > mode->clock)
+ if (sdvo_priv->pixel_clock_min > mode->clock)
return MODE_CLOCK_LOW;
- if (intel_sdvo->pixel_clock_max < mode->clock)
+ if (sdvo_priv->pixel_clock_max < mode->clock)
return MODE_CLOCK_HIGH;
- if (intel_sdvo->is_lvds) {
- if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
+ if (sdvo_priv->is_lvds == true) {
+ if (sdvo_priv->sdvo_lvds_fixed_mode == NULL)
return MODE_PANEL;
- if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay)
+ if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay)
+ return MODE_PANEL;
+
+ if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay)
return MODE_PANEL;
}
return MODE_OK;
}
-static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
{
- return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps));
+ u8 status;
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
}
/* No use! */
@@ -1296,12 +1368,12 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
{
struct drm_connector *connector = NULL;
- struct intel_sdvo *iout = NULL;
- struct intel_sdvo *sdvo;
+ struct intel_encoder *iout = NULL;
+ struct intel_sdvo_priv *sdvo;
/* find the sdvo connector */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- iout = to_intel_sdvo(connector);
+ iout = to_intel_encoder(connector);
if (iout->type != INTEL_OUTPUT_SDVO)
continue;
@@ -1323,69 +1395,75 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
{
u8 response[2];
u8 status;
- struct intel_sdvo *intel_sdvo;
+ struct intel_encoder *intel_encoder;
DRM_DEBUG_KMS("\n");
if (!connector)
return 0;
- intel_sdvo = to_intel_sdvo(connector);
+ intel_encoder = to_intel_encoder(connector);
+
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
+
+ if (response[0] !=0)
+ return 1;
- return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
- &response, 2) && response[0];
+ return 0;
}
void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
u8 response[2];
u8 status;
- struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(intel_sdvo, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_encoder, &response, 2);
if (on) {
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
- status = intel_sdvo_read_response(intel_sdvo, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
} else {
response[0] = 0;
response[1] = 0;
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
}
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(intel_sdvo, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_encoder, &response, 2);
}
#endif
static bool
-intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
{
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int caps = 0;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1))
caps++;
- if (intel_sdvo->caps.output_flags &
+ if (sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1))
caps++;
@@ -1397,11 +1475,11 @@ intel_find_analog_connector(struct drm_device *dev)
{
struct drm_connector *connector;
struct drm_encoder *encoder;
- struct intel_sdvo *intel_sdvo;
+ struct intel_encoder *intel_encoder;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- intel_sdvo = enc_to_intel_sdvo(encoder);
- if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) {
+ intel_encoder = enc_to_intel_encoder(encoder);
+ if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (encoder == intel_attached_encoder(connector))
return connector;
@@ -1415,8 +1493,8 @@ static int
intel_analog_is_connected(struct drm_device *dev)
{
struct drm_connector *analog_connector;
-
analog_connector = intel_find_analog_connector(dev);
+
if (!analog_connector)
return false;
@@ -1431,52 +1509,54 @@ enum drm_connector_status
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
enum drm_connector_status status = connector_status_connected;
struct edid *edid = NULL;
- edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus);
+ edid = drm_get_edid(connector, intel_encoder->ddc_bus);
/* This is only applied to SDVO cards with multiple outputs */
- if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
+ if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
uint8_t saved_ddc, temp_ddc;
- saved_ddc = intel_sdvo->ddc_bus;
- temp_ddc = intel_sdvo->ddc_bus >> 1;
+ saved_ddc = sdvo_priv->ddc_bus;
+ temp_ddc = sdvo_priv->ddc_bus >> 1;
/*
* Don't use the 1 as the argument of DDC bus switch to get
* the EDID. It is used for SDVO SPD ROM.
*/
while(temp_ddc > 1) {
- intel_sdvo->ddc_bus = temp_ddc;
- edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus);
+ sdvo_priv->ddc_bus = temp_ddc;
+ edid = drm_get_edid(connector, intel_encoder->ddc_bus);
if (edid) {
/*
* When we can get the EDID, maybe it is the
* correct DDC bus. Update it.
*/
- intel_sdvo->ddc_bus = temp_ddc;
+ sdvo_priv->ddc_bus = temp_ddc;
break;
}
temp_ddc >>= 1;
}
if (edid == NULL)
- intel_sdvo->ddc_bus = saved_ddc;
+ sdvo_priv->ddc_bus = saved_ddc;
}
/* when there is no edid and no monitor is connected with VGA
* port, try to use the CRT ddc to read the EDID for DVI-connector
*/
- if (edid == NULL && intel_sdvo->analog_ddc_bus &&
+ if (edid == NULL && sdvo_priv->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev))
- edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus);
+ edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus);
if (edid != NULL) {
bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
- bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK);
+ bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK);
/* DDC bus is shared, match EDID to connector type */
if (is_digital && need_digital)
- intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
+ sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
else if (is_digital != need_digital)
status = connector_status_disconnected;
@@ -1492,29 +1572,33 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
{
uint16_t response;
+ u8 status;
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
enum drm_connector_status ret;
- if (!intel_sdvo_write_cmd(intel_sdvo,
- SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
- return connector_status_unknown;
- if (intel_sdvo->is_tv) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+ if (sdvo_priv->is_tv) {
/* add 30ms delay when the output type is SDVO-TV */
mdelay(30);
}
- if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
- return connector_status_unknown;
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return connector_status_unknown;
+
if (response == 0)
return connector_status_disconnected;
- intel_sdvo->attached_output = response;
+ sdvo_priv->attached_output = response;
- if ((intel_sdvo_connector->output_flag & response) == 0)
+ if ((sdvo_connector->output_flag & response) == 0)
ret = connector_status_disconnected;
else if (response & SDVO_TMDS_MASK)
ret = intel_sdvo_hdmi_sink_detect(connector);
@@ -1523,16 +1607,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
/* May update encoder flag for like clock for SDVO TV, etc.*/
if (ret == connector_status_connected) {
- intel_sdvo->is_tv = false;
- intel_sdvo->is_lvds = false;
- intel_sdvo->base.needs_tv_clock = false;
+ sdvo_priv->is_tv = false;
+ sdvo_priv->is_lvds = false;
+ intel_encoder->needs_tv_clock = false;
if (response & SDVO_TV_MASK) {
- intel_sdvo->is_tv = true;
- intel_sdvo->base.needs_tv_clock = true;
+ sdvo_priv->is_tv = true;
+ intel_encoder->needs_tv_clock = true;
}
if (response & SDVO_LVDS_MASK)
- intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
+ sdvo_priv->is_lvds = true;
}
return ret;
@@ -1541,11 +1625,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int num_modes;
/* set the bus switch and get the modes */
- num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus);
+ num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
/*
* Mac mini hack. On this device, the DVI-I connector shares one DDC
@@ -1554,11 +1639,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
* which case we'll look there for the digital DDC data.
*/
if (num_modes == 0 &&
- intel_sdvo->analog_ddc_bus &&
+ sdvo_priv->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev)) {
/* Switch to the analog ddc bus and try that
*/
- (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus);
+ (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus);
}
}
@@ -1630,43 +1715,52 @@ struct drm_display_mode sdvo_tv_modes[] = {
static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo_sdtv_resolution_request tv_res;
uint32_t reply = 0, format_map = 0;
int i;
+ uint8_t status;
+
/* Read the list of supported input resolutions for the selected TV
* format.
*/
- format_map = 1 << intel_sdvo->tv_format_index;
+ for (i = 0; i < TV_FORMAT_NUM; i++)
+ if (tv_format_names[i] == sdvo_priv->tv_format_name)
+ break;
+
+ format_map = (1 << i);
memcpy(&tv_res, &format_map,
- min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request)));
+ sizeof(struct intel_sdvo_sdtv_resolution_request) >
+ sizeof(format_map) ? sizeof(format_map) :
+ sizeof(struct intel_sdvo_sdtv_resolution_request));
- if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output))
- return;
+ intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output);
- BUILD_BUG_ON(sizeof(tv_res) != 3);
- if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
- &tv_res, sizeof(tv_res)))
- return;
- if (!intel_sdvo_read_response(intel_sdvo, &reply, 3))
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
+ &tv_res, sizeof(tv_res));
+ status = intel_sdvo_read_response(intel_encoder, &reply, 3);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
return;
for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
if (reply & (1 << i)) {
struct drm_display_mode *nmode;
nmode = drm_mode_duplicate(connector->dev,
- &sdvo_tv_modes[i]);
+ &sdvo_tv_modes[i]);
if (nmode)
drm_mode_probed_add(connector, nmode);
}
+
}
static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_display_mode *newmode;
/*
@@ -1674,7 +1768,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
* Assume that the preferred modes are
* arranged in priority order.
*/
- intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus);
+ intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
if (list_empty(&connector->probed_modes) == false)
goto end;
@@ -1693,9 +1787,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
end:
list_for_each_entry(newmode, &connector->probed_modes, head) {
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
- intel_sdvo->sdvo_lvds_fixed_mode =
+ sdvo_priv->sdvo_lvds_fixed_mode =
drm_mode_duplicate(connector->dev, newmode);
- intel_sdvo->is_lvds = true;
break;
}
}
@@ -1704,67 +1797,66 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
static int intel_sdvo_get_modes(struct drm_connector *connector)
{
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
- if (IS_TV(intel_sdvo_connector))
+ if (IS_TV(sdvo_connector))
intel_sdvo_get_tv_modes(connector);
- else if (IS_LVDS(intel_sdvo_connector))
+ else if (IS_LVDS(sdvo_connector))
intel_sdvo_get_lvds_modes(connector);
else
intel_sdvo_get_ddc_modes(connector);
- return !list_empty(&connector->probed_modes);
+ if (list_empty(&connector->probed_modes))
+ return 0;
+ return 1;
}
-static void
-intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
+static
+void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
{
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv;
struct drm_device *dev = connector->dev;
- if (intel_sdvo_connector->left)
- drm_property_destroy(dev, intel_sdvo_connector->left);
- if (intel_sdvo_connector->right)
- drm_property_destroy(dev, intel_sdvo_connector->right);
- if (intel_sdvo_connector->top)
- drm_property_destroy(dev, intel_sdvo_connector->top);
- if (intel_sdvo_connector->bottom)
- drm_property_destroy(dev, intel_sdvo_connector->bottom);
- if (intel_sdvo_connector->hpos)
- drm_property_destroy(dev, intel_sdvo_connector->hpos);
- if (intel_sdvo_connector->vpos)
- drm_property_destroy(dev, intel_sdvo_connector->vpos);
- if (intel_sdvo_connector->saturation)
- drm_property_destroy(dev, intel_sdvo_connector->saturation);
- if (intel_sdvo_connector->contrast)
- drm_property_destroy(dev, intel_sdvo_connector->contrast);
- if (intel_sdvo_connector->hue)
- drm_property_destroy(dev, intel_sdvo_connector->hue);
- if (intel_sdvo_connector->sharpness)
- drm_property_destroy(dev, intel_sdvo_connector->sharpness);
- if (intel_sdvo_connector->flicker_filter)
- drm_property_destroy(dev, intel_sdvo_connector->flicker_filter);
- if (intel_sdvo_connector->flicker_filter_2d)
- drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d);
- if (intel_sdvo_connector->flicker_filter_adaptive)
- drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive);
- if (intel_sdvo_connector->tv_luma_filter)
- drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter);
- if (intel_sdvo_connector->tv_chroma_filter)
- drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter);
- if (intel_sdvo_connector->dot_crawl)
- drm_property_destroy(dev, intel_sdvo_connector->dot_crawl);
- if (intel_sdvo_connector->brightness)
- drm_property_destroy(dev, intel_sdvo_connector->brightness);
+ if (IS_TV(sdvo_priv)) {
+ if (sdvo_priv->left_property)
+ drm_property_destroy(dev, sdvo_priv->left_property);
+ if (sdvo_priv->right_property)
+ drm_property_destroy(dev, sdvo_priv->right_property);
+ if (sdvo_priv->top_property)
+ drm_property_destroy(dev, sdvo_priv->top_property);
+ if (sdvo_priv->bottom_property)
+ drm_property_destroy(dev, sdvo_priv->bottom_property);
+ if (sdvo_priv->hpos_property)
+ drm_property_destroy(dev, sdvo_priv->hpos_property);
+ if (sdvo_priv->vpos_property)
+ drm_property_destroy(dev, sdvo_priv->vpos_property);
+ if (sdvo_priv->saturation_property)
+ drm_property_destroy(dev,
+ sdvo_priv->saturation_property);
+ if (sdvo_priv->contrast_property)
+ drm_property_destroy(dev,
+ sdvo_priv->contrast_property);
+ if (sdvo_priv->hue_property)
+ drm_property_destroy(dev, sdvo_priv->hue_property);
+ }
+ if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) {
+ if (sdvo_priv->brightness_property)
+ drm_property_destroy(dev,
+ sdvo_priv->brightness_property);
+ }
+ return;
}
static void intel_sdvo_destroy(struct drm_connector *connector)
{
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
- if (intel_sdvo_connector->tv_format)
+ if (sdvo_connector->tv_format_property)
drm_property_destroy(connector->dev,
- intel_sdvo_connector->tv_format);
+ sdvo_connector->tv_format_property);
intel_sdvo_destroy_enhance_property(connector);
drm_sysfs_connector_remove(connector);
@@ -1778,118 +1870,132 @@ intel_sdvo_set_property(struct drm_connector *connector,
uint64_t val)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
- struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
+ struct drm_crtc *crtc = encoder->crtc;
+ int ret = 0;
+ bool changed = false;
+ uint8_t cmd, status;
uint16_t temp_value;
- uint8_t cmd;
- int ret;
ret = drm_connector_property_set_value(connector, property, val);
- if (ret)
- return ret;
-
-#define CHECK_PROPERTY(name, NAME) \
- if (intel_sdvo_connector->name == property) { \
- if (intel_sdvo_connector->cur_##name == temp_value) return 0; \
- if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \
- cmd = SDVO_CMD_SET_##NAME; \
- intel_sdvo_connector->cur_##name = temp_value; \
- goto set_value; \
- }
+ if (ret < 0)
+ goto out;
- if (property == intel_sdvo_connector->tv_format) {
- if (val >= TV_FORMAT_NUM)
- return -EINVAL;
+ if (property == sdvo_connector->tv_format_property) {
+ if (val >= TV_FORMAT_NUM) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (sdvo_priv->tv_format_name ==
+ sdvo_connector->tv_format_supported[val])
+ goto out;
- if (intel_sdvo->tv_format_index ==
- intel_sdvo_connector->tv_format_supported[val])
- return 0;
+ sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val];
+ changed = true;
+ }
- intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val];
- goto done;
- } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) {
+ if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) {
+ cmd = 0;
temp_value = val;
- if (intel_sdvo_connector->left == property) {
+ if (sdvo_connector->left_property == property) {
drm_connector_property_set_value(connector,
- intel_sdvo_connector->right, val);
- if (intel_sdvo_connector->left_margin == temp_value)
- return 0;
-
- intel_sdvo_connector->left_margin = temp_value;
- intel_sdvo_connector->right_margin = temp_value;
- temp_value = intel_sdvo_connector->max_hscan -
- intel_sdvo_connector->left_margin;
+ sdvo_connector->right_property, val);
+ if (sdvo_connector->left_margin == temp_value)
+ goto out;
+
+ sdvo_connector->left_margin = temp_value;
+ sdvo_connector->right_margin = temp_value;
+ temp_value = sdvo_connector->max_hscan -
+ sdvo_connector->left_margin;
cmd = SDVO_CMD_SET_OVERSCAN_H;
- goto set_value;
- } else if (intel_sdvo_connector->right == property) {
+ } else if (sdvo_connector->right_property == property) {
drm_connector_property_set_value(connector,
- intel_sdvo_connector->left, val);
- if (intel_sdvo_connector->right_margin == temp_value)
- return 0;
-
- intel_sdvo_connector->left_margin = temp_value;
- intel_sdvo_connector->right_margin = temp_value;
- temp_value = intel_sdvo_connector->max_hscan -
- intel_sdvo_connector->left_margin;
+ sdvo_connector->left_property, val);
+ if (sdvo_connector->right_margin == temp_value)
+ goto out;
+
+ sdvo_connector->left_margin = temp_value;
+ sdvo_connector->right_margin = temp_value;
+ temp_value = sdvo_connector->max_hscan -
+ sdvo_connector->left_margin;
cmd = SDVO_CMD_SET_OVERSCAN_H;
- goto set_value;
- } else if (intel_sdvo_connector->top == property) {
+ } else if (sdvo_connector->top_property == property) {
drm_connector_property_set_value(connector,
- intel_sdvo_connector->bottom, val);
- if (intel_sdvo_connector->top_margin == temp_value)
- return 0;
-
- intel_sdvo_connector->top_margin = temp_value;
- intel_sdvo_connector->bottom_margin = temp_value;
- temp_value = intel_sdvo_connector->max_vscan -
- intel_sdvo_connector->top_margin;
+ sdvo_connector->bottom_property, val);
+ if (sdvo_connector->top_margin == temp_value)
+ goto out;
+
+ sdvo_connector->top_margin = temp_value;
+ sdvo_connector->bottom_margin = temp_value;
+ temp_value = sdvo_connector->max_vscan -
+ sdvo_connector->top_margin;
cmd = SDVO_CMD_SET_OVERSCAN_V;
- goto set_value;
- } else if (intel_sdvo_connector->bottom == property) {
+ } else if (sdvo_connector->bottom_property == property) {
drm_connector_property_set_value(connector,
- intel_sdvo_connector->top, val);
- if (intel_sdvo_connector->bottom_margin == temp_value)
- return 0;
-
- intel_sdvo_connector->top_margin = temp_value;
- intel_sdvo_connector->bottom_margin = temp_value;
- temp_value = intel_sdvo_connector->max_vscan -
- intel_sdvo_connector->top_margin;
+ sdvo_connector->top_property, val);
+ if (sdvo_connector->bottom_margin == temp_value)
+ goto out;
+ sdvo_connector->top_margin = temp_value;
+ sdvo_connector->bottom_margin = temp_value;
+ temp_value = sdvo_connector->max_vscan -
+ sdvo_connector->top_margin;
cmd = SDVO_CMD_SET_OVERSCAN_V;
- goto set_value;
+ } else if (sdvo_connector->hpos_property == property) {
+ if (sdvo_connector->cur_hpos == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_POSITION_H;
+ sdvo_connector->cur_hpos = temp_value;
+ } else if (sdvo_connector->vpos_property == property) {
+ if (sdvo_connector->cur_vpos == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_POSITION_V;
+ sdvo_connector->cur_vpos = temp_value;
+ } else if (sdvo_connector->saturation_property == property) {
+ if (sdvo_connector->cur_saturation == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_SATURATION;
+ sdvo_connector->cur_saturation = temp_value;
+ } else if (sdvo_connector->contrast_property == property) {
+ if (sdvo_connector->cur_contrast == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_CONTRAST;
+ sdvo_connector->cur_contrast = temp_value;
+ } else if (sdvo_connector->hue_property == property) {
+ if (sdvo_connector->cur_hue == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_HUE;
+ sdvo_connector->cur_hue = temp_value;
+ } else if (sdvo_connector->brightness_property == property) {
+ if (sdvo_connector->cur_brightness == temp_value)
+ goto out;
+
+ cmd = SDVO_CMD_SET_BRIGHTNESS;
+ sdvo_connector->cur_brightness = temp_value;
+ }
+ if (cmd) {
+ intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+ status = intel_sdvo_read_response(intel_encoder,
+ NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO command \n");
+ return -EINVAL;
+ }
+ changed = true;
}
- CHECK_PROPERTY(hpos, HPOS)
- CHECK_PROPERTY(vpos, VPOS)
- CHECK_PROPERTY(saturation, SATURATION)
- CHECK_PROPERTY(contrast, CONTRAST)
- CHECK_PROPERTY(hue, HUE)
- CHECK_PROPERTY(brightness, BRIGHTNESS)
- CHECK_PROPERTY(sharpness, SHARPNESS)
- CHECK_PROPERTY(flicker_filter, FLICKER_FILTER)
- CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D)
- CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE)
- CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER)
- CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER)
- CHECK_PROPERTY(dot_crawl, DOT_CRAWL)
}
-
- return -EINVAL; /* unknown property */
-
-set_value:
- if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2))
- return -EIO;
-
-
-done:
- if (encoder->crtc) {
- struct drm_crtc *crtc = encoder->crtc;
-
+ if (changed && crtc)
drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
- crtc->y, crtc->fb);
- }
-
- return 0;
-#undef CHECK_PROPERTY
+ crtc->y, crtc->fb);
+out:
+ return ret;
}
static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
@@ -1916,16 +2022,22 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs
static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
{
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
- if (intel_sdvo->analog_ddc_bus)
- intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
+ if (sdvo_priv->analog_ddc_bus)
+ intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
- if (intel_sdvo->sdvo_lvds_fixed_mode != NULL)
+ if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
drm_mode_destroy(encoder->dev,
- intel_sdvo->sdvo_lvds_fixed_mode);
+ sdvo_priv->sdvo_lvds_fixed_mode);
- intel_encoder_destroy(encoder);
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
}
static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
@@ -1942,7 +2054,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
*/
static void
intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
- struct intel_sdvo *sdvo, u32 reg)
+ struct intel_sdvo_priv *sdvo, u32 reg)
{
struct sdvo_device_mapping *mapping;
@@ -1955,46 +2067,57 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
}
static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device)
{
- return intel_sdvo_set_target_output(intel_sdvo,
- device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) &&
- intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
- &intel_sdvo->is_hdmi, 1);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ uint8_t status;
+
+ if (device == 0)
+ intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0);
+ else
+ intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1);
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+ return true;
}
-static struct intel_sdvo *
-intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
{
struct drm_device *dev = chan->drm_dev;
struct drm_encoder *encoder;
+ struct intel_encoder *intel_encoder = NULL;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder);
- if (intel_sdvo->base.ddc_bus == &chan->adapter)
- return intel_sdvo;
+ intel_encoder = enc_to_intel_encoder(encoder);
+ if (intel_encoder->ddc_bus == &chan->adapter)
+ break;
}
-
- return NULL;
+ return intel_encoder;
}
static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msgs[], int num)
{
- struct intel_sdvo *intel_sdvo;
+ struct intel_encoder *intel_encoder;
+ struct intel_sdvo_priv *sdvo_priv;
struct i2c_algo_bit_data *algo_data;
const struct i2c_algorithm *algo;
algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
- intel_sdvo =
- intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *)
- (algo_data->data));
- if (intel_sdvo == NULL)
+ intel_encoder =
+ intel_sdvo_chan_to_intel_encoder(
+ (struct intel_i2c_chan *)(algo_data->data));
+ if (intel_encoder == NULL)
return -EINVAL;
- algo = intel_sdvo->base.i2c_bus->algo;
+ sdvo_priv = intel_encoder->dev_priv;
+ algo = intel_encoder->i2c_bus->algo;
- intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus);
+ intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
return algo->master_xfer(i2c_adap, msgs, num);
}
@@ -2039,9 +2162,27 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
return 0x72;
}
+static bool
+intel_sdvo_connector_alloc (struct intel_connector **ret)
+{
+ struct intel_connector *intel_connector;
+ struct intel_sdvo_connector *sdvo_connector;
+
+ *ret = kzalloc(sizeof(*intel_connector) +
+ sizeof(*sdvo_connector), GFP_KERNEL);
+ if (!*ret)
+ return false;
+
+ intel_connector = *ret;
+ sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1);
+ intel_connector->dev_priv = sdvo_connector;
+
+ return true;
+}
+
static void
-intel_sdvo_connector_init(struct drm_encoder *encoder,
- struct drm_connector *connector)
+intel_sdvo_connector_create (struct drm_encoder *encoder,
+ struct drm_connector *connector)
{
drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs,
connector->connector_type);
@@ -2057,470 +2198,582 @@ intel_sdvo_connector_init(struct drm_encoder *encoder,
}
static bool
-intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
{
- struct drm_encoder *encoder = &intel_sdvo->base.enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_connector *connector;
struct intel_connector *intel_connector;
- struct intel_sdvo_connector *intel_sdvo_connector;
+ struct intel_sdvo_connector *sdvo_connector;
- intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
- if (!intel_sdvo_connector)
+ if (!intel_sdvo_connector_alloc(&intel_connector))
return false;
+ sdvo_connector = intel_connector->dev_priv;
+
if (device == 0) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0;
+ sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
} else if (device == 1) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1;
+ sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
}
- intel_connector = &intel_sdvo_connector->base;
connector = &intel_connector->base;
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
- if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode)
- && intel_sdvo_get_digital_encoding_mode(intel_sdvo, device)
- && intel_sdvo->is_hdmi) {
+ if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode)
+ && intel_sdvo_get_digital_encoding_mode(intel_encoder, device)
+ && sdvo_priv->is_hdmi) {
/* enable hdmi encoding mode if supported */
- intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
- intel_sdvo_set_colorimetry(intel_sdvo,
+ intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+ intel_sdvo_set_colorimetry(intel_encoder,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT));
+ intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ (1 << INTEL_ANALOG_CLONE_BIT);
- intel_sdvo_connector_init(encoder, connector);
+ intel_sdvo_connector_create(encoder, connector);
return true;
}
static bool
-intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
+intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type)
{
- struct drm_encoder *encoder = &intel_sdvo->base.enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_connector *connector;
struct intel_connector *intel_connector;
- struct intel_sdvo_connector *intel_sdvo_connector;
+ struct intel_sdvo_connector *sdvo_connector;
- intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
- if (!intel_sdvo_connector)
- return false;
+ if (!intel_sdvo_connector_alloc(&intel_connector))
+ return false;
- intel_connector = &intel_sdvo_connector->base;
connector = &intel_connector->base;
encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+ sdvo_connector = intel_connector->dev_priv;
- intel_sdvo->controlled_output |= type;
- intel_sdvo_connector->output_flag = type;
+ sdvo_priv->controlled_output |= type;
+ sdvo_connector->output_flag = type;
- intel_sdvo->is_tv = true;
- intel_sdvo->base.needs_tv_clock = true;
- intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+ sdvo_priv->is_tv = true;
+ intel_encoder->needs_tv_clock = true;
+ intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
- intel_sdvo_connector_init(encoder, connector);
+ intel_sdvo_connector_create(encoder, connector);
- if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
- goto err;
+ intel_sdvo_tv_create_property(connector, type);
- if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
- goto err;
+ intel_sdvo_create_enhance_property(connector);
return true;
-
-err:
- intel_sdvo_destroy_enhance_property(connector);
- kfree(intel_sdvo_connector);
- return false;
}
static bool
-intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device)
{
- struct drm_encoder *encoder = &intel_sdvo->base.enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_connector *connector;
struct intel_connector *intel_connector;
- struct intel_sdvo_connector *intel_sdvo_connector;
+ struct intel_sdvo_connector *sdvo_connector;
- intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
- if (!intel_sdvo_connector)
- return false;
+ if (!intel_sdvo_connector_alloc(&intel_connector))
+ return false;
- intel_connector = &intel_sdvo_connector->base;
connector = &intel_connector->base;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+ sdvo_connector = intel_connector->dev_priv;
if (device == 0) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0;
+ sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
} else if (device == 1) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1;
+ sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT));
+ intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ (1 << INTEL_ANALOG_CLONE_BIT);
- intel_sdvo_connector_init(encoder, connector);
+ intel_sdvo_connector_create(encoder, connector);
return true;
}
static bool
-intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device)
{
- struct drm_encoder *encoder = &intel_sdvo->base.enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_connector *connector;
struct intel_connector *intel_connector;
- struct intel_sdvo_connector *intel_sdvo_connector;
+ struct intel_sdvo_connector *sdvo_connector;
- intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL);
- if (!intel_sdvo_connector)
- return false;
+ if (!intel_sdvo_connector_alloc(&intel_connector))
+ return false;
- intel_connector = &intel_sdvo_connector->base;
- connector = &intel_connector->base;
+ connector = &intel_connector->base;
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+ sdvo_connector = intel_connector->dev_priv;
+
+ sdvo_priv->is_lvds = true;
if (device == 0) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0;
+ sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
} else if (device == 1) {
- intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
- intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
+ sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1;
+ sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) |
- (1 << INTEL_SDVO_LVDS_CLONE_BIT));
-
- intel_sdvo_connector_init(encoder, connector);
- if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
- goto err;
+ intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+ (1 << INTEL_SDVO_LVDS_CLONE_BIT);
- return true;
-
-err:
- intel_sdvo_destroy_enhance_property(connector);
- kfree(intel_sdvo_connector);
- return false;
+ intel_sdvo_connector_create(encoder, connector);
+ intel_sdvo_create_enhance_property(connector);
+ return true;
}
static bool
-intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
{
- intel_sdvo->is_tv = false;
- intel_sdvo->base.needs_tv_clock = false;
- intel_sdvo->is_lvds = false;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+
+ sdvo_priv->is_tv = false;
+ intel_encoder->needs_tv_clock = false;
+ sdvo_priv->is_lvds = false;
/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
if (flags & SDVO_OUTPUT_TMDS0)
- if (!intel_sdvo_dvi_init(intel_sdvo, 0))
+ if (!intel_sdvo_dvi_init(intel_encoder, 0))
return false;
if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
- if (!intel_sdvo_dvi_init(intel_sdvo, 1))
+ if (!intel_sdvo_dvi_init(intel_encoder, 1))
return false;
/* TV has no XXX1 function block */
if (flags & SDVO_OUTPUT_SVID0)
- if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
+ if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0))
return false;
if (flags & SDVO_OUTPUT_CVBS0)
- if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
+ if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0))
return false;
if (flags & SDVO_OUTPUT_RGB0)
- if (!intel_sdvo_analog_init(intel_sdvo, 0))
+ if (!intel_sdvo_analog_init(intel_encoder, 0))
return false;
if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
- if (!intel_sdvo_analog_init(intel_sdvo, 1))
+ if (!intel_sdvo_analog_init(intel_encoder, 1))
return false;
if (flags & SDVO_OUTPUT_LVDS0)
- if (!intel_sdvo_lvds_init(intel_sdvo, 0))
+ if (!intel_sdvo_lvds_init(intel_encoder, 0))
return false;
if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
- if (!intel_sdvo_lvds_init(intel_sdvo, 1))
+ if (!intel_sdvo_lvds_init(intel_encoder, 1))
return false;
if ((flags & SDVO_OUTPUT_MASK) == 0) {
unsigned char bytes[2];
- intel_sdvo->controlled_output = 0;
- memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
+ sdvo_priv->controlled_output = 0;
+ memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
- SDVO_NAME(intel_sdvo),
+ SDVO_NAME(sdvo_priv),
bytes[0], bytes[1]);
return false;
}
- intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
return true;
}
-static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector,
- int type)
+static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type)
{
- struct drm_device *dev = intel_sdvo->base.enc.dev;
+ struct drm_encoder *encoder = intel_attached_encoder(connector);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
struct intel_sdvo_tv_format format;
uint32_t format_map, i;
+ uint8_t status;
- if (!intel_sdvo_set_target_output(intel_sdvo, type))
- return false;
+ intel_sdvo_set_target_output(intel_encoder, type);
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_SUPPORTED_TV_FORMATS,
- &format, sizeof(format)))
- return false;
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &format, sizeof(format));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return;
- memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format)));
+ memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ?
+ sizeof(format_map) : sizeof(format));
if (format_map == 0)
- return false;
+ return;
- intel_sdvo_connector->format_supported_num = 0;
+ sdvo_connector->format_supported_num = 0;
for (i = 0 ; i < TV_FORMAT_NUM; i++)
- if (format_map & (1 << i))
- intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i;
+ if (format_map & (1 << i)) {
+ sdvo_connector->tv_format_supported
+ [sdvo_connector->format_supported_num++] =
+ tv_format_names[i];
+ }
- intel_sdvo_connector->tv_format =
- drm_property_create(dev, DRM_MODE_PROP_ENUM,
- "mode", intel_sdvo_connector->format_supported_num);
- if (!intel_sdvo_connector->tv_format)
- return false;
+ sdvo_connector->tv_format_property =
+ drm_property_create(
+ connector->dev, DRM_MODE_PROP_ENUM,
+ "mode", sdvo_connector->format_supported_num);
- for (i = 0; i < intel_sdvo_connector->format_supported_num; i++)
+ for (i = 0; i < sdvo_connector->format_supported_num; i++)
drm_property_add_enum(
- intel_sdvo_connector->tv_format, i,
- i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
+ sdvo_connector->tv_format_property, i,
+ i, sdvo_connector->tv_format_supported[i]);
- intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0];
- drm_connector_attach_property(&intel_sdvo_connector->base.base,
- intel_sdvo_connector->tv_format, 0);
- return true;
+ sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0];
+ drm_connector_attach_property(
+ connector, sdvo_connector->tv_format_property, 0);
}
-#define ENHANCEMENT(name, NAME) do { \
- if (enhancements.name) { \
- if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \
- !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \
- return false; \
- intel_sdvo_connector->max_##name = data_value[0]; \
- intel_sdvo_connector->cur_##name = response; \
- intel_sdvo_connector->name = \
- drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
- if (!intel_sdvo_connector->name) return false; \
- intel_sdvo_connector->name->values[0] = 0; \
- intel_sdvo_connector->name->values[1] = data_value[0]; \
- drm_connector_attach_property(connector, \
- intel_sdvo_connector->name, \
- intel_sdvo_connector->cur_##name); \
- DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
- data_value[0], data_value[1], response); \
- } \
-} while(0)
-
-static bool
-intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector,
- struct intel_sdvo_enhancements_reply enhancements)
+static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
{
- struct drm_device *dev = intel_sdvo->base.enc.dev;
- struct drm_connector *connector = &intel_sdvo_connector->base.base;
+ struct drm_encoder *encoder = intel_attached_encoder(connector);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv;
+ struct intel_sdvo_enhancements_reply sdvo_data;
+ struct drm_device *dev = connector->dev;
+ uint8_t status;
uint16_t response, data_value[2];
- /* when horizontal overscan is supported, Add the left/right property */
- if (enhancements.overscan_h) {
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_MAX_OVERSCAN_H,
- &data_value, 4))
- return false;
-
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_OVERSCAN_H,
- &response, 2))
- return false;
-
- intel_sdvo_connector->max_hscan = data_value[0];
- intel_sdvo_connector->left_margin = data_value[0] - response;
- intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
- intel_sdvo_connector->left =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "left_margin", 2);
- if (!intel_sdvo_connector->left)
- return false;
-
- intel_sdvo_connector->left->values[0] = 0;
- intel_sdvo_connector->left->values[1] = data_value[0];
- drm_connector_attach_property(connector,
- intel_sdvo_connector->left,
- intel_sdvo_connector->left_margin);
-
- intel_sdvo_connector->right =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "right_margin", 2);
- if (!intel_sdvo_connector->right)
- return false;
-
- intel_sdvo_connector->right->values[0] = 0;
- intel_sdvo_connector->right->values[1] = data_value[0];
- drm_connector_attach_property(connector,
- intel_sdvo_connector->right,
- intel_sdvo_connector->right_margin);
- DRM_DEBUG_KMS("h_overscan: max %d, "
- "default %d, current %d\n",
- data_value[0], data_value[1], response);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+ NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
+ sizeof(sdvo_data));
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS(" incorrect response is returned\n");
+ return;
}
-
- if (enhancements.overscan_v) {
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_MAX_OVERSCAN_V,
- &data_value, 4))
- return false;
-
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_OVERSCAN_V,
- &response, 2))
- return false;
-
- intel_sdvo_connector->max_vscan = data_value[0];
- intel_sdvo_connector->top_margin = data_value[0] - response;
- intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
- intel_sdvo_connector->top =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "top_margin", 2);
- if (!intel_sdvo_connector->top)
- return false;
-
- intel_sdvo_connector->top->values[0] = 0;
- intel_sdvo_connector->top->values[1] = data_value[0];
- drm_connector_attach_property(connector,
- intel_sdvo_connector->top,
- intel_sdvo_connector->top_margin);
-
- intel_sdvo_connector->bottom =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "bottom_margin", 2);
- if (!intel_sdvo_connector->bottom)
- return false;
-
- intel_sdvo_connector->bottom->values[0] = 0;
- intel_sdvo_connector->bottom->values[1] = data_value[0];
- drm_connector_attach_property(connector,
- intel_sdvo_connector->bottom,
- intel_sdvo_connector->bottom_margin);
- DRM_DEBUG_KMS("v_overscan: max %d, "
- "default %d, current %d\n",
- data_value[0], data_value[1], response);
+ response = *((uint16_t *)&sdvo_data);
+ if (!response) {
+ DRM_DEBUG_KMS("No enhancement is supported\n");
+ return;
}
-
- ENHANCEMENT(hpos, HPOS);
- ENHANCEMENT(vpos, VPOS);
- ENHANCEMENT(saturation, SATURATION);
- ENHANCEMENT(contrast, CONTRAST);
- ENHANCEMENT(hue, HUE);
- ENHANCEMENT(sharpness, SHARPNESS);
- ENHANCEMENT(brightness, BRIGHTNESS);
- ENHANCEMENT(flicker_filter, FLICKER_FILTER);
- ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE);
- ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D);
- ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER);
- ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER);
-
- if (enhancements.dot_crawl) {
- if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2))
- return false;
-
- intel_sdvo_connector->max_dot_crawl = 1;
- intel_sdvo_connector->cur_dot_crawl = response & 0x1;
- intel_sdvo_connector->dot_crawl =
- drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
- if (!intel_sdvo_connector->dot_crawl)
- return false;
-
- intel_sdvo_connector->dot_crawl->values[0] = 0;
- intel_sdvo_connector->dot_crawl->values[1] = 1;
- drm_connector_attach_property(connector,
- intel_sdvo_connector->dot_crawl,
- intel_sdvo_connector->cur_dot_crawl);
- DRM_DEBUG_KMS("dot crawl: current %d\n", response);
+ if (IS_TV(sdvo_priv)) {
+ /* when horizontal overscan is supported, Add the left/right
+ * property
+ */
+ if (sdvo_data.overscan_h) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO max "
+ "h_overscan\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
+ return;
+ }
+ sdvo_priv->max_hscan = data_value[0];
+ sdvo_priv->left_margin = data_value[0] - response;
+ sdvo_priv->right_margin = sdvo_priv->left_margin;
+ sdvo_priv->left_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "left_margin", 2);
+ sdvo_priv->left_property->values[0] = 0;
+ sdvo_priv->left_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->left_property,
+ sdvo_priv->left_margin);
+ sdvo_priv->right_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "right_margin", 2);
+ sdvo_priv->right_property->values[0] = 0;
+ sdvo_priv->right_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->right_property,
+ sdvo_priv->right_margin);
+ DRM_DEBUG_KMS("h_overscan: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.overscan_v) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO max "
+ "v_overscan\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
+ return;
+ }
+ sdvo_priv->max_vscan = data_value[0];
+ sdvo_priv->top_margin = data_value[0] - response;
+ sdvo_priv->bottom_margin = sdvo_priv->top_margin;
+ sdvo_priv->top_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "top_margin", 2);
+ sdvo_priv->top_property->values[0] = 0;
+ sdvo_priv->top_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->top_property,
+ sdvo_priv->top_margin);
+ sdvo_priv->bottom_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "bottom_margin", 2);
+ sdvo_priv->bottom_property->values[0] = 0;
+ sdvo_priv->bottom_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->bottom_property,
+ sdvo_priv->bottom_margin);
+ DRM_DEBUG_KMS("v_overscan: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.position_h) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_POSITION_H, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
+ return;
+ }
+ sdvo_priv->max_hpos = data_value[0];
+ sdvo_priv->cur_hpos = response;
+ sdvo_priv->hpos_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "hpos", 2);
+ sdvo_priv->hpos_property->values[0] = 0;
+ sdvo_priv->hpos_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->hpos_property,
+ sdvo_priv->cur_hpos);
+ DRM_DEBUG_KMS("h_position: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.position_v) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_POSITION_V, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
+ return;
+ }
+ sdvo_priv->max_vpos = data_value[0];
+ sdvo_priv->cur_vpos = response;
+ sdvo_priv->vpos_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "vpos", 2);
+ sdvo_priv->vpos_property->values[0] = 0;
+ sdvo_priv->vpos_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->vpos_property,
+ sdvo_priv->cur_vpos);
+ DRM_DEBUG_KMS("v_position: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.saturation) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_SATURATION, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
+ return;
+ }
+ sdvo_priv->max_saturation = data_value[0];
+ sdvo_priv->cur_saturation = response;
+ sdvo_priv->saturation_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "saturation", 2);
+ sdvo_priv->saturation_property->values[0] = 0;
+ sdvo_priv->saturation_property->values[1] =
+ data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->saturation_property,
+ sdvo_priv->cur_saturation);
+ DRM_DEBUG_KMS("saturation: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.contrast) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_CONTRAST, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
+ return;
+ }
+ sdvo_priv->max_contrast = data_value[0];
+ sdvo_priv->cur_contrast = response;
+ sdvo_priv->contrast_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "contrast", 2);
+ sdvo_priv->contrast_property->values[0] = 0;
+ sdvo_priv->contrast_property->values[1] = data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->contrast_property,
+ sdvo_priv->cur_contrast);
+ DRM_DEBUG_KMS("contrast: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
+ if (sdvo_data.hue) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_HUE, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_HUE, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
+ return;
+ }
+ sdvo_priv->max_hue = data_value[0];
+ sdvo_priv->cur_hue = response;
+ sdvo_priv->hue_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "hue", 2);
+ sdvo_priv->hue_property->values[0] = 0;
+ sdvo_priv->hue_property->values[1] =
+ data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->hue_property,
+ sdvo_priv->cur_hue);
+ DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
}
-
- return true;
-}
-
-static bool
-intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector,
- struct intel_sdvo_enhancements_reply enhancements)
-{
- struct drm_device *dev = intel_sdvo->base.enc.dev;
- struct drm_connector *connector = &intel_sdvo_connector->base.base;
- uint16_t response, data_value[2];
-
- ENHANCEMENT(brightness, BRIGHTNESS);
-
- return true;
-}
-#undef ENHANCEMENT
-
-static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
- struct intel_sdvo_connector *intel_sdvo_connector)
-{
- union {
- struct intel_sdvo_enhancements_reply reply;
- uint16_t response;
- } enhancements;
-
- if (!intel_sdvo_get_value(intel_sdvo,
- SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
- &enhancements, sizeof(enhancements)))
- return false;
-
- if (enhancements.response == 0) {
- DRM_DEBUG_KMS("No enhancement is supported\n");
- return true;
+ if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) {
+ if (sdvo_data.brightness) {
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &data_value, 4);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
+ return;
+ }
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder,
+ &response, 2);
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
+ return;
+ }
+ sdvo_priv->max_brightness = data_value[0];
+ sdvo_priv->cur_brightness = response;
+ sdvo_priv->brightness_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "brightness", 2);
+ sdvo_priv->brightness_property->values[0] = 0;
+ sdvo_priv->brightness_property->values[1] =
+ data_value[0];
+ drm_connector_attach_property(connector,
+ sdvo_priv->brightness_property,
+ sdvo_priv->cur_brightness);
+ DRM_DEBUG_KMS("brightness: max %d, "
+ "default %d, current %d\n",
+ data_value[0], data_value[1], response);
+ }
}
-
- if (IS_TV(intel_sdvo_connector))
- return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply);
- else if(IS_LVDS(intel_sdvo_connector))
- return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply);
- else
- return true;
-
+ return;
}
bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder;
- struct intel_sdvo *intel_sdvo;
+ struct intel_sdvo_priv *sdvo_priv;
u8 ch[0x40];
int i;
u32 i2c_reg, ddc_reg, analog_ddc_reg;
- intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
- if (!intel_sdvo)
+ intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+ if (!intel_encoder) {
return false;
+ }
- intel_sdvo->sdvo_reg = sdvo_reg;
+ sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+ sdvo_priv->sdvo_reg = sdvo_reg;
- intel_encoder = &intel_sdvo->base;
+ intel_encoder->dev_priv = sdvo_priv;
intel_encoder->type = INTEL_OUTPUT_SDVO;
if (HAS_PCH_SPLIT(dev)) {
@@ -2542,14 +2795,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
if (!intel_encoder->i2c_bus)
goto err_inteloutput;
- intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
+ sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
/* Save the bit-banging i2c functionality for use by the DDC wrapper */
intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
- if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) {
+ if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
IS_SDVOB(sdvo_reg) ? 'B' : 'C');
goto err_i2c;
@@ -2559,16 +2812,17 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
/* setup the DDC bus. */
if (IS_SDVOB(sdvo_reg)) {
intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS");
- intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
"SDVOB/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
} else {
intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS");
- intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg,
"SDVOC/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
}
- if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL)
+
+ if (intel_encoder->ddc_bus == NULL)
goto err_i2c;
/* Wrap with our custom algo which switches to DDC mode */
@@ -2579,56 +2833,53 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
/* In default case sdvo lvds is false */
- if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
- goto err_enc;
+ intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
- if (intel_sdvo_output_setup(intel_sdvo,
- intel_sdvo->caps.output_flags) != true) {
+ if (intel_sdvo_output_setup(intel_encoder,
+ sdvo_priv->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
IS_SDVOB(sdvo_reg) ? 'B' : 'C');
- goto err_enc;
+ goto err_i2c;
}
- intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
+ intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg);
/* Set the input timing to the screen. Assume always input 0. */
- if (!intel_sdvo_set_target_input(intel_sdvo))
- goto err_enc;
+ intel_sdvo_set_target_input(intel_encoder, true, false);
+
+ intel_sdvo_get_input_pixel_clock_range(intel_encoder,
+ &sdvo_priv->pixel_clock_min,
+ &sdvo_priv->pixel_clock_max);
- if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
- &intel_sdvo->pixel_clock_min,
- &intel_sdvo->pixel_clock_max))
- goto err_enc;
DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
"input 1: %c, input 2: %c, "
"output 1: %c, output 2: %c\n",
- SDVO_NAME(intel_sdvo),
- intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,
- intel_sdvo->caps.device_rev_id,
- intel_sdvo->pixel_clock_min / 1000,
- intel_sdvo->pixel_clock_max / 1000,
- (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
- (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
+ SDVO_NAME(sdvo_priv),
+ sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
+ sdvo_priv->caps.device_rev_id,
+ sdvo_priv->pixel_clock_min / 1000,
+ sdvo_priv->pixel_clock_max / 1000,
+ (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
+ (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
/* check currently supported outputs */
- intel_sdvo->caps.output_flags &
+ sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
- intel_sdvo->caps.output_flags &
+ sdvo_priv->caps.output_flags &
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
+
return true;
-err_enc:
- drm_encoder_cleanup(&intel_encoder->enc);
err_i2c:
- if (intel_sdvo->analog_ddc_bus != NULL)
- intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
+ if (sdvo_priv->analog_ddc_bus != NULL)
+ intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
if (intel_encoder->ddc_bus != NULL)
intel_i2c_destroy(intel_encoder->ddc_bus);
if (intel_encoder->i2c_bus != NULL)
intel_i2c_destroy(intel_encoder->i2c_bus);
err_inteloutput:
- kfree(intel_sdvo);
+ kfree(intel_encoder);
return false;
}
diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h
index a386b022e538..ba5cdf8ae40b 100644
--- a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -312,7 +312,7 @@ struct intel_sdvo_set_target_input_args {
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
-/** 6 bytes of bit flags for TV formats shared by all TV format functions */
+/** 5 bytes of bit flags for TV formats shared by all TV format functions */
struct intel_sdvo_tv_format {
unsigned int ntsc_m:1;
unsigned int ntsc_j:1;
@@ -596,32 +596,32 @@ struct intel_sdvo_enhancements_reply {
unsigned int overscan_h:1;
unsigned int overscan_v:1;
- unsigned int hpos:1;
- unsigned int vpos:1;
+ unsigned int position_h:1;
+ unsigned int position_v:1;
unsigned int sharpness:1;
unsigned int dot_crawl:1;
unsigned int dither:1;
- unsigned int tv_chroma_filter:1;
- unsigned int tv_luma_filter:1;
+ unsigned int max_tv_chroma_filter:1;
+ unsigned int max_tv_luma_filter:1;
} __attribute__((packed));
/* Picture enhancement limits below are dependent on the current TV format,
* and thus need to be queried and set after it.
*/
-#define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d
-#define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b
-#define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52
+#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d
+#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b
+#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52
#define SDVO_CMD_GET_MAX_SATURATION 0x55
#define SDVO_CMD_GET_MAX_HUE 0x58
#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b
#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
-#define SDVO_CMD_GET_MAX_HPOS 0x67
-#define SDVO_CMD_GET_MAX_VPOS 0x6a
-#define SDVO_CMD_GET_MAX_SHARPNESS 0x6d
-#define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74
-#define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77
+#define SDVO_CMD_GET_MAX_POSITION_H 0x67
+#define SDVO_CMD_GET_MAX_POSITION_V 0x6a
+#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d
+#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74
+#define SDVO_CMD_GET_MAX_TV_LUMA 0x77
struct intel_sdvo_enhancement_limits_reply {
u16 max_value;
u16 default_value;
@@ -638,10 +638,10 @@ struct intel_sdvo_enhancement_limits_reply {
#define SDVO_CMD_GET_FLICKER_FILTER 0x4e
#define SDVO_CMD_SET_FLICKER_FILTER 0x4f
-#define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50
-#define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51
-#define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53
-#define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54
+#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50
+#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51
+#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53
+#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54
#define SDVO_CMD_GET_SATURATION 0x56
#define SDVO_CMD_SET_SATURATION 0x57
#define SDVO_CMD_GET_HUE 0x59
@@ -654,16 +654,16 @@ struct intel_sdvo_enhancement_limits_reply {
#define SDVO_CMD_SET_OVERSCAN_H 0x63
#define SDVO_CMD_GET_OVERSCAN_V 0x65
#define SDVO_CMD_SET_OVERSCAN_V 0x66
-#define SDVO_CMD_GET_HPOS 0x68
-#define SDVO_CMD_SET_HPOS 0x69
-#define SDVO_CMD_GET_VPOS 0x6b
-#define SDVO_CMD_SET_VPOS 0x6c
+#define SDVO_CMD_GET_POSITION_H 0x68
+#define SDVO_CMD_SET_POSITION_H 0x69
+#define SDVO_CMD_GET_POSITION_V 0x6b
+#define SDVO_CMD_SET_POSITION_V 0x6c
#define SDVO_CMD_GET_SHARPNESS 0x6e
#define SDVO_CMD_SET_SHARPNESS 0x6f
-#define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75
-#define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76
-#define SDVO_CMD_GET_TV_LUMA_FILTER 0x78
-#define SDVO_CMD_SET_TV_LUMA_FILTER 0x79
+#define SDVO_CMD_GET_TV_CHROMA 0x75
+#define SDVO_CMD_SET_TV_CHROMA 0x76
+#define SDVO_CMD_GET_TV_LUMA 0x78
+#define SDVO_CMD_SET_TV_LUMA 0x79
struct intel_sdvo_enhancements_arg {
u16 value;
}__attribute__((packed));
diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c
index d2029efee982..cc3726a4a1cb 100644
--- a/trunk/drivers/gpu/drm/i915/intel_tv.c
+++ b/trunk/drivers/gpu/drm/i915/intel_tv.c
@@ -44,9 +44,7 @@ enum tv_margin {
};
/** Private structure for the integrated TV support */
-struct intel_tv {
- struct intel_encoder base;
-
+struct intel_tv_priv {
int type;
char *tv_format;
int margin[4];
@@ -898,11 +896,6 @@ static const struct tv_mode tv_modes[] = {
},
};
-static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder)
-{
- return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base);
-}
-
static void
intel_tv_dpms(struct drm_encoder *encoder, int mode)
{
@@ -936,17 +929,19 @@ intel_tv_mode_lookup (char *tv_format)
}
static const struct tv_mode *
-intel_tv_mode_find (struct intel_tv *intel_tv)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
{
- return intel_tv_mode_lookup(intel_tv->tv_format);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+
+ return intel_tv_mode_lookup(tv_priv->tv_format);
}
static enum drm_mode_status
intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
/* Ensure TV refresh is close to desired refresh */
if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -962,8 +957,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
{
struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
struct drm_encoder *other_encoder;
if (!tv_mode)
@@ -988,8 +983,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
u32 tv_ctl;
u32 hctl1, hctl2, hctl3;
u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1005,7 +1001,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
tv_ctl = I915_READ(TV_CTL);
tv_ctl &= TV_CTL_SAVE;
- switch (intel_tv->type) {
+ switch (tv_priv->type) {
default:
case DRM_MODE_CONNECTOR_Unknown:
case DRM_MODE_CONNECTOR_Composite:
@@ -1158,11 +1154,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
/* Wait for vblank for the disable to take effect */
if (!IS_I9XX(dev))
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
/* Wait for vblank for the disable to take effect. */
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
/* Filter ctl must be set before TV_WIN_SIZE */
I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
@@ -1172,12 +1168,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
else
ysize = 2*tv_mode->nbr_end + 1;
- xpos += intel_tv->margin[TV_MARGIN_LEFT];
- ypos += intel_tv->margin[TV_MARGIN_TOP];
- xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
- intel_tv->margin[TV_MARGIN_RIGHT]);
- ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
- intel_tv->margin[TV_MARGIN_BOTTOM]);
+ xpos += tv_priv->margin[TV_MARGIN_LEFT];
+ ypos += tv_priv->margin[TV_MARGIN_TOP];
+ xsize -= (tv_priv->margin[TV_MARGIN_LEFT] +
+ tv_priv->margin[TV_MARGIN_RIGHT]);
+ ysize -= (tv_priv->margin[TV_MARGIN_TOP] +
+ tv_priv->margin[TV_MARGIN_BOTTOM]);
I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
@@ -1226,12 +1222,11 @@ static const struct drm_display_mode reported_modes[] = {
* \return false if TV is disconnected.
*/
static int
-intel_tv_detect_type (struct intel_tv *intel_tv)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
{
- struct drm_encoder *encoder = &intel_tv->base.enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
unsigned long irqflags;
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
@@ -1268,11 +1263,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
DAC_C_0_7_V);
I915_WRITE(TV_CTL, tv_ctl);
I915_WRITE(TV_DAC, tv_dac);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
tv_dac = I915_READ(TV_DAC);
I915_WRITE(TV_DAC, save_tv_dac);
I915_WRITE(TV_CTL, save_tv_ctl);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ intel_wait_for_vblank(dev);
/*
* A B C
* 0 1 1 Composite
@@ -1309,11 +1304,12 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
static void intel_tv_find_better_format(struct drm_connector *connector)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
int i;
- if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
+ if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
tv_mode->component_only)
return;
@@ -1321,12 +1317,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
tv_mode = tv_modes + i;
- if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
+ if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
tv_mode->component_only)
break;
}
- intel_tv->tv_format = tv_mode->name;
+ tv_priv->tv_format = tv_mode->name;
drm_connector_property_set_value(connector,
connector->dev->mode_config.tv_mode_property, i);
}
@@ -1340,31 +1336,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
static enum drm_connector_status
intel_tv_detect(struct drm_connector *connector)
{
+ struct drm_crtc *crtc;
struct drm_display_mode mode;
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- int type;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ int dpms_mode;
+ int type = tv_priv->type;
mode = reported_modes[0];
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
if (encoder->crtc && encoder->crtc->enabled) {
- type = intel_tv_detect_type(intel_tv);
+ type = intel_tv_detect_type(encoder->crtc, intel_encoder);
} else {
- struct drm_crtc *crtc;
- int dpms_mode;
-
- crtc = intel_get_load_detect_pipe(&intel_tv->base, connector,
+ crtc = intel_get_load_detect_pipe(intel_encoder, connector,
&mode, &dpms_mode);
if (crtc) {
- type = intel_tv_detect_type(intel_tv);
- intel_release_load_detect_pipe(&intel_tv->base, connector,
+ type = intel_tv_detect_type(crtc, intel_encoder);
+ intel_release_load_detect_pipe(intel_encoder, connector,
dpms_mode);
} else
type = -1;
}
- intel_tv->type = type;
+ tv_priv->type = type;
if (type < 0)
return connector_status_disconnected;
@@ -1395,8 +1391,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector,
struct drm_display_mode *mode_ptr)
{
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1421,8 +1417,8 @@ intel_tv_get_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode_ptr;
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
int j, count = 0;
u64 tmp;
@@ -1487,7 +1483,8 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
{
struct drm_device *dev = connector->dev;
struct drm_encoder *encoder = intel_attached_encoder(connector);
- struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
bool changed = false;
@@ -1497,30 +1494,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
goto out;
if (property == dev->mode_config.tv_left_margin_property &&
- intel_tv->margin[TV_MARGIN_LEFT] != val) {
- intel_tv->margin[TV_MARGIN_LEFT] = val;
+ tv_priv->margin[TV_MARGIN_LEFT] != val) {
+ tv_priv->margin[TV_MARGIN_LEFT] = val;
changed = true;
} else if (property == dev->mode_config.tv_right_margin_property &&
- intel_tv->margin[TV_MARGIN_RIGHT] != val) {
- intel_tv->margin[TV_MARGIN_RIGHT] = val;
+ tv_priv->margin[TV_MARGIN_RIGHT] != val) {
+ tv_priv->margin[TV_MARGIN_RIGHT] = val;
changed = true;
} else if (property == dev->mode_config.tv_top_margin_property &&
- intel_tv->margin[TV_MARGIN_TOP] != val) {
- intel_tv->margin[TV_MARGIN_TOP] = val;
+ tv_priv->margin[TV_MARGIN_TOP] != val) {
+ tv_priv->margin[TV_MARGIN_TOP] = val;
changed = true;
} else if (property == dev->mode_config.tv_bottom_margin_property &&
- intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
- intel_tv->margin[TV_MARGIN_BOTTOM] = val;
+ tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
+ tv_priv->margin[TV_MARGIN_BOTTOM] = val;
changed = true;
} else if (property == dev->mode_config.tv_mode_property) {
if (val >= ARRAY_SIZE(tv_modes)) {
ret = -EINVAL;
goto out;
}
- if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
+ if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
goto out;
- intel_tv->tv_format = tv_modes[val].name;
+ tv_priv->tv_format = tv_modes[val].name;
changed = true;
} else {
ret = -EINVAL;
@@ -1556,8 +1553,16 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs =
.best_encoder = intel_attached_encoder,
};
+static void intel_tv_enc_destroy(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
+}
+
static const struct drm_encoder_funcs intel_tv_enc_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_tv_enc_destroy,
};
/*
@@ -1601,9 +1606,9 @@ intel_tv_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_tv *intel_tv;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
+ struct intel_tv_priv *tv_priv;
u32 tv_dac_on, tv_dac_off, save_tv_dac;
char **tv_format_names;
int i, initial_mode = 0;
@@ -1642,18 +1647,18 @@ intel_tv_init(struct drm_device *dev)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
- intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL);
- if (!intel_tv) {
+ intel_encoder = kzalloc(sizeof(struct intel_encoder) +
+ sizeof(struct intel_tv_priv), GFP_KERNEL);
+ if (!intel_encoder) {
return;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_tv);
+ kfree(intel_encoder);
return;
}
- intel_encoder = &intel_tv->base;
connector = &intel_connector->base;
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
@@ -1663,20 +1668,22 @@ intel_tv_init(struct drm_device *dev)
DRM_MODE_ENCODER_TVDAC);
drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
+ tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
intel_encoder->type = INTEL_OUTPUT_TVOUT;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
- intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
+ intel_encoder->dev_priv = tv_priv;
+ tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
/* BIOS margin values */
- intel_tv->margin[TV_MARGIN_LEFT] = 54;
- intel_tv->margin[TV_MARGIN_TOP] = 36;
- intel_tv->margin[TV_MARGIN_RIGHT] = 46;
- intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
+ tv_priv->margin[TV_MARGIN_LEFT] = 54;
+ tv_priv->margin[TV_MARGIN_TOP] = 36;
+ tv_priv->margin[TV_MARGIN_RIGHT] = 46;
+ tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
- intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
+ tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
@@ -1696,16 +1703,16 @@ intel_tv_init(struct drm_device *dev)
initial_mode);
drm_connector_attach_property(connector,
dev->mode_config.tv_left_margin_property,
- intel_tv->margin[TV_MARGIN_LEFT]);
+ tv_priv->margin[TV_MARGIN_LEFT]);
drm_connector_attach_property(connector,
dev->mode_config.tv_top_margin_property,
- intel_tv->margin[TV_MARGIN_TOP]);
+ tv_priv->margin[TV_MARGIN_TOP]);
drm_connector_attach_property(connector,
dev->mode_config.tv_right_margin_property,
- intel_tv->margin[TV_MARGIN_RIGHT]);
+ tv_priv->margin[TV_MARGIN_RIGHT]);
drm_connector_attach_property(connector,
dev->mode_config.tv_bottom_margin_property,
- intel_tv->margin[TV_MARGIN_BOTTOM]);
+ tv_priv->margin[TV_MARGIN_BOTTOM]);
out:
drm_sysfs_connector_add(connector);
}
diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c
index 0c52899be964..e635199a0cd2 100644
--- a/trunk/drivers/hid/hid-core.c
+++ b/trunk/drivers/hid/hid-core.c
@@ -1299,7 +1299,6 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
diff --git a/trunk/drivers/hid/hid-egalax.c b/trunk/drivers/hid/hid-egalax.c
index 8ca7f65cf2f8..f44bdc084cb2 100644
--- a/trunk/drivers/hid/hid-egalax.c
+++ b/trunk/drivers/hid/hid-egalax.c
@@ -159,13 +159,6 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
{
struct egalax_data *td = hid_get_drvdata(hid);
- /* Note, eGalax has two product lines: the first is resistive and
- * uses a standard parallel multitouch protocol (product ID ==
- * 48xx). The second is capacitive and uses an unusual "serial"
- * protocol with a different message for each multitouch finger
- * (product ID == 72xx). We do not yet generate a correct event
- * sequence for the capacitive/serial protocol.
- */
if (hid->claimed & HID_CLAIMED_INPUT) {
struct input_dev *input = field->hidinput->input;
@@ -253,8 +246,6 @@ static void egalax_remove(struct hid_device *hdev)
static const struct hid_device_id egalax_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
{ }
};
MODULE_DEVICE_TABLE(hid, egalax_devices);
diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h
index 85c6d13c9ffa..d3fc13ae094d 100644
--- a/trunk/drivers/hid/hid-ids.h
+++ b/trunk/drivers/hid/hid-ids.h
@@ -188,7 +188,6 @@
#define USB_VENDOR_ID_DWAV 0x0eef
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
diff --git a/trunk/drivers/hid/hid-picolcd.c b/trunk/drivers/hid/hid-picolcd.c
index bc2e07740628..346f0e34987e 100644
--- a/trunk/drivers/hid/hid-picolcd.c
+++ b/trunk/drivers/hid/hid-picolcd.c
@@ -547,11 +547,11 @@ static void picolcd_fb_destroy(struct fb_info *info)
ref_cnt--;
mutex_lock(&info->lock);
(*ref_cnt)--;
- may_release = !*ref_cnt;
+ may_release = !ref_cnt;
mutex_unlock(&info->lock);
if (may_release) {
- vfree((u8 *)info->fix.smem_start);
framebuffer_release(info);
+ vfree((u8 *)info->fix.smem_start);
}
}
diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c
index 0a29c51114aa..254a003af048 100644
--- a/trunk/drivers/hid/usbhid/hiddev.c
+++ b/trunk/drivers/hid/usbhid/hiddev.c
@@ -266,15 +266,13 @@ static int hiddev_open(struct inode *inode, struct file *file)
{
struct hiddev_list *list;
struct usb_interface *intf;
- struct hid_device *hid;
struct hiddev *hiddev;
int res;
intf = usb_find_interface(&hiddev_driver, iminor(inode));
if (!intf)
return -ENODEV;
- hid = usb_get_intfdata(intf);
- hiddev = hid->hiddev;
+ hiddev = usb_get_intfdata(intf);
if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
return -ENOMEM;
@@ -589,7 +587,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev;
struct hid_device *hid = hiddev->hid;
- struct usb_device *dev;
+ struct usb_device *dev = hid_to_usb_dev(hid);
struct hiddev_collection_info cinfo;
struct hiddev_report_info rinfo;
struct hiddev_field_info finfo;
@@ -603,11 +601,9 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* Called without BKL by compat methods so no BKL taken */
/* FIXME: Who or what stop this racing with a disconnect ?? */
- if (!hiddev->exist || !hid)
+ if (!hiddev->exist)
return -EIO;
- dev = hid_to_usb_dev(hid);
-
switch (cmd) {
case HIDIOCGVERSION:
@@ -892,6 +888,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hid->hiddev = hiddev;
hiddev->hid = hid;
hiddev->exist = 1;
+ usb_set_intfdata(usbhid->intf, usbhid);
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig
index 4d4d09bdec0a..0fba82943125 100644
--- a/trunk/drivers/hwmon/Kconfig
+++ b/trunk/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
will be called f71805f.
config SENSORS_F71882FG
- tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+ tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
depends on EXPERIMENTAL
help
- If you say yes here you get support for hardware monitoring
- features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+ If you say yes here you get support for hardware monitoring features
+ of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
F71889FG and F8000 Super-I/O chips.
This driver can also be built as a module. If so, the module
diff --git a/trunk/drivers/hwmon/f71882fg.c b/trunk/drivers/hwmon/f71882fg.c
index 537841ef44b9..6207120dcd4d 100644
--- a/trunk/drivers/hwmon/f71882fg.c
+++ b/trunk/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
+#define SIO_F71808_ID 0x0901 /* Chipset ID */
#define SIO_F71858_ID 0x0507 /* Chipset ID */
#define SIO_F71862_ID 0x0601 /* Chipset ID */
#define SIO_F71882_ID 0x0541 /* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
static const char *f71882fg_names[] = {
+ "f71808fg",
"f71858fg",
"f71862fg",
"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
};
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+ SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+ SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+ SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+ SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+ SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+ SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+ SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+ SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
store_temp_beep, 0, 6),
SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
data->temp_type[1] = 6;
break;
}
+ } else if (data->type == f71808fg) {
+ reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+ data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+ data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
} else {
reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
if ((reg2 & 0x03) == 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
val /= 1000;
- if (data->type == f71889fg)
+ if (data->type == f71889fg
+ || data->type == f71808fg)
val = SENSORS_LIMIT(val, -128, 127);
else
val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,28 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
/* fall through! */
case f71862fg:
err = f71882fg_create_sysfs_files(pdev,
- fxxxx_in_temp_attr,
- ARRAY_SIZE(fxxxx_in_temp_attr));
+ f71862_temp_attr,
+ ARRAY_SIZE(f71862_temp_attr));
+ if (err)
+ goto exit_unregister_sysfs;
+ err = f71882fg_create_sysfs_files(pdev,
+ fxxxx_in_attr,
+ ARRAY_SIZE(fxxxx_in_attr));
+ if (err)
+ goto exit_unregister_sysfs;
+ err = f71882fg_create_sysfs_files(pdev,
+ fxxxx_temp_attr,
+ ARRAY_SIZE(fxxxx_temp_attr));
+ break;
+ case f71808fg:
+ err = f71882fg_create_sysfs_files(pdev,
+ f71808_in_attr,
+ ARRAY_SIZE(f71808_in_attr));
+ if (err)
+ goto exit_unregister_sysfs;
+ err = f71882fg_create_sysfs_files(pdev,
+ fxxxx_temp_attr,
+ ARRAY_SIZE(fxxxx_temp_attr));
break;
case f8000:
err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2050,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
case f71862fg:
err = (data->pwm_enable & 0x15) != 0x15;
break;
+ case f71808fg:
case f71882fg:
case f71889fg:
err = 0;
@@ -2047,6 +2096,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
f8000_auto_pwm_attr,
ARRAY_SIZE(f8000_auto_pwm_attr));
break;
+ case f71808fg:
case f71889fg:
for (i = 0; i < nr_fans; i++) {
data->pwm_auto_point_mapping[i] =
@@ -2126,8 +2176,22 @@ static int f71882fg_remove(struct platform_device *pdev)
/* fall through! */
case f71862fg:
f71882fg_remove_sysfs_files(pdev,
- fxxxx_in_temp_attr,
- ARRAY_SIZE(fxxxx_in_temp_attr));
+ f71862_temp_attr,
+ ARRAY_SIZE(f71862_temp_attr));
+ f71882fg_remove_sysfs_files(pdev,
+ fxxxx_in_attr,
+ ARRAY_SIZE(fxxxx_in_attr));
+ f71882fg_remove_sysfs_files(pdev,
+ fxxxx_temp_attr,
+ ARRAY_SIZE(fxxxx_temp_attr));
+ break;
+ case f71808fg:
+ f71882fg_remove_sysfs_files(pdev,
+ f71808_in_attr,
+ ARRAY_SIZE(f71808_in_attr));
+ f71882fg_remove_sysfs_files(pdev,
+ fxxxx_temp_attr,
+ ARRAY_SIZE(fxxxx_temp_attr));
break;
case f8000:
f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2259,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
switch (devid) {
+ case SIO_F71808_ID:
+ sio_data->type = f71808fg;
+ break;
case SIO_F71858_ID:
sio_data->type = f71858fg;
break;
diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c
index c148b6302154..11567c7999a2 100644
--- a/trunk/drivers/md/md.c
+++ b/trunk/drivers/md/md.c
@@ -2136,6 +2136,16 @@ static void sync_sbs(mddev_t * mddev, int nospares)
* with the rest of the array)
*/
mdk_rdev_t *rdev;
+
+ /* First make sure individual recovery_offsets are correct */
+ list_for_each_entry(rdev, &mddev->disks, same_set) {
+ if (rdev->raid_disk >= 0 &&
+ mddev->delta_disks >= 0 &&
+ !test_bit(In_sync, &rdev->flags) &&
+ mddev->curr_resync_completed > rdev->recovery_offset)
+ rdev->recovery_offset = mddev->curr_resync_completed;
+
+ }
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (rdev->sb_events == mddev->events ||
(nospares &&
@@ -2157,27 +2167,12 @@ static void md_update_sb(mddev_t * mddev, int force_change)
int sync_req;
int nospares = 0;
-repeat:
- /* First make sure individual recovery_offsets are correct */
- list_for_each_entry(rdev, &mddev->disks, same_set) {
- if (rdev->raid_disk >= 0 &&
- mddev->delta_disks >= 0 &&
- !test_bit(In_sync, &rdev->flags) &&
- mddev->curr_resync_completed > rdev->recovery_offset)
- rdev->recovery_offset = mddev->curr_resync_completed;
-
- }
- if (mddev->external || !mddev->persistent) {
- clear_bit(MD_CHANGE_DEVS, &mddev->flags);
- clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
- wake_up(&mddev->sb_wait);
+ mddev->utime = get_seconds();
+ if (mddev->external)
return;
- }
-
+repeat:
spin_lock_irq(&mddev->write_lock);
- mddev->utime = get_seconds();
-
set_bit(MD_CHANGE_PENDING, &mddev->flags);
if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
force_change = 1;
@@ -2226,6 +2221,19 @@ static void md_update_sb(mddev_t * mddev, int force_change)
MD_BUG();
mddev->events --;
}
+
+ /*
+ * do not write anything to disk if using
+ * nonpersistent superblocks
+ */
+ if (!mddev->persistent) {
+ if (!mddev->external)
+ clear_bit(MD_CHANGE_PENDING, &mddev->flags);
+
+ spin_unlock_irq(&mddev->write_lock);
+ wake_up(&mddev->sb_wait);
+ return;
+ }
sync_sbs(mddev, nospares);
spin_unlock_irq(&mddev->write_lock);
diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c
index ad83a4dcadc3..73cc74ffc26b 100644
--- a/trunk/drivers/md/raid1.c
+++ b/trunk/drivers/md/raid1.c
@@ -787,8 +787,8 @@ static int make_request(mddev_t *mddev, struct bio * bio)
struct bio_list bl;
struct page **behind_pages = NULL;
const int rw = bio_data_dir(bio);
- const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
- unsigned long do_barriers;
+ const bool do_sync = (bio->bi_rw & REQ_SYNC);
+ bool do_barriers;
mdk_rdev_t *blocked_rdev;
/*
@@ -1120,8 +1120,6 @@ static int raid1_spare_active(mddev_t *mddev)
{
int i;
conf_t *conf = mddev->private;
- int count = 0;
- unsigned long flags;
/*
* Find all failed disks within the RAID1 configuration
@@ -1133,16 +1131,15 @@ static int raid1_spare_active(mddev_t *mddev)
if (rdev
&& !test_bit(Faulty, &rdev->flags)
&& !test_and_set_bit(In_sync, &rdev->flags)) {
- count++;
- sysfs_notify_dirent(rdev->sysfs_state);
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded--;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded -= count;
- spin_unlock_irqrestore(&conf->device_lock, flags);
print_conf(conf);
- return count;
+ return 0;
}
@@ -1643,7 +1640,7 @@ static void raid1d(mddev_t *mddev)
* We already have a nr_pending reference on these rdevs.
*/
int i;
- const unsigned long do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC);
+ const bool do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC);
clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
clear_bit(R1BIO_Barrier, &r1_bio->state);
for (i=0; i < conf->raid_disks; i++)
@@ -1699,7 +1696,7 @@ static void raid1d(mddev_t *mddev)
(unsigned long long)r1_bio->sector);
raid_end_bio_io(r1_bio);
} else {
- const unsigned long do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC;
+ const bool do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC;
r1_bio->bios[r1_bio->read_disk] =
mddev->ro ? IO_BLOCKED : NULL;
r1_bio->read_disk = disk;
diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c
index 84718383124d..a88aeb5198c7 100644
--- a/trunk/drivers/md/raid10.c
+++ b/trunk/drivers/md/raid10.c
@@ -799,7 +799,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
int i;
int chunk_sects = conf->chunk_mask + 1;
const int rw = bio_data_dir(bio);
- const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
+ const bool do_sync = (bio->bi_rw & REQ_SYNC);
struct bio_list bl;
unsigned long flags;
mdk_rdev_t *blocked_rdev;
@@ -1116,8 +1116,6 @@ static int raid10_spare_active(mddev_t *mddev)
int i;
conf_t *conf = mddev->private;
mirror_info_t *tmp;
- int count = 0;
- unsigned long flags;
/*
* Find all non-in_sync disks within the RAID10 configuration
@@ -1128,16 +1126,15 @@ static int raid10_spare_active(mddev_t *mddev)
if (tmp->rdev
&& !test_bit(Faulty, &tmp->rdev->flags)
&& !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
- count++;
- sysfs_notify_dirent(tmp->rdev->sysfs_state);
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded--;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded -= count;
- spin_unlock_irqrestore(&conf->device_lock, flags);
print_conf(conf);
- return count;
+ return 0;
}
@@ -1737,7 +1734,7 @@ static void raid10d(mddev_t *mddev)
raid_end_bio_io(r10_bio);
bio_put(bio);
} else {
- const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
+ const bool do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
bio_put(bio);
rdev = conf->mirrors[mirror].rdev;
if (printk_ratelimit())
diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c
index 69b0a169e43d..866d4b5a144c 100644
--- a/trunk/drivers/md/raid5.c
+++ b/trunk/drivers/md/raid5.c
@@ -5330,8 +5330,6 @@ static int raid5_spare_active(mddev_t *mddev)
int i;
raid5_conf_t *conf = mddev->private;
struct disk_info *tmp;
- int count = 0;
- unsigned long flags;
for (i = 0; i < conf->raid_disks; i++) {
tmp = conf->disks + i;
@@ -5339,15 +5337,14 @@ static int raid5_spare_active(mddev_t *mddev)
&& tmp->rdev->recovery_offset == MaxSector
&& !test_bit(Faulty, &tmp->rdev->flags)
&& !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
- count++;
- sysfs_notify_dirent(tmp->rdev->sysfs_state);
+ unsigned long flags;
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded--;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
}
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded -= count;
- spin_unlock_irqrestore(&conf->device_lock, flags);
print_raid5_conf(conf);
- return count;
+ return 0;
}
static int raid5_remove_disk(mddev_t *mddev, int number)
diff --git a/trunk/drivers/mmc/core/host.c b/trunk/drivers/mmc/core/host.c
index d80cfdc8edd2..0efe631e50ca 100644
--- a/trunk/drivers/mmc/core/host.c
+++ b/trunk/drivers/mmc/core/host.c
@@ -86,9 +86,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
init_waitqueue_head(&host->wq);
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);
-#ifdef CONFIG_PM
host->pm_notify.notifier_call = mmc_pm_notify;
-#endif
/*
* By default, hosts do not support SGIO or large requests.
diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig
index 68d12794cfd9..283190bc2a40 100644
--- a/trunk/drivers/mmc/host/Kconfig
+++ b/trunk/drivers/mmc/host/Kconfig
@@ -132,7 +132,7 @@ config MMC_SDHCI_CNS3XXX
config MMC_SDHCI_S3C
tristate "SDHCI support on Samsung S3C SoC"
- depends on MMC_SDHCI && PLAT_SAMSUNG
+ depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX)
help
This selects the Secure Digital Host Controller Interface (SDHCI)
often referrered to as the HSMMC block in some of the Samsung S3C
diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c
index 71ad4163b95e..0a7f2614c6f0 100644
--- a/trunk/drivers/mmc/host/sdhci-s3c.c
+++ b/trunk/drivers/mmc/host/sdhci-s3c.c
@@ -242,7 +242,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
{
struct sdhci_host *host = platform_get_drvdata(dev);
if (host) {
- spin_lock(&host->lock);
+ mutex_lock(&host->lock);
if (state) {
dev_dbg(&dev->dev, "card inserted.\n");
host->flags &= ~SDHCI_DEVICE_DEAD;
@@ -252,8 +252,8 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
host->flags |= SDHCI_DEVICE_DEAD;
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
- tasklet_schedule(&host->card_tasklet);
- spin_unlock(&host->lock);
+ sdhci_card_detect(host);
+ mutex_unlock(&host->lock);
}
}
diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c
index 401527d273b5..785512133b50 100644
--- a/trunk/drivers/mmc/host/sdhci.c
+++ b/trunk/drivers/mmc/host/sdhci.c
@@ -1180,8 +1180,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
ctrl &= ~SDHCI_CTRL_4BITBUS;
- if (ios->timing == MMC_TIMING_SD_HS &&
- !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
+ if (ios->timing == MMC_TIMING_SD_HS)
ctrl |= SDHCI_CTRL_HISPD;
else
ctrl &= ~SDHCI_CTRL_HISPD;
diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h
index d316bc79b636..036cfae76368 100644
--- a/trunk/drivers/mmc/host/sdhci.h
+++ b/trunk/drivers/mmc/host/sdhci.h
@@ -245,8 +245,6 @@ struct sdhci_host {
#define SDHCI_QUIRK_MISSING_CAPS (1<<27)
/* Controller uses Auto CMD12 command to stop the transfer */
#define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28)
-/* Controller doesn't have HISPD bit field in HI-SPEED SD card */
-#define SDHCI_QUIRK_NO_HISPD_BIT (1<<29)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c
index fe63f6bd663c..00af55d7afba 100644
--- a/trunk/drivers/mtd/maps/physmap_of.c
+++ b/trunk/drivers/mtd/maps/physmap_of.c
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c
index d551ddd9537a..a3c7473dd409 100644
--- a/trunk/drivers/mtd/nand/nand_base.c
+++ b/trunk/drivers/mtd/nand/nand_base.c
@@ -2866,7 +2866,6 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
*/
if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
id_data[0] == NAND_MFR_SAMSUNG &&
- (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
id_data[5] != 0x00) {
/* Calc pagesize */
mtd->writesize = 2048 << (extid & 0x03);
@@ -2935,10 +2934,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
/* Set the bad block position */
- if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
- chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
- else
+ if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO ||
+ (*maf_id == NAND_MFR_SAMSUNG &&
+ mtd->writesize == 512) ||
+ *maf_id == NAND_MFR_AMD))
chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+ else
+ chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+
/* Get chip options, preserve non chip based options */
chip->options &= ~NAND_CHIPOPTIONS_MSK;
diff --git a/trunk/drivers/mtd/nand/pxa3xx_nand.c b/trunk/drivers/mtd/nand/pxa3xx_nand.c
index 4d89f3780207..e02fa4f0e3c9 100644
--- a/trunk/drivers/mtd/nand/pxa3xx_nand.c
+++ b/trunk/drivers/mtd/nand/pxa3xx_nand.c
@@ -363,7 +363,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
/* convert nano-seconds to nand flash controller clock cycles */
-#define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000)
+#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
/* convert nand flash controller clock cycles to nano-seconds */
#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c
index 373dcfec689c..0d5de2574dd1 100644
--- a/trunk/drivers/net/wireless/ath/ath5k/base.c
+++ b/trunk/drivers/net/wireless/ath/ath5k/base.c
@@ -48,7 +48,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -477,26 +476,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
int ret;
u8 csz;
- /*
- * L0s needs to be disabled on all ath5k cards.
- *
- * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
- * by default in the future in 2.6.36) this will also mean both L1 and
- * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
- * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
- * though but cannot currently undue the effect of a blacklist, for
- * details you can read pcie_aspm_sanity_check() and see how it adjusts
- * the device link capability.
- *
- * It may be possible in the future to implement some PCI API to allow
- * drivers to override blacklists for pre 1.1 PCIe but for now it is
- * best to accept that both L0s and L1 will be disabled completely for
- * distributions shipping with CONFIG_PCIEASPM rather than having this
- * issue present. Motivation for adding this new API will be to help
- * with power consumption for some of these devices.
- */
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
-
ret = pci_enable_device(pdev);
if (ret) {
dev_err(&pdev->dev, "can't enable device\n");
diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
index 7f48df1e2903..8750c558c221 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -191,7 +191,6 @@
#define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1
#define AR9287_EEP_START_LOC 128
-#define AR9287_HTC_EEP_START_LOC 256
#define AR9287_NUM_2G_CAL_PIERS 3
#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
#define AR9287_NUM_2G_20_TARGET_POWERS 3
diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index dff2da777312..4a52cf03808b 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -34,14 +34,9 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
struct ath_common *common = ath9k_hw_common(ah);
u16 *eep_data;
- int addr, eep_start_loc;
+ int addr, eep_start_loc = AR9287_EEP_START_LOC;
eep_data = (u16 *)eep;
- if (ah->hw_version.devid == 0x7015)
- eep_start_loc = AR9287_HTC_EEP_START_LOC;
- else
- eep_start_loc = AR9287_EEP_START_LOC;
-
if (!ath9k_hw_use_flash(ah)) {
ath_print(common, ATH_DBG_EEPROM,
"Reading from EEPROM, not flash\n");
diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
index 17e7a9a367e7..61c1bee3f26a 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -799,7 +799,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
}
kfree(buf);
- if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015))
+ if (hif_dev->device_id == 0x7010)
firm_offset = AR7010_FIRMWARE_TEXT;
else
firm_offset = AR9271_FIRMWARE_TEXT;
@@ -901,7 +901,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
switch(hif_dev->device_id) {
case 0x7010:
- case 0x7015:
case 0x9018:
if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
hif_dev->fw_name = FIRMWARE_AR7010_1_1;
@@ -913,6 +912,11 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
break;
}
+ if (!hif_dev->fw_name) {
+ dev_err(&udev->dev, "Can't determine firmware !\n");
+ goto err_htc_hw_alloc;
+ }
+
ret = ath9k_hif_usb_dev_init(hif_dev);
if (ret) {
ret = -EINVAL;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 2d4279191d7a..148b43317fdb 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -245,7 +245,6 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
switch(devid) {
case 0x7010:
- case 0x7015:
case 0x9018:
priv->htc->credits = 45;
break;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 7d09b4b17bbd..ebed9d1691a5 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -366,8 +366,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
caps = WLAN_RC_HT_FLAG;
if (sta->ht_cap.mcs.rx_mask[1])
caps |= WLAN_RC_DS_FLAG;
- if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
- (conf_is_ht40(&priv->hw->conf)))
+ if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
caps |= WLAN_RC_40_FLAG;
if (conf_is_ht40(&priv->hw->conf) &&
(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 2a6e45a293a9..bd0b4acc3ece 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -78,23 +78,18 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = tx_info->control.sta;
struct ath9k_htc_sta *ista;
+ struct ath9k_htc_vif *avp;
struct ath9k_htc_tx_ctl tx_ctl;
enum htc_endpoint_id epid;
u16 qnum;
__le16 fc;
u8 *tx_fhdr;
- u8 sta_idx, vif_idx;
+ u8 sta_idx;
hdr = (struct ieee80211_hdr *) skb->data;
fc = hdr->frame_control;
- if (tx_info->control.vif &&
- (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv)
- vif_idx = ((struct ath9k_htc_vif *)
- tx_info->control.vif->drv_priv)->index;
- else
- vif_idx = priv->nvifs;
-
+ avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
if (sta) {
ista = (struct ath9k_htc_sta *) sta->drv_priv;
sta_idx = ista->index;
@@ -111,7 +106,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
tx_hdr.node_idx = sta_idx;
- tx_hdr.vif_idx = vif_idx;
+ tx_hdr.vif_idx = avp->index;
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
tx_ctl.type = ATH9K_HTC_AMPDU;
@@ -174,7 +169,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
tx_ctl.type = ATH9K_HTC_NORMAL;
mgmt_hdr.node_idx = sta_idx;
- mgmt_hdr.vif_idx = vif_idx;
+ mgmt_hdr.vif_idx = avp->index;
mgmt_hdr.tidno = 0;
mgmt_hdr.flags = 0;
diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h
index d01c4adab8d6..633e3d949ec0 100644
--- a/trunk/drivers/net/wireless/ath/ath9k/reg.h
+++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h
@@ -899,7 +899,6 @@
#define AR_DEVID_7010(_ah) \
(((_ah)->hw_version.devid == 0x7010) || \
- ((_ah)->hw_version.devid == 0x7015) || \
((_ah)->hw_version.devid == 0x9018))
#define AR_RADIO_SREV_MAJOR 0xf0
diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c
index 1189dbb6e2a6..16bbfa3189a5 100644
--- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6665,13 +6665,12 @@ static int __init ipw2100_init(void)
printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
- pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
-
ret = pci_register_driver(&ipw2100_pci_driver);
if (ret)
goto out;
+ pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+ PM_QOS_DEFAULT_VALUE);
#ifdef CONFIG_IPW2100_DEBUG
ipw2100_debug_level = debug;
ret = driver_create_file(&ipw2100_pci_driver.driver,
diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.c b/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.c
index ce3722f4c3e3..a37b30cef489 100644
--- a/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -484,7 +484,7 @@ int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
cmd->timeout = timeout;
- ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
+ ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
if (ret < 0) {
wl1251_error("cmd trigger scan to failed: %d", ret);
goto out;
diff --git a/trunk/drivers/platform/x86/asus_acpi.c b/trunk/drivers/platform/x86/asus_acpi.c
index ca05aefd03bf..e058c2ba2a15 100644
--- a/trunk/drivers/platform/x86/asus_acpi.c
+++ b/trunk/drivers/platform/x86/asus_acpi.c
@@ -938,11 +938,10 @@ static int set_brightness(int value)
/* SPLV laptop */
if (hotk->methods->brightness_set) {
if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
- value, NULL)) {
+ value, NULL))
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
ret = -EIO;
- }
goto out;
}
@@ -954,11 +953,10 @@ static int set_brightness(int value)
hotk->methods->brightness_down,
NULL, NULL);
(value > 0) ? value-- : value++;
- if (ACPI_FAILURE(status)) {
+ if (ACPI_FAILURE(status))
printk(KERN_WARNING
"Asus ACPI: Error changing brightness\n");
ret = -EIO;
- }
}
out:
return ret;
diff --git a/trunk/drivers/platform/x86/compal-laptop.c b/trunk/drivers/platform/x86/compal-laptop.c
index 097083cac413..d071ce056322 100644
--- a/trunk/drivers/platform/x86/compal-laptop.c
+++ b/trunk/drivers/platform/x86/compal-laptop.c
@@ -840,14 +840,6 @@ static struct dmi_system_id __initdata compal_dmi_table[] = {
},
.callback = dmi_check_cb
},
- {
- .ident = "Dell Mini 1012",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
- },
- .callback = dmi_check_cb
- },
{
.ident = "Dell Inspiron 11z",
.matches = {
@@ -1100,6 +1092,5 @@ MODULE_ALIAS("dmi:*:rnJHL90:rvrREFERENCE:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*");
-MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1012:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*");
MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*");
diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c
index 4413975912e0..b41ed5cab3e7 100644
--- a/trunk/drivers/platform/x86/dell-laptop.c
+++ b/trunk/drivers/platform/x86/dell-laptop.c
@@ -121,13 +121,6 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
},
},
- {
- .ident = "Dell Mini 1012",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
- },
- },
{
.ident = "Dell Inspiron 11z",
.matches = {
diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c
index 9024480a8228..afe82e50dfea 100644
--- a/trunk/drivers/platform/x86/intel_ips.c
+++ b/trunk/drivers/platform/x86/intel_ips.c
@@ -1342,10 +1342,8 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
limits = &ips_lv_limits;
else if (strstr(boot_cpu_data.x86_model_id, "CPU U"))
limits = &ips_ulv_limits;
- else {
+ else
dev_info(&ips->dev->dev, "No CPUID match found.\n");
- goto out;
- }
rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power);
tdp = turbo_power & TURBO_TDP_MASK;
@@ -1434,12 +1432,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
spin_lock_init(&ips->turbo_status_lock);
- ret = pci_enable_device(dev);
- if (ret) {
- dev_err(&dev->dev, "can't enable PCI device, aborting\n");
- goto error_free;
- }
-
if (!pci_resource_start(dev, 0)) {
dev_err(&dev->dev, "TBAR not assigned, aborting\n");
ret = -ENXIO;
@@ -1452,6 +1444,11 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto error_free;
}
+ ret = pci_enable_device(dev);
+ if (ret) {
+ dev_err(&dev->dev, "can't enable PCI device, aborting\n");
+ goto error_free;
+ }
ips->regmap = ioremap(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));
diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c
index e35ed128bdef..5d6119bed00c 100644
--- a/trunk/drivers/platform/x86/thinkpad_acpi.c
+++ b/trunk/drivers/platform/x86/thinkpad_acpi.c
@@ -1911,17 +1911,6 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
TP_ACPI_HOTKEYSCAN_MUTE,
TP_ACPI_HOTKEYSCAN_THINKPAD,
- TP_ACPI_HOTKEYSCAN_UNK1,
- TP_ACPI_HOTKEYSCAN_UNK2,
- TP_ACPI_HOTKEYSCAN_UNK3,
- TP_ACPI_HOTKEYSCAN_UNK4,
- TP_ACPI_HOTKEYSCAN_UNK5,
- TP_ACPI_HOTKEYSCAN_UNK6,
- TP_ACPI_HOTKEYSCAN_UNK7,
- TP_ACPI_HOTKEYSCAN_UNK8,
-
- /* Hotkey keymap size */
- TPACPI_HOTKEY_MAP_LEN
};
enum { /* Keys/events available through NVRAM polling */
@@ -3093,8 +3082,6 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
};
-typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
-
static int __init hotkey_init(struct ibm_init_struct *iibm)
{
/* Requirements for changing the default keymaps:
@@ -3126,17 +3113,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
* If the above is too much to ask, don't change the keymap.
* Ask the thinkpad-acpi maintainer to do it, instead.
*/
-
- enum keymap_index {
- TPACPI_KEYMAP_IBM_GENERIC = 0,
- TPACPI_KEYMAP_LENOVO_GENERIC,
- };
-
- static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
- /* Generic keymap for IBM ThinkPads */
- [TPACPI_KEYMAP_IBM_GENERIC] = {
+ static u16 ibm_keycode_map[] __initdata = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
- KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP,
+ KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
@@ -3167,13 +3146,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
- },
-
- /* Generic keymap for Lenovo ThinkPads */
- [TPACPI_KEYMAP_LENOVO_GENERIC] = {
+ };
+ static u16 lenovo_keycode_map[] __initdata = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
- KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
+ KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
/* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
@@ -3212,25 +3189,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
- },
- };
-
- static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
- /* Generic maps (fallback) */
- {
- .vendor = PCI_VENDOR_ID_IBM,
- .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
- .quirks = TPACPI_KEYMAP_IBM_GENERIC,
- },
- {
- .vendor = PCI_VENDOR_ID_LENOVO,
- .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
- .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
- },
};
-#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
-#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0])
+#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
+#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
+#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
int res, i;
int status;
@@ -3239,7 +3202,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
bool tabletsw_state = false;
unsigned long quirks;
- unsigned long keymap_id;
vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"initializing hotkey subdriver\n");
@@ -3380,6 +3342,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit;
/* Set up key map */
+
hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
GFP_KERNEL);
if (!hotkey_keycode_map) {
@@ -3389,14 +3352,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
goto err_exit;
}
- keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
- ARRAY_SIZE(tpacpi_keymap_qtable));
- BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
- dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
- "using keymap number %lu\n", keymap_id);
-
- memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
- TPACPI_HOTKEY_MAP_SIZE);
+ if (tpacpi_is_lenovo()) {
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "using Lenovo default hot key map\n");
+ memcpy(hotkey_keycode_map, &lenovo_keycode_map,
+ TPACPI_HOTKEY_MAP_SIZE);
+ } else {
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "using IBM default hot key map\n");
+ memcpy(hotkey_keycode_map, &ibm_keycode_map,
+ TPACPI_HOTKEY_MAP_SIZE);
+ }
input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
@@ -3503,8 +3469,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
*send_acpi_ev = true;
*ignore_acpi_ev = false;
- /* HKEY event 0x1001 is scancode 0x00 */
- if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
+ if (scancode > 0 && scancode < 0x21) {
scancode--;
if (!(hotkey_source_mask & (1 << scancode))) {
tpacpi_input_send_key_masked(scancode);
@@ -6115,18 +6080,13 @@ static struct backlight_ops ibm_backlight_data = {
/* --------------------------------------------------------------------- */
-/*
- * Call _BCL method of video device. On some ThinkPads this will
- * switch the firmware to the ACPI brightness control mode.
- */
-
static int __init tpacpi_query_bcl_levels(acpi_handle handle)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
int rc;
- if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
+ if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
obj = (union acpi_object *)buffer.pointer;
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
printk(TPACPI_ERR "Unknown _BCL data, "
@@ -6143,22 +6103,55 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
return rc;
}
+static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
+ u32 lvl, void *context, void **rv)
+{
+ char name[ACPI_PATH_SEGMENT_LENGTH];
+ struct acpi_buffer buffer = { sizeof(name), &name };
+
+ if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+ !strncmp("_BCL", name, sizeof(name) - 1)) {
+ BUG_ON(!rv || !*rv);
+ **(int **)rv = tpacpi_query_bcl_levels(handle);
+ return AE_CTRL_TERMINATE;
+ } else {
+ return AE_OK;
+ }
+}
/*
* Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
*/
static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
{
- acpi_handle video_device;
+ int status;
int bcl_levels = 0;
+ void *bcl_ptr = &bcl_levels;
+
+ if (!vid_handle)
+ TPACPI_ACPIHANDLE_INIT(vid);
+
+ if (!vid_handle)
+ return 0;
+
+ /*
+ * Search for a _BCL method, and execute it. This is safe on all
+ * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
+ * BIOS in ACPI backlight control mode. We do NOT have to care
+ * about calling the _BCL method in an enabled video device, any
+ * will do for our purposes.
+ */
- tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
- if (video_device)
- bcl_levels = tpacpi_query_bcl_levels(video_device);
+ status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
+ tpacpi_acpi_walk_find_bcl, NULL, NULL,
+ &bcl_ptr);
- tp_features.bright_acpimode = (bcl_levels > 0);
+ if (ACPI_SUCCESS(status) && bcl_levels > 2) {
+ tp_features.bright_acpimode = 1;
+ return bcl_levels - 2;
+ }
- return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
+ return 0;
}
/*
@@ -6251,6 +6244,28 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (tp_features.bright_unkfw)
return 1;
+ if (tp_features.bright_acpimode) {
+ if (acpi_video_backlight_support()) {
+ if (brightness_enable > 1) {
+ printk(TPACPI_NOTICE
+ "Standard ACPI backlight interface "
+ "available, not loading native one.\n");
+ return 1;
+ } else if (brightness_enable == 1) {
+ printk(TPACPI_NOTICE
+ "Backlight control force enabled, even if standard "
+ "ACPI backlight interface is available\n");
+ }
+ } else {
+ if (brightness_enable > 1) {
+ printk(TPACPI_NOTICE
+ "Standard ACPI backlight interface not "
+ "available, thinkpad_acpi native "
+ "brightness control enabled\n");
+ }
+ }
+ }
+
if (!brightness_enable) {
dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
"brightness support disabled by "
@@ -6258,26 +6273,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
return 1;
}
- if (acpi_video_backlight_support()) {
- if (brightness_enable > 1) {
- printk(TPACPI_INFO
- "Standard ACPI backlight interface "
- "available, not loading native one.\n");
- return 1;
- } else if (brightness_enable == 1) {
- printk(TPACPI_WARN
- "Cannot enable backlight brightness support, "
- "ACPI is already handling it. Refer to the "
- "acpi_backlight kernel parameter\n");
- return 1;
- }
- } else if (tp_features.bright_acpimode && brightness_enable > 1) {
- printk(TPACPI_NOTICE
- "Standard ACPI backlight interface not "
- "available, thinkpad_acpi native "
- "brightness control enabled\n");
- }
-
/*
* Check for module parameter bogosity, note that we
* init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
diff --git a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
index c8dc392edd57..95a895dd4f13 100644
--- a/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/trunk/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -56,7 +56,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h
index 95a26fb1626c..f065204e401b 100644
--- a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -132,7 +132,7 @@ void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha);
int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha);
void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha);
void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha);
-void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha);
+inline void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha);
extern int ql4xextended_error_logging;
extern int ql4xdiscoverywait;
diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nx.c b/trunk/drivers/scsi/qla4xxx/ql4_nx.c
index 5d4a3822382d..e031a734836e 100644
--- a/trunk/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/trunk/drivers/scsi/qla4xxx/ql4_nx.c
@@ -1418,7 +1418,7 @@ static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha)
return QLA_SUCCESS;
}
-void
+inline void
qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
{
uint32_t drv_active;
diff --git a/trunk/drivers/serial/of_serial.c b/trunk/drivers/serial/of_serial.c
index 2af8fd113123..659a695bdad6 100644
--- a/trunk/drivers/serial/of_serial.c
+++ b/trunk/drivers/serial/of_serial.c
@@ -14,10 +14,11 @@
#include
#include
#include
-#include
#include
#include
+#include
+
struct of_serial_info {
int type;
int line;
diff --git a/trunk/drivers/serial/suncore.c b/trunk/drivers/serial/suncore.c
index 6381a0282ee7..544f2e25d0e5 100644
--- a/trunk/drivers/serial/suncore.c
+++ b/trunk/drivers/serial/suncore.c
@@ -55,12 +55,7 @@ EXPORT_SYMBOL(sunserial_unregister_minors);
int sunserial_console_match(struct console *con, struct device_node *dp,
struct uart_driver *drv, int line, bool ignore_line)
{
- if (!con)
- return 0;
-
- drv->cons = con;
-
- if (of_console_device != dp)
+ if (!con || of_console_device != dp)
return 0;
if (!ignore_line) {
@@ -74,10 +69,12 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
return 0;
}
- if (!console_set_on_cmdline) {
- con->index = line;
+ con->index = line;
+ drv->cons = con;
+
+ if (!console_set_on_cmdline)
add_preferred_console(con->name, line, NULL);
- }
+
return 1;
}
EXPORT_SYMBOL(sunserial_console_match);
diff --git a/trunk/drivers/spi/coldfire_qspi.c b/trunk/drivers/spi/coldfire_qspi.c
index 052b3c7fa6a0..59be3efe0636 100644
--- a/trunk/drivers/spi/coldfire_qspi.c
+++ b/trunk/drivers/spi/coldfire_qspi.c
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/drivers/staging/pohmelfs/path_entry.c b/trunk/drivers/staging/pohmelfs/path_entry.c
index 8ec83d2dffb7..cdc4dd50d638 100644
--- a/trunk/drivers/staging/pohmelfs/path_entry.c
+++ b/trunk/drivers/staging/pohmelfs/path_entry.c
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le
return -ENOENT;
}
- spin_lock(¤t->fs->lock);
+ read_lock(¤t->fs->lock);
path.mnt = mntget(current->fs->root.mnt);
- spin_unlock(¤t->fs->lock);
+ read_unlock(¤t->fs->lock);
path.dentry = d;
@@ -91,9 +91,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi)
return -ENOENT;
}
- spin_lock(¤t->fs->lock);
+ read_lock(¤t->fs->lock);
root = dget(current->fs->root.dentry);
- spin_unlock(¤t->fs->lock);
+ read_unlock(¤t->fs->lock);
spin_lock(&dcache_lock);
diff --git a/trunk/drivers/video/amba-clcd.c b/trunk/drivers/video/amba-clcd.c
index 1c2c68356ea7..afe21e6eb544 100644
--- a/trunk/drivers/video/amba-clcd.c
+++ b/trunk/drivers/video/amba-clcd.c
@@ -80,10 +80,7 @@ static void clcdfb_disable(struct clcd_fb *fb)
/*
* Disable CLCD clock source.
*/
- if (fb->clk_enabled) {
- fb->clk_enabled = false;
- clk_disable(fb->clk);
- }
+ clk_disable(fb->clk);
}
static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
@@ -91,10 +88,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
/*
* Enable the CLCD clock source.
*/
- if (!fb->clk_enabled) {
- fb->clk_enabled = true;
- clk_enable(fb->clk);
- }
+ clk_enable(fb->clk);
/*
* Bring up by first enabling..
diff --git a/trunk/drivers/video/matrox/matroxfb_base.h b/trunk/drivers/video/matrox/matroxfb_base.h
index f96a471cb1a8..f3a4e15672d9 100644
--- a/trunk/drivers/video/matrox/matroxfb_base.h
+++ b/trunk/drivers/video/matrox/matroxfb_base.h
@@ -151,13 +151,13 @@ static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) {
#if defined(__alpha__) || defined(__i386__) || defined(__x86_64__)
/*
- * iowrite32_rep works for us if:
+ * memcpy_toio works for us if:
* (1) Copies data as 32bit quantities, not byte after byte,
* (2) Performs LE ordered stores, and
* (3) It copes with unaligned source (destination is guaranteed to be page
* aligned and length is guaranteed to be multiple of 4).
*/
- iowrite32_rep(va.vaddr, src, len >> 2);
+ memcpy_toio(va.vaddr, src, len);
#else
u_int32_t __iomem* addr = va.vaddr;
diff --git a/trunk/fs/binfmt_misc.c b/trunk/fs/binfmt_misc.c
index a7528b913936..9e60fd201716 100644
--- a/trunk/fs/binfmt_misc.c
+++ b/trunk/fs/binfmt_misc.c
@@ -108,7 +108,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
Node *fmt;
struct file * interp_file = NULL;
char iname[BINPRM_BUF_SIZE];
- const char *iname_addr = iname;
+ char *iname_addr = iname;
int retval;
int fd_binary = -1;
diff --git a/trunk/fs/binfmt_script.c b/trunk/fs/binfmt_script.c
index 396a9884591f..aca9d55afb22 100644
--- a/trunk/fs/binfmt_script.c
+++ b/trunk/fs/binfmt_script.c
@@ -16,8 +16,7 @@
static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
{
- const char *i_arg, *i_name;
- char *cp;
+ char *cp, *i_name, *i_arg;
struct file *file;
char interp[BINPRM_BUF_SIZE];
int retval;
diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c
index 3e7dca279d1c..50efa339e051 100644
--- a/trunk/fs/buffer.c
+++ b/trunk/fs/buffer.c
@@ -770,12 +770,11 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
spin_unlock(lock);
/*
* Ensure any pending I/O completes so that
- * write_dirty_buffer() actually writes the
- * current contents - it is a noop if I/O is
- * still in flight on potentially older
- * contents.
+ * ll_rw_block() actually writes the current
+ * contents - it is a noop if I/O is still in
+ * flight on potentially older contents.
*/
- write_dirty_buffer(bh, WRITE_SYNC_PLUG);
+ ll_rw_block(SWRITE_SYNC_PLUG, 1, &bh);
/*
* Kick off IO for the previous mapping. Note
@@ -2912,6 +2911,13 @@ int submit_bh(int rw, struct buffer_head * bh)
BUG_ON(buffer_delay(bh));
BUG_ON(buffer_unwritten(bh));
+ /*
+ * Mask in barrier bit for a write (could be either a WRITE or a
+ * WRITE_SYNC
+ */
+ if (buffer_ordered(bh) && (rw & WRITE))
+ rw |= WRITE_BARRIER;
+
/*
* Only clear out a write error when rewriting
*/
@@ -2950,21 +2956,22 @@ EXPORT_SYMBOL(submit_bh);
/**
* ll_rw_block: low-level access to block devices (DEPRECATED)
- * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
+ * @rw: whether to %READ or %WRITE or %SWRITE or maybe %READA (readahead)
* @nr: number of &struct buffer_heads in the array
* @bhs: array of pointers to &struct buffer_head
*
* ll_rw_block() takes an array of pointers to &struct buffer_heads, and
* requests an I/O operation on them, either a %READ or a %WRITE. The third
- * %READA option is described in the documentation for generic_make_request()
- * which ll_rw_block() calls.
+ * %SWRITE is like %WRITE only we make sure that the *current* data in buffers
+ * are sent to disk. The fourth %READA option is described in the documentation
+ * for generic_make_request() which ll_rw_block() calls.
*
* This function drops any buffer that it cannot get a lock on (with the
- * BH_Lock state bit), any buffer that appears to be clean when doing a write
- * request, and any buffer that appears to be up-to-date when doing read
- * request. Further it marks as clean buffers that are processed for
- * writing (the buffer cache won't assume that they are actually clean
- * until the buffer gets unlocked).
+ * BH_Lock state bit) unless SWRITE is required, any buffer that appears to be
+ * clean when doing a write request, and any buffer that appears to be
+ * up-to-date when doing read request. Further it marks as clean buffers that
+ * are processed for writing (the buffer cache won't assume that they are
+ * actually clean until the buffer gets unlocked).
*
* ll_rw_block sets b_end_io to simple completion handler that marks
* the buffer up-to-date (if approriate), unlocks the buffer and wakes
@@ -2980,13 +2987,20 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
for (i = 0; i < nr; i++) {
struct buffer_head *bh = bhs[i];
- if (!trylock_buffer(bh))
+ if (rw == SWRITE || rw == SWRITE_SYNC || rw == SWRITE_SYNC_PLUG)
+ lock_buffer(bh);
+ else if (!trylock_buffer(bh))
continue;
- if (rw == WRITE) {
+
+ if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC ||
+ rw == SWRITE_SYNC_PLUG) {
if (test_clear_buffer_dirty(bh)) {
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
- submit_bh(WRITE, bh);
+ if (rw == SWRITE_SYNC)
+ submit_bh(WRITE_SYNC, bh);
+ else
+ submit_bh(WRITE, bh);
continue;
}
} else {
@@ -3002,25 +3016,12 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
}
EXPORT_SYMBOL(ll_rw_block);
-void write_dirty_buffer(struct buffer_head *bh, int rw)
-{
- lock_buffer(bh);
- if (!test_clear_buffer_dirty(bh)) {
- unlock_buffer(bh);
- return;
- }
- bh->b_end_io = end_buffer_write_sync;
- get_bh(bh);
- submit_bh(rw, bh);
-}
-EXPORT_SYMBOL(write_dirty_buffer);
-
/*
* For a data-integrity writeout, we need to wait upon any in-progress I/O
* and then start new I/O and then wait upon it. The caller must have a ref on
* the buffer_head.
*/
-int __sync_dirty_buffer(struct buffer_head *bh, int rw)
+int sync_dirty_buffer(struct buffer_head *bh)
{
int ret = 0;
@@ -3029,7 +3030,7 @@ int __sync_dirty_buffer(struct buffer_head *bh, int rw)
if (test_clear_buffer_dirty(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_write_sync;
- ret = submit_bh(rw, bh);
+ ret = submit_bh(WRITE_SYNC, bh);
wait_on_buffer(bh);
if (buffer_eopnotsupp(bh)) {
clear_buffer_eopnotsupp(bh);
@@ -3042,12 +3043,6 @@ int __sync_dirty_buffer(struct buffer_head *bh, int rw)
}
return ret;
}
-EXPORT_SYMBOL(__sync_dirty_buffer);
-
-int sync_dirty_buffer(struct buffer_head *bh)
-{
- return __sync_dirty_buffer(bh, WRITE_SYNC);
-}
EXPORT_SYMBOL(sync_dirty_buffer);
/*
diff --git a/trunk/fs/cramfs/inode.c b/trunk/fs/cramfs/inode.c
index 1e7a33028d33..a53b130b366c 100644
--- a/trunk/fs/cramfs/inode.c
+++ b/trunk/fs/cramfs/inode.c
@@ -80,7 +80,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb,
}
} else {
inode = iget_locked(sb, CRAMINO(cramfs_inode));
- if (inode && (inode->i_state & I_NEW)) {
+ if (inode) {
setup_inode(inode, cramfs_inode);
unlock_new_inode(inode);
}
diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c
index 83293be48149..4d13bf50b7b1 100644
--- a/trunk/fs/dcache.c
+++ b/trunk/fs/dcache.c
@@ -1332,13 +1332,31 @@ EXPORT_SYMBOL(d_add_ci);
* d_lookup - search for a dentry
* @parent: parent dentry
* @name: qstr of name we wish to find
- * Returns: dentry, or NULL
*
- * d_lookup searches the children of the parent dentry for the name in
- * question. If the dentry is found its reference count is incremented and the
- * dentry is returned. The caller must use dput to free the entry when it has
- * finished using it. %NULL is returned if the dentry does not exist.
+ * Searches the children of the parent dentry for the name in question. If
+ * the dentry is found its reference count is incremented and the dentry
+ * is returned. The caller must use dput to free the entry when it has
+ * finished using it. %NULL is returned on failure.
+ *
+ * __d_lookup is dcache_lock free. The hash list is protected using RCU.
+ * Memory barriers are used while updating and doing lockless traversal.
+ * To avoid races with d_move while rename is happening, d_lock is used.
+ *
+ * Overflows in memcmp(), while d_move, are avoided by keeping the length
+ * and name pointer in one structure pointed by d_qstr.
+ *
+ * rcu_read_lock() and rcu_read_unlock() are used to disable preemption while
+ * lookup is going on.
+ *
+ * The dentry unused LRU is not updated even if lookup finds the required dentry
+ * in there. It is updated in places such as prune_dcache, shrink_dcache_sb,
+ * select_parent and __dget_locked. This laziness saves lookup from dcache_lock
+ * acquisition.
+ *
+ * d_lookup() is protected against the concurrent renames in some unrelated
+ * directory using the seqlockt_t rename_lock.
*/
+
struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
{
struct dentry * dentry = NULL;
@@ -1354,21 +1372,6 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
}
EXPORT_SYMBOL(d_lookup);
-/*
- * __d_lookup - search for a dentry (racy)
- * @parent: parent dentry
- * @name: qstr of name we wish to find
- * Returns: dentry, or NULL
- *
- * __d_lookup is like d_lookup, however it may (rarely) return a
- * false-negative result due to unrelated rename activity.
- *
- * __d_lookup is slightly faster by avoiding rename_lock read seqlock,
- * however it must be used carefully, eg. with a following d_lookup in
- * the case of failure.
- *
- * __d_lookup callers must be commented.
- */
struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
{
unsigned int len = name->len;
@@ -1379,19 +1382,6 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
struct hlist_node *node;
struct dentry *dentry;
- /*
- * The hash list is protected using RCU.
- *
- * Take d_lock when comparing a candidate dentry, to avoid races
- * with d_move().
- *
- * It is possible that concurrent renames can mess up our list
- * walk here and result in missing our dentry, resulting in the
- * false-negative result. d_lookup() protects against concurrent
- * renames using rename_lock seqlock.
- *
- * See Documentation/vfs/dcache-locking.txt for more details.
- */
rcu_read_lock();
hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
@@ -1406,8 +1396,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
/*
* Recheck the dentry after taking the lock - d_move may have
- * changed things. Don't bother checking the hash because
- * we're about to compare the whole name anyway.
+ * changed things. Don't bother checking the hash because we're
+ * about to compare the whole name anyway.
*/
if (dentry->d_parent != parent)
goto next;
@@ -1935,7 +1925,7 @@ static int prepend_path(const struct path *path, struct path *root,
bool slash = false;
int error = 0;
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
while (dentry != root->dentry || vfsmnt != root->mnt) {
struct dentry * parent;
@@ -1964,7 +1954,7 @@ static int prepend_path(const struct path *path, struct path *root,
if (!error && !slash)
error = prepend(buffer, buflen, "/", 1);
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return error;
global_root:
@@ -2302,12 +2292,11 @@ int path_is_under(struct path *path1, struct path *path2)
struct vfsmount *mnt = path1->mnt;
struct dentry *dentry = path1->dentry;
int res;
-
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (mnt != path2->mnt) {
for (;;) {
if (mnt->mnt_parent == mnt) {
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return 0;
}
if (mnt->mnt_parent == path2->mnt)
@@ -2317,7 +2306,7 @@ int path_is_under(struct path *path1, struct path *path2)
dentry = mnt->mnt_mountpoint;
}
res = is_subdir(dentry, path2->dentry);
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return res;
}
EXPORT_SYMBOL(path_is_under);
diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c
index 2d9455282744..7761837e4500 100644
--- a/trunk/fs/exec.c
+++ b/trunk/fs/exec.c
@@ -361,13 +361,13 @@ int bprm_mm_init(struct linux_binprm *bprm)
/*
* count() counts the number of strings in array ARGV.
*/
-static int count(const char __user * const __user * argv, int max)
+static int count(char __user * __user * argv, int max)
{
int i = 0;
if (argv != NULL) {
for (;;) {
- const char __user * p;
+ char __user * p;
if (get_user(p, argv))
return -EFAULT;
@@ -387,7 +387,7 @@ static int count(const char __user * const __user * argv, int max)
* processes's memory to the new process's stack. The call to get_user_pages()
* ensures the destination page is created and not swapped out.
*/
-static int copy_strings(int argc, const char __user *const __user *argv,
+static int copy_strings(int argc, char __user * __user * argv,
struct linux_binprm *bprm)
{
struct page *kmapped_page = NULL;
@@ -396,7 +396,7 @@ static int copy_strings(int argc, const char __user *const __user *argv,
int ret;
while (argc-- > 0) {
- const char __user *str;
+ char __user *str;
int len;
unsigned long pos;
@@ -470,13 +470,12 @@ static int copy_strings(int argc, const char __user *const __user *argv,
/*
* Like copy_strings, but get argv and its values from kernel memory.
*/
-int copy_strings_kernel(int argc, const char *const *argv,
- struct linux_binprm *bprm)
+int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm)
{
int r;
mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
- r = copy_strings(argc, (const char __user *const __user *)argv, bprm);
+ r = copy_strings(argc, (char __user * __user *)argv, bprm);
set_fs(oldfs);
return r;
}
@@ -998,7 +997,7 @@ EXPORT_SYMBOL(flush_old_exec);
void setup_new_exec(struct linux_binprm * bprm)
{
int i, ch;
- const char *name;
+ char * name;
char tcomm[sizeof(current->comm)];
arch_pick_mmap_layout(current->mm);
@@ -1118,7 +1117,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
bprm->unsafe = tracehook_unsafe_exec(p);
n_fs = 1;
- spin_lock(&p->fs->lock);
+ write_lock(&p->fs->lock);
rcu_read_lock();
for (t = next_thread(p); t != p; t = next_thread(t)) {
if (t->fs == p->fs)
@@ -1135,7 +1134,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
res = 1;
}
}
- spin_unlock(&p->fs->lock);
+ write_unlock(&p->fs->lock);
return res;
}
@@ -1317,9 +1316,9 @@ EXPORT_SYMBOL(search_binary_handler);
/*
* sys_execve() executes a new program.
*/
-int do_execve(const char * filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
+int do_execve(char * filename,
+ char __user *__user *argv,
+ char __user *__user *envp,
struct pt_regs * regs)
{
struct linux_binprm *bprm;
diff --git a/trunk/fs/fat/misc.c b/trunk/fs/fat/misc.c
index 1736f2356388..1fa23f6ffba5 100644
--- a/trunk/fs/fat/misc.c
+++ b/trunk/fs/fat/misc.c
@@ -250,9 +250,7 @@ int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
{
int i, err = 0;
- for (i = 0; i < nr_bhs; i++)
- write_dirty_buffer(bhs[i], WRITE);
-
+ ll_rw_block(SWRITE, nr_bhs, bhs);
for (i = 0; i < nr_bhs; i++) {
wait_on_buffer(bhs[i]);
if (buffer_eopnotsupp(bhs[i])) {
diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c
index a04bdd81c11c..edecd36fed9b 100644
--- a/trunk/fs/file_table.c
+++ b/trunk/fs/file_table.c
@@ -20,9 +20,7 @@
#include
#include
#include
-#include
#include
-#include
#include
#include
@@ -34,8 +32,8 @@ struct files_stat_struct files_stat = {
.max_files = NR_FILE
};
-DECLARE_LGLOCK(files_lglock);
-DEFINE_LGLOCK(files_lglock);
+/* public. Not pretty! */
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock);
/* SLAB cache for file structures */
static struct kmem_cache *filp_cachep __read_mostly;
@@ -251,7 +249,7 @@ static void __fput(struct file *file)
cdev_put(inode->i_cdev);
fops_put(file->f_op);
put_pid(file->f_owner.pid);
- file_sb_list_del(file);
+ file_kill(file);
if (file->f_mode & FMODE_WRITE)
drop_file_write_access(file);
file->f_path.dentry = NULL;
@@ -330,107 +328,41 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
return file;
}
+
void put_filp(struct file *file)
{
if (atomic_long_dec_and_test(&file->f_count)) {
security_file_free(file);
- file_sb_list_del(file);
+ file_kill(file);
file_free(file);
}
}
-static inline int file_list_cpu(struct file *file)
-{
-#ifdef CONFIG_SMP
- return file->f_sb_list_cpu;
-#else
- return smp_processor_id();
-#endif
-}
-
-/* helper for file_sb_list_add to reduce ifdefs */
-static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
-{
- struct list_head *list;
-#ifdef CONFIG_SMP
- int cpu;
- cpu = smp_processor_id();
- file->f_sb_list_cpu = cpu;
- list = per_cpu_ptr(sb->s_files, cpu);
-#else
- list = &sb->s_files;
-#endif
- list_add(&file->f_u.fu_list, list);
-}
-
-/**
- * file_sb_list_add - add a file to the sb's file list
- * @file: file to add
- * @sb: sb to add it to
- *
- * Use this function to associate a file with the superblock of the inode it
- * refers to.
- */
-void file_sb_list_add(struct file *file, struct super_block *sb)
+void file_move(struct file *file, struct list_head *list)
{
- lg_local_lock(files_lglock);
- __file_sb_list_add(file, sb);
- lg_local_unlock(files_lglock);
+ if (!list)
+ return;
+ file_list_lock();
+ list_move(&file->f_u.fu_list, list);
+ file_list_unlock();
}
-/**
- * file_sb_list_del - remove a file from the sb's file list
- * @file: file to remove
- * @sb: sb to remove it from
- *
- * Use this function to remove a file from its superblock.
- */
-void file_sb_list_del(struct file *file)
+void file_kill(struct file *file)
{
if (!list_empty(&file->f_u.fu_list)) {
- lg_local_lock_cpu(files_lglock, file_list_cpu(file));
+ file_list_lock();
list_del_init(&file->f_u.fu_list);
- lg_local_unlock_cpu(files_lglock, file_list_cpu(file));
+ file_list_unlock();
}
}
-#ifdef CONFIG_SMP
-
-/*
- * These macros iterate all files on all CPUs for a given superblock.
- * files_lglock must be held globally.
- */
-#define do_file_list_for_each_entry(__sb, __file) \
-{ \
- int i; \
- for_each_possible_cpu(i) { \
- struct list_head *list; \
- list = per_cpu_ptr((__sb)->s_files, i); \
- list_for_each_entry((__file), list, f_u.fu_list)
-
-#define while_file_list_for_each_entry \
- } \
-}
-
-#else
-
-#define do_file_list_for_each_entry(__sb, __file) \
-{ \
- struct list_head *list; \
- list = &(sb)->s_files; \
- list_for_each_entry((__file), list, f_u.fu_list)
-
-#define while_file_list_for_each_entry \
-}
-
-#endif
-
int fs_may_remount_ro(struct super_block *sb)
{
struct file *file;
+
/* Check that no files are currently opened for writing. */
- lg_global_lock(files_lglock);
- do_file_list_for_each_entry(sb, file) {
+ file_list_lock();
+ list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
struct inode *inode = file->f_path.dentry->d_inode;
/* File with pending delete? */
@@ -440,11 +372,11 @@ int fs_may_remount_ro(struct super_block *sb)
/* Writeable file? */
if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
goto too_bad;
- } while_file_list_for_each_entry;
- lg_global_unlock(files_lglock);
+ }
+ file_list_unlock();
return 1; /* Tis' cool bro. */
too_bad:
- lg_global_unlock(files_lglock);
+ file_list_unlock();
return 0;
}
@@ -460,8 +392,8 @@ void mark_files_ro(struct super_block *sb)
struct file *f;
retry:
- lg_global_lock(files_lglock);
- do_file_list_for_each_entry(sb, f) {
+ file_list_lock();
+ list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
struct vfsmount *mnt;
if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
continue;
@@ -476,13 +408,16 @@ void mark_files_ro(struct super_block *sb)
continue;
file_release_write(f);
mnt = mntget(f->f_path.mnt);
- /* This can sleep, so we can't hold the spinlock. */
- lg_global_unlock(files_lglock);
+ file_list_unlock();
+ /*
+ * This can sleep, so we can't hold
+ * the file_list_lock() spinlock.
+ */
mnt_drop_write(mnt);
mntput(mnt);
goto retry;
- } while_file_list_for_each_entry;
- lg_global_unlock(files_lglock);
+ }
+ file_list_unlock();
}
void __init files_init(unsigned long mempages)
@@ -502,6 +437,5 @@ void __init files_init(unsigned long mempages)
if (files_stat.max_files < NR_FILE)
files_stat.max_files = NR_FILE;
files_defer_init();
- lg_lock_init(files_lglock);
percpu_counter_init(&nr_files, 0);
}
diff --git a/trunk/fs/fs_struct.c b/trunk/fs/fs_struct.c
index ed45a9cf5f3d..1ee40eb9a2c0 100644
--- a/trunk/fs/fs_struct.c
+++ b/trunk/fs/fs_struct.c
@@ -13,11 +13,11 @@ void set_fs_root(struct fs_struct *fs, struct path *path)
{
struct path old_root;
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
old_root = fs->root;
fs->root = *path;
path_get(path);
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
if (old_root.dentry)
path_put(&old_root);
}
@@ -30,11 +30,11 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
{
struct path old_pwd;
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
old_pwd = fs->pwd;
fs->pwd = *path;
path_get(path);
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
if (old_pwd.dentry)
path_put(&old_pwd);
@@ -51,7 +51,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
task_lock(p);
fs = p->fs;
if (fs) {
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
if (fs->root.dentry == old_root->dentry
&& fs->root.mnt == old_root->mnt) {
path_get(new_root);
@@ -64,7 +64,7 @@ void chroot_fs_refs(struct path *old_root, struct path *new_root)
fs->pwd = *new_root;
count++;
}
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
}
task_unlock(p);
} while_each_thread(g, p);
@@ -87,10 +87,10 @@ void exit_fs(struct task_struct *tsk)
if (fs) {
int kill;
task_lock(tsk);
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
tsk->fs = NULL;
kill = !--fs->users;
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
task_unlock(tsk);
if (kill)
free_fs_struct(fs);
@@ -104,7 +104,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
if (fs) {
fs->users = 1;
fs->in_exec = 0;
- spin_lock_init(&fs->lock);
+ rwlock_init(&fs->lock);
fs->umask = old->umask;
get_fs_root_and_pwd(old, &fs->root, &fs->pwd);
}
@@ -121,10 +121,10 @@ int unshare_fs_struct(void)
return -ENOMEM;
task_lock(current);
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
kill = !--fs->users;
current->fs = new_fs;
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
task_unlock(current);
if (kill)
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(current_umask);
/* to be mentioned only in INIT_TASK */
struct fs_struct init_fs = {
.users = 1,
- .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
+ .lock = __RW_LOCK_UNLOCKED(init_fs.lock),
.umask = 0022,
};
@@ -156,14 +156,14 @@ void daemonize_fs_struct(void)
task_lock(current);
- spin_lock(&init_fs.lock);
+ write_lock(&init_fs.lock);
init_fs.users++;
- spin_unlock(&init_fs.lock);
+ write_unlock(&init_fs.lock);
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
current->fs = &init_fs;
kill = !--fs->users;
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
task_unlock(current);
if (kill)
diff --git a/trunk/fs/generic_acl.c b/trunk/fs/generic_acl.c
index 6bc9e3a5a693..99800e564157 100644
--- a/trunk/fs/generic_acl.c
+++ b/trunk/fs/generic_acl.c
@@ -94,7 +94,6 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
if (error < 0)
goto failed;
inode->i_mode = mode;
- inode->i_ctime = CURRENT_TIME;
if (error == 0) {
posix_acl_release(acl);
acl = NULL;
diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c
index f7dc9b5f9ef8..dd1e55535a4e 100644
--- a/trunk/fs/hostfs/hostfs_kern.c
+++ b/trunk/fs/hostfs/hostfs_kern.c
@@ -104,7 +104,7 @@ static char *__dentry_name(struct dentry *dentry, char *name)
__putname(name);
return NULL;
}
- strlcpy(name, root, PATH_MAX);
+ strncpy(name, root, PATH_MAX);
if (len > p - name) {
__putname(name);
return NULL;
@@ -876,7 +876,7 @@ static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
char *path = dentry_name(dentry);
int err = -ENOMEM;
if (path) {
- err = hostfs_do_readlink(path, link, PATH_MAX);
+ int err = hostfs_do_readlink(path, link, PATH_MAX);
if (err == PATH_MAX)
err = -E2BIG;
__putname(path);
diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h
index a6910e91cee8..6b706bc60a66 100644
--- a/trunk/fs/internal.h
+++ b/trunk/fs/internal.h
@@ -9,8 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include
-
struct super_block;
struct linux_binprm;
struct path;
@@ -72,8 +70,7 @@ extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
extern void __init mnt_init(void);
-DECLARE_BRLOCK(vfsmount_lock);
-
+extern spinlock_t vfsmount_lock;
/*
* fs_struct.c
@@ -83,8 +80,6 @@ extern void chroot_fs_refs(struct path *, struct path *);
/*
* file_table.c
*/
-extern void file_sb_list_add(struct file *f, struct super_block *sb);
-extern void file_sb_list_del(struct file *f);
extern void mark_files_ro(struct super_block *);
extern struct file *get_empty_filp(void);
diff --git a/trunk/fs/jbd/checkpoint.c b/trunk/fs/jbd/checkpoint.c
index 05a38b9c4c0e..b0435dd0654d 100644
--- a/trunk/fs/jbd/checkpoint.c
+++ b/trunk/fs/jbd/checkpoint.c
@@ -254,9 +254,7 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
{
int i;
- for (i = 0; i < *batch_count; i++)
- write_dirty_buffer(bhs[i], WRITE);
-
+ ll_rw_block(SWRITE, *batch_count, bhs);
for (i = 0; i < *batch_count; i++) {
struct buffer_head *bh = bhs[i];
clear_buffer_jwrite(bh);
diff --git a/trunk/fs/jbd/commit.c b/trunk/fs/jbd/commit.c
index 95d8c11c929e..28a9ddaa0c49 100644
--- a/trunk/fs/jbd/commit.c
+++ b/trunk/fs/jbd/commit.c
@@ -119,6 +119,7 @@ static int journal_write_commit_record(journal_t *journal,
struct buffer_head *bh;
journal_header_t *header;
int ret;
+ int barrier_done = 0;
if (is_journal_aborted(journal))
return 0;
@@ -136,36 +137,34 @@ static int journal_write_commit_record(journal_t *journal,
JBUFFER_TRACE(descriptor, "write commit block");
set_buffer_dirty(bh);
-
if (journal->j_flags & JFS_BARRIER) {
- ret = __sync_dirty_buffer(bh, WRITE_SYNC | WRITE_BARRIER);
-
- /*
- * Is it possible for another commit to fail at roughly
- * the same time as this one? If so, we don't want to
- * trust the barrier flag in the super, but instead want
- * to remember if we sent a barrier request
- */
- if (ret == -EOPNOTSUPP) {
- char b[BDEVNAME_SIZE];
+ set_buffer_ordered(bh);
+ barrier_done = 1;
+ }
+ ret = sync_dirty_buffer(bh);
+ if (barrier_done)
+ clear_buffer_ordered(bh);
+ /* is it possible for another commit to fail at roughly
+ * the same time as this one? If so, we don't want to
+ * trust the barrier flag in the super, but instead want
+ * to remember if we sent a barrier request
+ */
+ if (ret == -EOPNOTSUPP && barrier_done) {
+ char b[BDEVNAME_SIZE];
- printk(KERN_WARNING
- "JBD: barrier-based sync failed on %s - "
- "disabling barriers\n",
- bdevname(journal->j_dev, b));
- spin_lock(&journal->j_state_lock);
- journal->j_flags &= ~JFS_BARRIER;
- spin_unlock(&journal->j_state_lock);
+ printk(KERN_WARNING
+ "JBD: barrier-based sync failed on %s - "
+ "disabling barriers\n",
+ bdevname(journal->j_dev, b));
+ spin_lock(&journal->j_state_lock);
+ journal->j_flags &= ~JFS_BARRIER;
+ spin_unlock(&journal->j_state_lock);
- /* And try again, without the barrier */
- set_buffer_uptodate(bh);
- set_buffer_dirty(bh);
- ret = sync_dirty_buffer(bh);
- }
- } else {
+ /* And try again, without the barrier */
+ set_buffer_uptodate(bh);
+ set_buffer_dirty(bh);
ret = sync_dirty_buffer(bh);
}
-
put_bh(bh); /* One for getblk() */
journal_put_journal_head(descriptor);
diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c
index 2c4b1f109da9..f19ce94693d8 100644
--- a/trunk/fs/jbd/journal.c
+++ b/trunk/fs/jbd/journal.c
@@ -1024,7 +1024,7 @@ void journal_update_superblock(journal_t *journal, int wait)
if (wait)
sync_dirty_buffer(bh);
else
- write_dirty_buffer(bh, WRITE);
+ ll_rw_block(SWRITE, 1, &bh);
out:
/* If we have just flushed the log (by marking s_start==0), then
diff --git a/trunk/fs/jbd/revoke.c b/trunk/fs/jbd/revoke.c
index d29018307e2e..ad717328343a 100644
--- a/trunk/fs/jbd/revoke.c
+++ b/trunk/fs/jbd/revoke.c
@@ -617,7 +617,7 @@ static void flush_descriptor(journal_t *journal,
set_buffer_jwrite(bh);
BUFFER_TRACE(bh, "write");
set_buffer_dirty(bh);
- write_dirty_buffer(bh, write_op);
+ ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh);
}
#endif
diff --git a/trunk/fs/jbd2/checkpoint.c b/trunk/fs/jbd2/checkpoint.c
index 5247e7ffdcb4..1c23a0f4e8a3 100644
--- a/trunk/fs/jbd2/checkpoint.c
+++ b/trunk/fs/jbd2/checkpoint.c
@@ -255,9 +255,7 @@ __flush_batch(journal_t *journal, int *batch_count)
{
int i;
- for (i = 0; i < *batch_count; i++)
- write_dirty_buffer(journal->j_chkpt_bhs[i], WRITE);
-
+ ll_rw_block(SWRITE, *batch_count, journal->j_chkpt_bhs);
for (i = 0; i < *batch_count; i++) {
struct buffer_head *bh = journal->j_chkpt_bhs[i];
clear_buffer_jwrite(bh);
diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c
index 7c068c189d80..f52e5e8049f1 100644
--- a/trunk/fs/jbd2/commit.c
+++ b/trunk/fs/jbd2/commit.c
@@ -101,6 +101,7 @@ static int journal_submit_commit_record(journal_t *journal,
struct commit_header *tmp;
struct buffer_head *bh;
int ret;
+ int barrier_done = 0;
struct timespec now = current_kernel_time();
if (is_journal_aborted(journal))
@@ -135,22 +136,30 @@ static int journal_submit_commit_record(journal_t *journal,
if (journal->j_flags & JBD2_BARRIER &&
!JBD2_HAS_INCOMPAT_FEATURE(journal,
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
- ret = submit_bh(WRITE_SYNC_PLUG | WRITE_BARRIER, bh);
- if (ret == -EOPNOTSUPP) {
- printk(KERN_WARNING
- "JBD2: Disabling barriers on %s, "
- "not supported by device\n", journal->j_devname);
- write_lock(&journal->j_state_lock);
- journal->j_flags &= ~JBD2_BARRIER;
- write_unlock(&journal->j_state_lock);
+ set_buffer_ordered(bh);
+ barrier_done = 1;
+ }
+ ret = submit_bh(WRITE_SYNC_PLUG, bh);
+ if (barrier_done)
+ clear_buffer_ordered(bh);
+
+ /* is it possible for another commit to fail at roughly
+ * the same time as this one? If so, we don't want to
+ * trust the barrier flag in the super, but instead want
+ * to remember if we sent a barrier request
+ */
+ if (ret == -EOPNOTSUPP && barrier_done) {
+ printk(KERN_WARNING
+ "JBD2: Disabling barriers on %s, "
+ "not supported by device\n", journal->j_devname);
+ write_lock(&journal->j_state_lock);
+ journal->j_flags &= ~JBD2_BARRIER;
+ write_unlock(&journal->j_state_lock);
- /* And try again, without the barrier */
- lock_buffer(bh);
- set_buffer_uptodate(bh);
- clear_buffer_dirty(bh);
- ret = submit_bh(WRITE_SYNC_PLUG, bh);
- }
- } else {
+ /* And try again, without the barrier */
+ lock_buffer(bh);
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
ret = submit_bh(WRITE_SYNC_PLUG, bh);
}
*cbh = bh;
diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c
index 0e8014ea6b94..ad5866aaf0f9 100644
--- a/trunk/fs/jbd2/journal.c
+++ b/trunk/fs/jbd2/journal.c
@@ -1124,7 +1124,7 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
set_buffer_uptodate(bh);
}
} else
- write_dirty_buffer(bh, WRITE);
+ ll_rw_block(SWRITE, 1, &bh);
out:
/* If we have just flushed the log (by marking s_start==0), then
diff --git a/trunk/fs/jbd2/revoke.c b/trunk/fs/jbd2/revoke.c
index 9ad321fd63fd..a360b06af2e3 100644
--- a/trunk/fs/jbd2/revoke.c
+++ b/trunk/fs/jbd2/revoke.c
@@ -625,7 +625,7 @@ static void flush_descriptor(journal_t *journal,
set_buffer_jwrite(bh);
BUFFER_TRACE(bh, "write");
set_buffer_dirty(bh);
- write_dirty_buffer(bh, write_op);
+ ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh);
}
#endif
diff --git a/trunk/fs/mbcache.c b/trunk/fs/mbcache.c
index 93444747237b..cf4e6cdfd15b 100644
--- a/trunk/fs/mbcache.c
+++ b/trunk/fs/mbcache.c
@@ -80,7 +80,6 @@ struct mb_cache {
struct list_head c_cache_list;
const char *c_name;
atomic_t c_entry_count;
- int c_max_entries;
int c_bucket_bits;
struct kmem_cache *c_entry_cache;
struct list_head *c_block_hash;
@@ -244,12 +243,6 @@ mb_cache_create(const char *name, int bucket_bits)
if (!cache->c_entry_cache)
goto fail2;
- /*
- * Set an upper limit on the number of cache entries so that the hash
- * chains won't grow too long.
- */
- cache->c_max_entries = bucket_count << 4;
-
spin_lock(&mb_cache_spinlock);
list_add(&cache->c_cache_list, &mb_cache_list);
spin_unlock(&mb_cache_spinlock);
@@ -340,6 +333,7 @@ mb_cache_destroy(struct mb_cache *cache)
kfree(cache);
}
+
/*
* mb_cache_entry_alloc()
*
@@ -351,29 +345,17 @@ mb_cache_destroy(struct mb_cache *cache)
struct mb_cache_entry *
mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags)
{
- struct mb_cache_entry *ce = NULL;
-
- if (atomic_read(&cache->c_entry_count) >= cache->c_max_entries) {
- spin_lock(&mb_cache_spinlock);
- if (!list_empty(&mb_cache_lru_list)) {
- ce = list_entry(mb_cache_lru_list.next,
- struct mb_cache_entry, e_lru_list);
- list_del_init(&ce->e_lru_list);
- __mb_cache_entry_unhash(ce);
- }
- spin_unlock(&mb_cache_spinlock);
- }
- if (!ce) {
- ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
- if (!ce)
- return NULL;
+ struct mb_cache_entry *ce;
+
+ ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
+ if (ce) {
atomic_inc(&cache->c_entry_count);
INIT_LIST_HEAD(&ce->e_lru_list);
INIT_LIST_HEAD(&ce->e_block_list);
ce->e_cache = cache;
+ ce->e_used = 1 + MB_CACHE_WRITER;
ce->e_queued = 0;
}
- ce->e_used = 1 + MB_CACHE_WRITER;
return ce;
}
diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c
index 24896e833565..17ea76bf2fbe 100644
--- a/trunk/fs/namei.c
+++ b/trunk/fs/namei.c
@@ -595,16 +595,15 @@ int follow_up(struct path *path)
{
struct vfsmount *parent;
struct dentry *mountpoint;
-
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
parent = path->mnt->mnt_parent;
if (parent == path->mnt) {
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return 0;
}
mntget(parent);
mountpoint = dget(path->mnt->mnt_mountpoint);
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
dput(path->dentry);
path->dentry = mountpoint;
mntput(path->mnt);
@@ -686,35 +685,6 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
follow_mount(&nd->path);
}
-/*
- * Allocate a dentry with name and parent, and perform a parent
- * directory ->lookup on it. Returns the new dentry, or ERR_PTR
- * on error. parent->d_inode->i_mutex must be held. d_lookup must
- * have verified that no child exists while under i_mutex.
- */
-static struct dentry *d_alloc_and_lookup(struct dentry *parent,
- struct qstr *name, struct nameidata *nd)
-{
- struct inode *inode = parent->d_inode;
- struct dentry *dentry;
- struct dentry *old;
-
- /* Don't create child dentry for a dead directory. */
- if (unlikely(IS_DEADDIR(inode)))
- return ERR_PTR(-ENOENT);
-
- dentry = d_alloc(parent, name);
- if (unlikely(!dentry))
- return ERR_PTR(-ENOMEM);
-
- old = inode->i_op->lookup(inode, dentry, nd);
- if (unlikely(old)) {
- dput(dentry);
- dentry = old;
- }
- return dentry;
-}
-
/*
* It's more convoluted than I'd like it to be, but... it's still fairly
* small and for now I'd prefer to have fast path as straight as possible.
@@ -736,15 +706,9 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
return err;
}
- /*
- * Rename seqlock is not required here because in the off chance
- * of a false negative due to a concurrent rename, we're going to
- * do the non-racy lookup, below.
- */
dentry = __d_lookup(nd->path.dentry, name);
if (!dentry)
goto need_lookup;
-found:
if (dentry->d_op && dentry->d_op->d_revalidate)
goto need_revalidate;
done:
@@ -760,28 +724,56 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
mutex_lock(&dir->i_mutex);
/*
* First re-do the cached lookup just in case it was created
- * while we waited for the directory semaphore, or the first
- * lookup failed due to an unrelated rename.
+ * while we waited for the directory semaphore..
*
- * This could use version numbering or similar to avoid unnecessary
- * cache lookups, but then we'd have to do the first lookup in the
- * non-racy way. However in the common case here, everything should
- * be hot in cache, so would it be a big win?
+ * FIXME! This could use version numbering or similar to
+ * avoid unnecessary cache lookups.
+ *
+ * The "dcache_lock" is purely to protect the RCU list walker
+ * from concurrent renames at this point (we mustn't get false
+ * negatives from the RCU list walk here, unlike the optimistic
+ * fast walk).
+ *
+ * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup
*/
dentry = d_lookup(parent, name);
- if (likely(!dentry)) {
- dentry = d_alloc_and_lookup(parent, name, nd);
+ if (!dentry) {
+ struct dentry *new;
+
+ /* Don't create child dentry for a dead directory. */
+ dentry = ERR_PTR(-ENOENT);
+ if (IS_DEADDIR(dir))
+ goto out_unlock;
+
+ new = d_alloc(parent, name);
+ dentry = ERR_PTR(-ENOMEM);
+ if (new) {
+ dentry = dir->i_op->lookup(dir, new, nd);
+ if (dentry)
+ dput(new);
+ else
+ dentry = new;
+ }
+out_unlock:
mutex_unlock(&dir->i_mutex);
if (IS_ERR(dentry))
goto fail;
goto done;
}
+
/*
* Uhhuh! Nasty case: the cache was re-populated while
* we waited on the semaphore. Need to revalidate.
*/
mutex_unlock(&dir->i_mutex);
- goto found;
+ if (dentry->d_op && dentry->d_op->d_revalidate) {
+ dentry = do_revalidate(dentry, nd);
+ if (!dentry)
+ dentry = ERR_PTR(-ENOENT);
+ }
+ if (IS_ERR(dentry))
+ goto fail;
+ goto done;
need_revalidate:
dentry = do_revalidate(dentry, nd);
@@ -1138,18 +1130,35 @@ static struct dentry *__lookup_hash(struct qstr *name,
goto out;
}
- /*
- * Don't bother with __d_lookup: callers are for creat as
- * well as unlink, so a lot of the time it would cost
- * a double lookup.
+ dentry = __d_lookup(base, name);
+
+ /* lockess __d_lookup may fail due to concurrent d_move()
+ * in some unrelated directory, so try with d_lookup
*/
- dentry = d_lookup(base, name);
+ if (!dentry)
+ dentry = d_lookup(base, name);
if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
dentry = do_revalidate(dentry, nd);
- if (!dentry)
- dentry = d_alloc_and_lookup(base, name, nd);
+ if (!dentry) {
+ struct dentry *new;
+
+ /* Don't create child dentry for a dead directory. */
+ dentry = ERR_PTR(-ENOENT);
+ if (IS_DEADDIR(inode))
+ goto out;
+
+ new = d_alloc(base, name);
+ dentry = ERR_PTR(-ENOMEM);
+ if (!new)
+ goto out;
+ dentry = inode->i_op->lookup(inode, new, nd);
+ if (!dentry)
+ dentry = new;
+ else
+ dput(new);
+ }
out:
return dentry;
}
diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c
index de402eb6eafb..2e10cb19c5b0 100644
--- a/trunk/fs/namespace.c
+++ b/trunk/fs/namespace.c
@@ -11,8 +11,6 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
@@ -40,10 +38,12 @@
#define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head))
#define HASH_SIZE (1UL << HASH_SHIFT)
+/* spinlock for vfsmount related operations, inplace of dcache_lock */
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
+
static int event;
static DEFINE_IDA(mnt_id_ida);
static DEFINE_IDA(mnt_group_ida);
-static DEFINE_SPINLOCK(mnt_id_lock);
static int mnt_id_start = 0;
static int mnt_group_start = 1;
@@ -55,16 +55,6 @@ static struct rw_semaphore namespace_sem;
struct kobject *fs_kobj;
EXPORT_SYMBOL_GPL(fs_kobj);
-/*
- * vfsmount lock may be taken for read to prevent changes to the
- * vfsmount hash, ie. during mountpoint lookups or walking back
- * up the tree.
- *
- * It should be taken for write in all cases where the vfsmount
- * tree or hash is modified or when a vfsmount structure is modified.
- */
-DEFINE_BRLOCK(vfsmount_lock);
-
static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
{
unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
@@ -75,21 +65,18 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
#define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16)
-/*
- * allocation is serialized by namespace_sem, but we need the spinlock to
- * serialize with freeing.
- */
+/* allocation is serialized by namespace_sem */
static int mnt_alloc_id(struct vfsmount *mnt)
{
int res;
retry:
ida_pre_get(&mnt_id_ida, GFP_KERNEL);
- spin_lock(&mnt_id_lock);
+ spin_lock(&vfsmount_lock);
res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
if (!res)
mnt_id_start = mnt->mnt_id + 1;
- spin_unlock(&mnt_id_lock);
+ spin_unlock(&vfsmount_lock);
if (res == -EAGAIN)
goto retry;
@@ -99,11 +86,11 @@ static int mnt_alloc_id(struct vfsmount *mnt)
static void mnt_free_id(struct vfsmount *mnt)
{
int id = mnt->mnt_id;
- spin_lock(&mnt_id_lock);
+ spin_lock(&vfsmount_lock);
ida_remove(&mnt_id_ida, id);
if (mnt_id_start > id)
mnt_id_start = id;
- spin_unlock(&mnt_id_lock);
+ spin_unlock(&vfsmount_lock);
}
/*
@@ -361,7 +348,7 @@ static int mnt_make_readonly(struct vfsmount *mnt)
{
int ret = 0;
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
mnt->mnt_flags |= MNT_WRITE_HOLD;
/*
* After storing MNT_WRITE_HOLD, we'll read the counters. This store
@@ -395,15 +382,15 @@ static int mnt_make_readonly(struct vfsmount *mnt)
*/
smp_wmb();
mnt->mnt_flags &= ~MNT_WRITE_HOLD;
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return ret;
}
static void __mnt_unmake_readonly(struct vfsmount *mnt)
{
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
mnt->mnt_flags &= ~MNT_READONLY;
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
@@ -427,7 +414,6 @@ void free_vfsmnt(struct vfsmount *mnt)
/*
* find the first or last mount at @dentry on vfsmount @mnt depending on
* @dir. If @dir is set return the first mount else return the last mount.
- * vfsmount_lock must be held for read or write.
*/
struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
int dir)
@@ -457,11 +443,10 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
struct vfsmount *lookup_mnt(struct path *path)
{
struct vfsmount *child_mnt;
-
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1)))
mntget(child_mnt);
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return child_mnt;
}
@@ -470,9 +455,6 @@ static inline int check_mnt(struct vfsmount *mnt)
return mnt->mnt_ns == current->nsproxy->mnt_ns;
}
-/*
- * vfsmount lock must be held for write
- */
static void touch_mnt_namespace(struct mnt_namespace *ns)
{
if (ns) {
@@ -481,9 +463,6 @@ static void touch_mnt_namespace(struct mnt_namespace *ns)
}
}
-/*
- * vfsmount lock must be held for write
- */
static void __touch_mnt_namespace(struct mnt_namespace *ns)
{
if (ns && ns->event != event) {
@@ -492,9 +471,6 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
}
}
-/*
- * vfsmount lock must be held for write
- */
static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
{
old_path->dentry = mnt->mnt_mountpoint;
@@ -506,9 +482,6 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
old_path->dentry->d_mounted--;
}
-/*
- * vfsmount lock must be held for write
- */
void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
struct vfsmount *child_mnt)
{
@@ -517,9 +490,6 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
dentry->d_mounted++;
}
-/*
- * vfsmount lock must be held for write
- */
static void attach_mnt(struct vfsmount *mnt, struct path *path)
{
mnt_set_mountpoint(path->mnt, path->dentry, mnt);
@@ -529,7 +499,7 @@ static void attach_mnt(struct vfsmount *mnt, struct path *path)
}
/*
- * vfsmount lock must be held for write
+ * the caller must hold vfsmount_lock
*/
static void commit_tree(struct vfsmount *mnt)
{
@@ -653,43 +623,39 @@ static inline void __mntput(struct vfsmount *mnt)
void mntput_no_expire(struct vfsmount *mnt)
{
repeat:
- if (atomic_add_unless(&mnt->mnt_count, -1, 1))
- return;
- br_write_lock(vfsmount_lock);
- if (!atomic_dec_and_test(&mnt->mnt_count)) {
- br_write_unlock(vfsmount_lock);
- return;
- }
- if (likely(!mnt->mnt_pinned)) {
- br_write_unlock(vfsmount_lock);
- __mntput(mnt);
- return;
+ if (atomic_dec_and_lock(&mnt->mnt_count, &vfsmount_lock)) {
+ if (likely(!mnt->mnt_pinned)) {
+ spin_unlock(&vfsmount_lock);
+ __mntput(mnt);
+ return;
+ }
+ atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
+ mnt->mnt_pinned = 0;
+ spin_unlock(&vfsmount_lock);
+ acct_auto_close_mnt(mnt);
+ goto repeat;
}
- atomic_add(mnt->mnt_pinned + 1, &mnt->mnt_count);
- mnt->mnt_pinned = 0;
- br_write_unlock(vfsmount_lock);
- acct_auto_close_mnt(mnt);
- goto repeat;
}
+
EXPORT_SYMBOL(mntput_no_expire);
void mnt_pin(struct vfsmount *mnt)
{
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
mnt->mnt_pinned++;
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
EXPORT_SYMBOL(mnt_pin);
void mnt_unpin(struct vfsmount *mnt)
{
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (mnt->mnt_pinned) {
atomic_inc(&mnt->mnt_count);
mnt->mnt_pinned--;
}
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
EXPORT_SYMBOL(mnt_unpin);
@@ -780,12 +746,12 @@ int mnt_had_events(struct proc_mounts *p)
struct mnt_namespace *ns = p->ns;
int res = 0;
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (p->event != ns->event) {
p->event = ns->event;
res = 1;
}
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
return res;
}
@@ -986,12 +952,12 @@ int may_umount_tree(struct vfsmount *mnt)
int minimum_refs = 0;
struct vfsmount *p;
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
for (p = mnt; p; p = next_mnt(p, mnt)) {
actual_refs += atomic_read(&p->mnt_count);
minimum_refs += 2;
}
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
if (actual_refs > minimum_refs)
return 0;
@@ -1018,10 +984,10 @@ int may_umount(struct vfsmount *mnt)
{
int ret = 1;
down_read(&namespace_sem);
- br_read_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (propagate_mount_busy(mnt, 2))
ret = 0;
- br_read_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
up_read(&namespace_sem);
return ret;
}
@@ -1037,14 +1003,13 @@ void release_mounts(struct list_head *head)
if (mnt->mnt_parent != mnt) {
struct dentry *dentry;
struct vfsmount *m;
-
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
dentry = mnt->mnt_mountpoint;
m = mnt->mnt_parent;
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
m->mnt_ghosts--;
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
dput(dentry);
mntput(m);
}
@@ -1052,10 +1017,6 @@ void release_mounts(struct list_head *head)
}
}
-/*
- * vfsmount lock must be held for write
- * namespace_sem must be held for write
- */
void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
{
struct vfsmount *p;
@@ -1146,7 +1107,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
}
down_write(&namespace_sem);
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
event++;
if (!(flags & MNT_DETACH))
@@ -1158,7 +1119,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
umount_tree(mnt, 1, &umount_list);
retval = 0;
}
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
up_write(&namespace_sem);
release_mounts(&umount_list);
return retval;
@@ -1270,19 +1231,19 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
q = clone_mnt(p, p->mnt_root, flag);
if (!q)
goto Enomem;
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
list_add_tail(&q->mnt_list, &res->mnt_list);
attach_mnt(q, &path);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
}
return res;
Enomem:
if (res) {
LIST_HEAD(umount_list);
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
umount_tree(res, 0, &umount_list);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
release_mounts(&umount_list);
}
return NULL;
@@ -1301,9 +1262,9 @@ void drop_collected_mounts(struct vfsmount *mnt)
{
LIST_HEAD(umount_list);
down_write(&namespace_sem);
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
umount_tree(mnt, 0, &umount_list);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
up_write(&namespace_sem);
release_mounts(&umount_list);
}
@@ -1431,7 +1392,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
if (err)
goto out_cleanup_ids;
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (IS_MNT_SHARED(dest_mnt)) {
for (p = source_mnt; p; p = next_mnt(p, source_mnt))
@@ -1450,8 +1411,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
list_del_init(&child->mnt_hash);
commit_tree(child);
}
- br_write_unlock(vfsmount_lock);
-
+ spin_unlock(&vfsmount_lock);
return 0;
out_cleanup_ids:
@@ -1506,10 +1466,10 @@ static int do_change_type(struct path *path, int flag)
goto out_unlock;
}
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
change_mnt_propagation(m, type);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
out_unlock:
up_write(&namespace_sem);
@@ -1553,10 +1513,9 @@ static int do_loopback(struct path *path, char *old_name,
err = graft_tree(mnt, path);
if (err) {
LIST_HEAD(umount_list);
-
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
umount_tree(mnt, 0, &umount_list);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
release_mounts(&umount_list);
}
@@ -1609,16 +1568,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
else
err = do_remount_sb(sb, flags, data, 0);
if (!err) {
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
mnt_flags |= path->mnt->mnt_flags & MNT_PROPAGATION_MASK;
path->mnt->mnt_flags = mnt_flags;
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
up_write(&sb->s_umount);
if (!err) {
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
touch_mnt_namespace(path->mnt->mnt_ns);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
}
return err;
}
@@ -1795,7 +1754,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
return;
down_write(&namespace_sem);
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
/* extract from the expiration list every vfsmount that matches the
* following criteria:
@@ -1814,7 +1773,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
touch_mnt_namespace(mnt->mnt_ns);
umount_tree(mnt, 1, &umounts);
}
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
up_write(&namespace_sem);
release_mounts(&umounts);
@@ -1871,8 +1830,6 @@ static int select_submounts(struct vfsmount *parent, struct list_head *graveyard
/*
* process a list of expirable mountpoints with the intent of discarding any
* submounts of a specific parent mountpoint
- *
- * vfsmount_lock must be held for write
*/
static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts)
{
@@ -2091,9 +2048,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
kfree(new_ns);
return ERR_PTR(-ENOMEM);
}
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
/*
* Second pass: switch the tsk->fs->* elements and mark new vfsmounts
@@ -2287,7 +2244,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
goto out2; /* not attached */
/* make sure we can reach put_old from new_root */
tmp = old.mnt;
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
if (tmp != new.mnt) {
for (;;) {
if (tmp->mnt_parent == tmp)
@@ -2307,7 +2264,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
/* mount new_root on / */
attach_mnt(new.mnt, &root_parent);
touch_mnt_namespace(current->nsproxy->mnt_ns);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
chroot_fs_refs(&root, &new);
error = 0;
path_put(&root_parent);
@@ -2322,7 +2279,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
out0:
return error;
out3:
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
goto out2;
}
@@ -2369,8 +2326,6 @@ void __init mnt_init(void)
for (u = 0; u < HASH_SIZE; u++)
INIT_LIST_HEAD(&mount_hashtable[u]);
- br_lock_init(vfsmount_lock);
-
err = sysfs_init();
if (err)
printk(KERN_WARNING "%s: sysfs_init error: %d\n",
@@ -2389,9 +2344,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
if (!atomic_dec_and_test(&ns->count))
return;
down_write(&namespace_sem);
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
umount_tree(ns->root, 0, &umount_list);
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
up_write(&namespace_sem);
release_mounts(&umount_list);
kfree(ns);
diff --git a/trunk/fs/nfs/Kconfig b/trunk/fs/nfs/Kconfig
index 6c2aad49d731..26a510a7be09 100644
--- a/trunk/fs/nfs/Kconfig
+++ b/trunk/fs/nfs/Kconfig
@@ -63,6 +63,7 @@ config NFS_V3_ACL
config NFS_V4
bool "NFS client support for NFS version 4"
depends on NFS_FS
+ select RPCSEC_GSS_KRB5
help
This option enables support for version 4 of the NFS protocol
(RFC 3530) in the kernel's NFS client.
diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c
index e257172d438c..29539ceeb745 100644
--- a/trunk/fs/nfs/dir.c
+++ b/trunk/fs/nfs/dir.c
@@ -140,13 +140,6 @@ nfs_opendir(struct inode *inode, struct file *filp)
/* Call generic open code in order to cache credentials */
res = nfs_open(inode, filp);
- if (filp->f_path.dentry == filp->f_path.mnt->mnt_root) {
- /* This is a mountpoint, so d_revalidate will never
- * have been called, so we need to refresh the
- * inode (for close-open consistency) ourselves.
- */
- __nfs_revalidate_inode(NFS_SERVER(inode), inode);
- }
return res;
}
@@ -1110,7 +1103,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
goto no_open_dput;
/* We can't create new files, or truncate existing ones here */
- openflags &= ~(O_CREAT|O_EXCL|O_TRUNC);
+ openflags &= ~(O_CREAT|O_TRUNC);
/*
* Note: we're not holding inode->i_mutex and so may be racing with
diff --git a/trunk/fs/nfs/file.c b/trunk/fs/nfs/file.c
index eb51bd6201da..2d141a74ae82 100644
--- a/trunk/fs/nfs/file.c
+++ b/trunk/fs/nfs/file.c
@@ -323,7 +323,7 @@ nfs_file_fsync(struct file *file, int datasync)
have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
if (have_error)
ret = xchg(&ctx->error, 0);
- if (!ret && status < 0)
+ if (!ret)
ret = status;
return ret;
}
diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c
index 089da5b5d20a..7ffbb98ddec3 100644
--- a/trunk/fs/nfs/nfs4proc.c
+++ b/trunk/fs/nfs/nfs4proc.c
@@ -2036,8 +2036,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
struct rpc_cred *cred;
struct nfs4_state *state;
struct dentry *res;
- int open_flags = nd->intent.open.flags;
- fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
+ fmode_t fmode = nd->intent.open.flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
if (nd->flags & LOOKUP_CREATE) {
attr.ia_mode = nd->intent.open.create_mode;
@@ -2045,9 +2044,8 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
if (!IS_POSIXACL(dir))
attr.ia_mode &= ~current_umask();
} else {
- open_flags &= ~O_EXCL;
attr.ia_valid = 0;
- BUG_ON(open_flags & O_CREAT);
+ BUG_ON(nd->intent.open.flags & O_CREAT);
}
cred = rpc_lookup_cred();
@@ -2056,7 +2054,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
parent = dentry->d_parent;
/* Protect against concurrent sillydeletes */
nfs_block_sillyrename(parent);
- state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred);
+ state = nfs4_do_open(dir, &path, fmode, nd->intent.open.flags, &attr, cred);
put_rpccred(cred);
if (IS_ERR(state)) {
if (PTR_ERR(state) == -ENOENT) {
@@ -2275,7 +2273,8 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct
out:
if (page)
__free_page(page);
- kfree(locations);
+ if (locations)
+ kfree(locations);
return status;
}
diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c
index ec3966e4706b..ee26316ad1f4 100644
--- a/trunk/fs/nfs/super.c
+++ b/trunk/fs/nfs/super.c
@@ -655,13 +655,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
if (nfss->options & NFS_OPTION_FSCACHE)
seq_printf(m, ",fsc");
-
- if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
- if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
- seq_printf(m, ",lookupcache=none");
- else
- seq_printf(m, ",lookupcache=pos");
- }
}
/*
diff --git a/trunk/fs/nfsd/Kconfig b/trunk/fs/nfsd/Kconfig
index 95932f523aef..503b9da159a3 100644
--- a/trunk/fs/nfsd/Kconfig
+++ b/trunk/fs/nfsd/Kconfig
@@ -69,6 +69,7 @@ config NFSD_V4
depends on NFSD && PROC_FS && EXPERIMENTAL
select NFSD_V3
select FS_POSIX_ACL
+ select RPCSEC_GSS_KRB5
help
This option enables support in your system's NFS server for
version 4 of the NFS protocol (RFC 3530).
diff --git a/trunk/fs/nilfs2/super.c b/trunk/fs/nilfs2/super.c
index 922263393c76..1fa86b9df73b 100644
--- a/trunk/fs/nilfs2/super.c
+++ b/trunk/fs/nilfs2/super.c
@@ -175,24 +175,24 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
int err;
+ int barrier_done = 0;
+ if (nilfs_test_opt(sbi, BARRIER)) {
+ set_buffer_ordered(nilfs->ns_sbh[0]);
+ barrier_done = 1;
+ }
retry:
set_buffer_dirty(nilfs->ns_sbh[0]);
-
- if (nilfs_test_opt(sbi, BARRIER)) {
- err = __sync_dirty_buffer(nilfs->ns_sbh[0],
- WRITE_SYNC | WRITE_BARRIER);
- if (err == -EOPNOTSUPP) {
- nilfs_warning(sbi->s_super, __func__,
- "barrier-based sync failed. "
- "disabling barriers\n");
- nilfs_clear_opt(sbi, BARRIER);
- goto retry;
- }
- } else {
- err = sync_dirty_buffer(nilfs->ns_sbh[0]);
+ err = sync_dirty_buffer(nilfs->ns_sbh[0]);
+ if (err == -EOPNOTSUPP && barrier_done) {
+ nilfs_warning(sbi->s_super, __func__,
+ "barrier-based sync failed. "
+ "disabling barriers\n");
+ nilfs_clear_opt(sbi, BARRIER);
+ barrier_done = 0;
+ clear_buffer_ordered(nilfs->ns_sbh[0]);
+ goto retry;
}
-
if (unlikely(err)) {
printk(KERN_ERR
"NILFS: unable to write superblock (err=%d)\n", err);
@@ -400,10 +400,9 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
list_add(&sbi->s_list, &nilfs->ns_supers);
up_write(&nilfs->ns_super_sem);
- err = -ENOMEM;
sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
if (!sbi->s_ifile)
- goto delist;
+ return -ENOMEM;
down_read(&nilfs->ns_segctor_sem);
err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
@@ -434,7 +433,6 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
nilfs_mdt_destroy(sbi->s_ifile);
sbi->s_ifile = NULL;
- delist:
down_write(&nilfs->ns_super_sem);
list_del_init(&sbi->s_list);
up_write(&nilfs->ns_super_sem);
diff --git a/trunk/fs/nilfs2/the_nilfs.c b/trunk/fs/nilfs2/the_nilfs.c
index 4317f177ea7c..37de1f062d81 100644
--- a/trunk/fs/nilfs2/the_nilfs.c
+++ b/trunk/fs/nilfs2/the_nilfs.c
@@ -608,11 +608,11 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
return -EINVAL;
}
- if (!valid[!swp])
+ if (swp) {
printk(KERN_WARNING "NILFS warning: broken superblock. "
"using spare superblock.\n");
- if (swp)
nilfs_swap_super_block(nilfs);
+ }
nilfs->ns_sbwcount = 0;
nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
@@ -775,7 +775,6 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
start * sects_per_block,
nblocks * sects_per_block,
GFP_NOFS,
- BLKDEV_IFL_WAIT |
BLKDEV_IFL_BARRIER);
if (ret < 0)
return ret;
@@ -786,8 +785,7 @@ int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
ret = blkdev_issue_discard(nilfs->ns_bdev,
start * sects_per_block,
nblocks * sects_per_block,
- GFP_NOFS,
- BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
+ GFP_NOFS, BLKDEV_IFL_BARRIER);
return ret;
}
diff --git a/trunk/fs/open.c b/trunk/fs/open.c
index d74e1983e8dc..630715f9f73d 100644
--- a/trunk/fs/open.c
+++ b/trunk/fs/open.c
@@ -675,7 +675,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f->f_path.mnt = mnt;
f->f_pos = 0;
f->f_op = fops_get(inode->i_fop);
- file_sb_list_add(f, inode->i_sb);
+ file_move(f, &inode->i_sb->s_files);
error = security_dentry_open(f, cred);
if (error)
@@ -721,7 +721,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
mnt_drop_write(mnt);
}
}
- file_sb_list_del(f);
+ file_kill(f);
f->f_path.dentry = NULL;
f->f_path.mnt = NULL;
cleanup_file:
diff --git a/trunk/fs/pnode.c b/trunk/fs/pnode.c
index 8066b8dd748f..5cc564a83149 100644
--- a/trunk/fs/pnode.c
+++ b/trunk/fs/pnode.c
@@ -126,9 +126,6 @@ static int do_make_slave(struct vfsmount *mnt)
return 0;
}
-/*
- * vfsmount lock must be held for write
- */
void change_mnt_propagation(struct vfsmount *mnt, int type)
{
if (type == MS_SHARED) {
@@ -273,12 +270,12 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
prev_src_mnt = child;
}
out:
- br_write_lock(vfsmount_lock);
+ spin_lock(&vfsmount_lock);
while (!list_empty(&tmp_list)) {
child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash);
umount_tree(child, 0, &umount_list);
}
- br_write_unlock(vfsmount_lock);
+ spin_unlock(&vfsmount_lock);
release_mounts(&umount_list);
return ret;
}
@@ -299,8 +296,6 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count)
* other mounts its parent propagates to.
* Check if any of these mounts that **do not have submounts**
* have more references than 'refcnt'. If so return busy.
- *
- * vfsmount lock must be held for read or write
*/
int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
{
@@ -358,8 +353,6 @@ static void __propagate_umount(struct vfsmount *mnt)
* collect all mounts that receive propagation from the mount in @list,
* and return these additional mounts in the same list.
* @list: the list of mounts to be unmounted.
- *
- * vfsmount lock must be held for write
*/
int propagate_umount(struct list_head *list)
{
diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c
index caa758377d66..ae35413dcbe1 100644
--- a/trunk/fs/reiserfs/inode.c
+++ b/trunk/fs/reiserfs/inode.c
@@ -83,7 +83,6 @@ void reiserfs_evict_inode(struct inode *inode)
dquot_drop(inode);
inode->i_blocks = 0;
reiserfs_write_unlock_once(inode->i_sb, depth);
- return;
no_delete:
end_writeback(inode);
diff --git a/trunk/fs/reiserfs/journal.c b/trunk/fs/reiserfs/journal.c
index 812e2c05aa29..1ec952b1f036 100644
--- a/trunk/fs/reiserfs/journal.c
+++ b/trunk/fs/reiserfs/journal.c
@@ -2311,7 +2311,7 @@ static int journal_read_transaction(struct super_block *sb,
/* flush out the real blocks */
for (i = 0; i < get_desc_trans_len(desc); i++) {
set_buffer_dirty(real_blocks[i]);
- write_dirty_buffer(real_blocks[i], WRITE);
+ ll_rw_block(SWRITE, 1, real_blocks + i);
}
for (i = 0; i < get_desc_trans_len(desc); i++) {
wait_on_buffer(real_blocks[i]);
diff --git a/trunk/fs/super.c b/trunk/fs/super.c
index 8819e3a7ff20..9674ab2c8718 100644
--- a/trunk/fs/super.c
+++ b/trunk/fs/super.c
@@ -54,22 +54,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
s = NULL;
goto out;
}
-#ifdef CONFIG_SMP
- s->s_files = alloc_percpu(struct list_head);
- if (!s->s_files) {
- security_sb_free(s);
- kfree(s);
- s = NULL;
- goto out;
- } else {
- int i;
-
- for_each_possible_cpu(i)
- INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i));
- }
-#else
INIT_LIST_HEAD(&s->s_files);
-#endif
INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_HEAD(&s->s_anon);
INIT_LIST_HEAD(&s->s_inodes);
@@ -123,9 +108,6 @@ static struct super_block *alloc_super(struct file_system_type *type)
*/
static inline void destroy_super(struct super_block *s)
{
-#ifdef CONFIG_SMP
- free_percpu(s->s_files);
-#endif
security_sb_free(s);
kfree(s->s_subtype);
kfree(s->s_options);
diff --git a/trunk/fs/ufs/balloc.c b/trunk/fs/ufs/balloc.c
index 46f7a807bbc1..048484fb10d2 100644
--- a/trunk/fs/ufs/balloc.c
+++ b/trunk/fs/ufs/balloc.c
@@ -114,8 +114,10 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
sb->s_dirt = 1;
unlock_super (sb);
@@ -205,8 +207,10 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
if (overflow) {
fragment += count;
@@ -554,8 +558,10 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
sb->s_dirt = 1;
UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment);
@@ -674,8 +680,10 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,
succed:
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
sb->s_dirt = 1;
result += cgno * uspi->s_fpg;
diff --git a/trunk/fs/ufs/ialloc.c b/trunk/fs/ufs/ialloc.c
index 2eabf04af3de..428017e018fe 100644
--- a/trunk/fs/ufs/ialloc.c
+++ b/trunk/fs/ufs/ialloc.c
@@ -113,8 +113,10 @@ void ufs_free_inode (struct inode * inode)
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
sb->s_dirt = 1;
unlock_super (sb);
@@ -154,8 +156,10 @@ static void ufs2_init_inodes_chunk(struct super_block *sb,
fs32_add(sb, &ucg->cg_u.cg_u2.cg_initediblk, uspi->s_inopb);
ubh_mark_buffer_dirty(UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer(UCPI_UBH(ucpi));
+ }
UFSD("EXIT\n");
}
@@ -286,8 +290,10 @@ struct inode * ufs_new_inode(struct inode * dir, int mode)
}
ubh_mark_buffer_dirty (USPI_UBH(uspi));
ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
- if (sb->s_flags & MS_SYNCHRONOUS)
- ubh_sync_block(UCPI_UBH(ucpi));
+ if (sb->s_flags & MS_SYNCHRONOUS) {
+ ubh_ll_rw_block(SWRITE, UCPI_UBH(ucpi));
+ ubh_wait_on_buffer (UCPI_UBH(ucpi));
+ }
sb->s_dirt = 1;
inode->i_ino = cg * uspi->s_ipg + bit;
diff --git a/trunk/fs/ufs/truncate.c b/trunk/fs/ufs/truncate.c
index a58f9155fc9a..34d5cb135320 100644
--- a/trunk/fs/ufs/truncate.c
+++ b/trunk/fs/ufs/truncate.c
@@ -243,8 +243,10 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p)
ubh_bforget(ind_ubh);
ind_ubh = NULL;
}
- if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh))
- ubh_sync_block(ind_ubh);
+ if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) {
+ ubh_ll_rw_block(SWRITE, ind_ubh);
+ ubh_wait_on_buffer (ind_ubh);
+ }
ubh_brelse (ind_ubh);
UFSD("EXIT: ino %lu\n", inode->i_ino);
@@ -305,8 +307,10 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
ubh_bforget(dind_bh);
dind_bh = NULL;
}
- if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh))
- ubh_sync_block(dind_bh);
+ if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) {
+ ubh_ll_rw_block(SWRITE, dind_bh);
+ ubh_wait_on_buffer (dind_bh);
+ }
ubh_brelse (dind_bh);
UFSD("EXIT: ino %lu\n", inode->i_ino);
@@ -363,8 +367,10 @@ static int ufs_trunc_tindirect(struct inode *inode)
ubh_bforget(tind_bh);
tind_bh = NULL;
}
- if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh))
- ubh_sync_block(tind_bh);
+ if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) {
+ ubh_ll_rw_block(SWRITE, tind_bh);
+ ubh_wait_on_buffer (tind_bh);
+ }
ubh_brelse (tind_bh);
UFSD("EXIT: ino %lu\n", inode->i_ino);
diff --git a/trunk/fs/ufs/util.c b/trunk/fs/ufs/util.c
index d2c36d53fe66..85a7fc9e4a4e 100644
--- a/trunk/fs/ufs/util.c
+++ b/trunk/fs/ufs/util.c
@@ -113,17 +113,21 @@ void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag)
}
}
-void ubh_sync_block(struct ufs_buffer_head *ubh)
+void ubh_ll_rw_block(int rw, struct ufs_buffer_head *ubh)
{
- if (ubh) {
- unsigned i;
+ if (!ubh)
+ return;
- for (i = 0; i < ubh->count; i++)
- write_dirty_buffer(ubh->bh[i], WRITE);
+ ll_rw_block(rw, ubh->count, ubh->bh);
+}
- for (i = 0; i < ubh->count; i++)
- wait_on_buffer(ubh->bh[i]);
- }
+void ubh_wait_on_buffer (struct ufs_buffer_head * ubh)
+{
+ unsigned i;
+ if (!ubh)
+ return;
+ for ( i = 0; i < ubh->count; i++ )
+ wait_on_buffer (ubh->bh[i]);
}
void ubh_bforget (struct ufs_buffer_head * ubh)
diff --git a/trunk/fs/ufs/util.h b/trunk/fs/ufs/util.h
index 9f8775ce381c..0466036912f1 100644
--- a/trunk/fs/ufs/util.h
+++ b/trunk/fs/ufs/util.h
@@ -269,7 +269,8 @@ extern void ubh_brelse (struct ufs_buffer_head *);
extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);
extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
-extern void ubh_sync_block(struct ufs_buffer_head *);
+extern void ubh_ll_rw_block(int, struct ufs_buffer_head *);
+extern void ubh_wait_on_buffer (struct ufs_buffer_head *);
extern void ubh_bforget (struct ufs_buffer_head *);
extern int ubh_buffer_dirty (struct ufs_buffer_head *);
#define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size)
diff --git a/trunk/include/asm-generic/syscalls.h b/trunk/include/asm-generic/syscalls.h
index d89dec864d42..df84e3b04555 100644
--- a/trunk/include/asm-generic/syscalls.h
+++ b/trunk/include/asm-generic/syscalls.h
@@ -23,10 +23,8 @@ asmlinkage long sys_vfork(struct pt_regs *regs);
#endif
#ifndef sys_execve
-asmlinkage long sys_execve(const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs);
+asmlinkage long sys_execve(char __user *filename, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs);
#endif
#ifndef sys_mmap2
diff --git a/trunk/include/linux/amba/clcd.h b/trunk/include/linux/amba/clcd.h
index be33b3affc8a..ca16c3801a1e 100644
--- a/trunk/include/linux/amba/clcd.h
+++ b/trunk/include/linux/amba/clcd.h
@@ -150,7 +150,6 @@ struct clcd_fb {
u16 off_cntl;
u32 clcd_cntl;
u32 cmap[16];
- bool clk_enabled;
};
static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
diff --git a/trunk/include/linux/binfmts.h b/trunk/include/linux/binfmts.h
index a065612fc928..c809e286d213 100644
--- a/trunk/include/linux/binfmts.h
+++ b/trunk/include/linux/binfmts.h
@@ -50,8 +50,8 @@ struct linux_binprm{
int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */
unsigned int per_clear; /* bits to clear in current->personality */
int argc, envc;
- const char * filename; /* Name of binary as seen by procps */
- const char * interp; /* Name of the binary really executed. Most
+ char * filename; /* Name of binary as seen by procps */
+ char * interp; /* Name of the binary really executed. Most
of the time same as filename, but could be
different for binfmt_{misc,script} */
unsigned interp_flags;
@@ -126,8 +126,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
unsigned long stack_top,
int executable_stack);
extern int bprm_mm_init(struct linux_binprm *bprm);
-extern int copy_strings_kernel(int argc, const char *const *argv,
- struct linux_binprm *bprm);
+extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
extern int prepare_bprm_creds(struct linux_binprm *bprm);
extern void install_exec_creds(struct linux_binprm *bprm);
extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
diff --git a/trunk/include/linux/buffer_head.h b/trunk/include/linux/buffer_head.h
index ec94c12f21da..43e649a72529 100644
--- a/trunk/include/linux/buffer_head.h
+++ b/trunk/include/linux/buffer_head.h
@@ -32,6 +32,7 @@ enum bh_state_bits {
BH_Delay, /* Buffer is not yet allocated on disk */
BH_Boundary, /* Block is followed by a discontiguity */
BH_Write_EIO, /* I/O error on write */
+ BH_Ordered, /* ordered write */
BH_Eopnotsupp, /* operation not supported (barrier) */
BH_Unwritten, /* Buffer is allocated on disk but not written */
BH_Quiet, /* Buffer Error Prinks to be quiet */
@@ -124,6 +125,7 @@ BUFFER_FNS(Async_Write, async_write)
BUFFER_FNS(Delay, delay)
BUFFER_FNS(Boundary, boundary)
BUFFER_FNS(Write_EIO, write_io_error)
+BUFFER_FNS(Ordered, ordered)
BUFFER_FNS(Eopnotsupp, eopnotsupp)
BUFFER_FNS(Unwritten, unwritten)
@@ -181,8 +183,6 @@ void unlock_buffer(struct buffer_head *bh);
void __lock_buffer(struct buffer_head *bh);
void ll_rw_block(int, int, struct buffer_head * bh[]);
int sync_dirty_buffer(struct buffer_head *bh);
-int __sync_dirty_buffer(struct buffer_head *bh, int rw);
-void write_dirty_buffer(struct buffer_head *bh, int rw);
int submit_bh(int, struct buffer_head *);
void write_boundary_block(struct block_device *bdev,
sector_t bblock, unsigned blocksize);
diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h
index 76041b614758..9a96b4d83fc1 100644
--- a/trunk/include/linux/fs.h
+++ b/trunk/include/linux/fs.h
@@ -125,6 +125,9 @@ struct inodes_stat_t {
* block layer could (in theory) choose to ignore this
* request if it runs into resource problems.
* WRITE A normal async write. Device will be plugged.
+ * SWRITE Like WRITE, but a special case for ll_rw_block() that
+ * tells it to lock the buffer first. Normally a buffer
+ * must be locked before doing IO.
* WRITE_SYNC_PLUG Synchronous write. Identical to WRITE, but passes down
* the hint that someone will be waiting on this IO
* shortly. The device must still be unplugged explicitly,
@@ -135,6 +138,9 @@ struct inodes_stat_t {
* immediately after submission. The write equivalent
* of READ_SYNC.
* WRITE_ODIRECT_PLUG Special case write for O_DIRECT only.
+ * SWRITE_SYNC
+ * SWRITE_SYNC_PLUG Like WRITE_SYNC/WRITE_SYNC_PLUG, but locks the buffer.
+ * See SWRITE.
* WRITE_BARRIER Like WRITE_SYNC, but tells the block layer that all
* previously submitted writes must be safely on storage
* before this one is started. Also guarantees that when
@@ -149,6 +155,7 @@ struct inodes_stat_t {
#define READ 0
#define WRITE RW_MASK
#define READA RWA_MASK
+#define SWRITE (WRITE | READA)
#define READ_SYNC (READ | REQ_SYNC | REQ_UNPLUG)
#define READ_META (READ | REQ_META)
@@ -158,6 +165,8 @@ struct inodes_stat_t {
#define WRITE_META (WRITE | REQ_META)
#define WRITE_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG | \
REQ_HARDBARRIER)
+#define SWRITE_SYNC_PLUG (SWRITE | REQ_SYNC | REQ_NOIDLE)
+#define SWRITE_SYNC (SWRITE | REQ_SYNC | REQ_NOIDLE | REQ_UNPLUG)
/*
* These aren't really reads or writes, they pass down information about
@@ -920,9 +929,6 @@ struct file {
#define f_vfsmnt f_path.mnt
const struct file_operations *f_op;
spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */
-#ifdef CONFIG_SMP
- int f_sb_list_cpu;
-#endif
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
@@ -947,6 +953,9 @@ struct file {
unsigned long f_mnt_write_state;
#endif
};
+extern spinlock_t files_lock;
+#define file_list_lock() spin_lock(&files_lock);
+#define file_list_unlock() spin_unlock(&files_lock);
#define get_file(x) atomic_long_inc(&(x)->f_count)
#define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
@@ -1337,11 +1346,7 @@ struct super_block {
struct list_head s_inodes; /* all inodes */
struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
-#ifdef CONFIG_SMP
- struct list_head __percpu *s_files;
-#else
struct list_head s_files;
-#endif
/* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
struct list_head s_dentry_lru; /* unused dentry lru */
int s_nr_dentry_unused; /* # of dentry on lru */
@@ -2192,6 +2197,8 @@ static inline void insert_inode_hash(struct inode *inode) {
__insert_inode_hash(inode, inode->i_ino);
}
+extern void file_move(struct file *f, struct list_head *list);
+extern void file_kill(struct file *f);
#ifdef CONFIG_BLOCK
extern void submit_bio(int, struct bio *);
extern int bdev_read_only(struct block_device *);
diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h
index a42b5bf02f8b..eca3d5202138 100644
--- a/trunk/include/linux/fs_struct.h
+++ b/trunk/include/linux/fs_struct.h
@@ -5,7 +5,7 @@
struct fs_struct {
int users;
- spinlock_t lock;
+ rwlock_t lock;
int umask;
int in_exec;
struct path root, pwd;
@@ -23,29 +23,29 @@ extern int unshare_fs_struct(void);
static inline void get_fs_root(struct fs_struct *fs, struct path *root)
{
- spin_lock(&fs->lock);
+ read_lock(&fs->lock);
*root = fs->root;
path_get(root);
- spin_unlock(&fs->lock);
+ read_unlock(&fs->lock);
}
static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
{
- spin_lock(&fs->lock);
+ read_lock(&fs->lock);
*pwd = fs->pwd;
path_get(pwd);
- spin_unlock(&fs->lock);
+ read_unlock(&fs->lock);
}
static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
struct path *pwd)
{
- spin_lock(&fs->lock);
+ read_lock(&fs->lock);
*root = fs->root;
path_get(root);
*pwd = fs->pwd;
path_get(pwd);
- spin_unlock(&fs->lock);
+ read_unlock(&fs->lock);
}
#endif /* _LINUX_FS_STRUCT_H */
diff --git a/trunk/include/linux/kfifo.h b/trunk/include/linux/kfifo.h
index 4aa95f203f3e..311f8753d713 100644
--- a/trunk/include/linux/kfifo.h
+++ b/trunk/include/linux/kfifo.h
@@ -836,8 +836,6 @@ extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
-extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
-
extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
void *buf, unsigned int len, size_t recsize);
diff --git a/trunk/include/linux/lglock.h b/trunk/include/linux/lglock.h
deleted file mode 100644
index b288cb713b90..000000000000
--- a/trunk/include/linux/lglock.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Specialised local-global spinlock. Can only be declared as global variables
- * to avoid overhead and keep things simple (and we don't want to start using
- * these inside dynamically allocated structures).
- *
- * "local/global locks" (lglocks) can be used to:
- *
- * - Provide fast exclusive access to per-CPU data, with exclusive access to
- * another CPU's data allowed but possibly subject to contention, and to
- * provide very slow exclusive access to all per-CPU data.
- * - Or to provide very fast and scalable read serialisation, and to provide
- * very slow exclusive serialisation of data (not necessarily per-CPU data).
- *
- * Brlocks are also implemented as a short-hand notation for the latter use
- * case.
- *
- * Copyright 2009, 2010, Nick Piggin, Novell Inc.
- */
-#ifndef __LINUX_LGLOCK_H
-#define __LINUX_LGLOCK_H
-
-#include
-#include
-#include
-
-/* can make br locks by using local lock for read side, global lock for write */
-#define br_lock_init(name) name##_lock_init()
-#define br_read_lock(name) name##_local_lock()
-#define br_read_unlock(name) name##_local_unlock()
-#define br_write_lock(name) name##_global_lock_online()
-#define br_write_unlock(name) name##_global_unlock_online()
-
-#define DECLARE_BRLOCK(name) DECLARE_LGLOCK(name)
-#define DEFINE_BRLOCK(name) DEFINE_LGLOCK(name)
-
-
-#define lg_lock_init(name) name##_lock_init()
-#define lg_local_lock(name) name##_local_lock()
-#define lg_local_unlock(name) name##_local_unlock()
-#define lg_local_lock_cpu(name, cpu) name##_local_lock_cpu(cpu)
-#define lg_local_unlock_cpu(name, cpu) name##_local_unlock_cpu(cpu)
-#define lg_global_lock(name) name##_global_lock()
-#define lg_global_unlock(name) name##_global_unlock()
-#define lg_global_lock_online(name) name##_global_lock_online()
-#define lg_global_unlock_online(name) name##_global_unlock_online()
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-#define LOCKDEP_INIT_MAP lockdep_init_map
-
-#define DEFINE_LGLOCK_LOCKDEP(name) \
- struct lock_class_key name##_lock_key; \
- struct lockdep_map name##_lock_dep_map; \
- EXPORT_SYMBOL(name##_lock_dep_map)
-
-#else
-#define LOCKDEP_INIT_MAP(a, b, c, d)
-
-#define DEFINE_LGLOCK_LOCKDEP(name)
-#endif
-
-
-#define DECLARE_LGLOCK(name) \
- extern void name##_lock_init(void); \
- extern void name##_local_lock(void); \
- extern void name##_local_unlock(void); \
- extern void name##_local_lock_cpu(int cpu); \
- extern void name##_local_unlock_cpu(int cpu); \
- extern void name##_global_lock(void); \
- extern void name##_global_unlock(void); \
- extern void name##_global_lock_online(void); \
- extern void name##_global_unlock_online(void); \
-
-#define DEFINE_LGLOCK(name) \
- \
- DEFINE_PER_CPU(arch_spinlock_t, name##_lock); \
- DEFINE_LGLOCK_LOCKDEP(name); \
- \
- void name##_lock_init(void) { \
- int i; \
- LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \
- for_each_possible_cpu(i) { \
- arch_spinlock_t *lock; \
- lock = &per_cpu(name##_lock, i); \
- *lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; \
- } \
- } \
- EXPORT_SYMBOL(name##_lock_init); \
- \
- void name##_local_lock(void) { \
- arch_spinlock_t *lock; \
- preempt_disable(); \
- rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \
- lock = &__get_cpu_var(name##_lock); \
- arch_spin_lock(lock); \
- } \
- EXPORT_SYMBOL(name##_local_lock); \
- \
- void name##_local_unlock(void) { \
- arch_spinlock_t *lock; \
- rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \
- lock = &__get_cpu_var(name##_lock); \
- arch_spin_unlock(lock); \
- preempt_enable(); \
- } \
- EXPORT_SYMBOL(name##_local_unlock); \
- \
- void name##_local_lock_cpu(int cpu) { \
- arch_spinlock_t *lock; \
- preempt_disable(); \
- rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_); \
- lock = &per_cpu(name##_lock, cpu); \
- arch_spin_lock(lock); \
- } \
- EXPORT_SYMBOL(name##_local_lock_cpu); \
- \
- void name##_local_unlock_cpu(int cpu) { \
- arch_spinlock_t *lock; \
- rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_); \
- lock = &per_cpu(name##_lock, cpu); \
- arch_spin_unlock(lock); \
- preempt_enable(); \
- } \
- EXPORT_SYMBOL(name##_local_unlock_cpu); \
- \
- void name##_global_lock_online(void) { \
- int i; \
- preempt_disable(); \
- rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \
- for_each_online_cpu(i) { \
- arch_spinlock_t *lock; \
- lock = &per_cpu(name##_lock, i); \
- arch_spin_lock(lock); \
- } \
- } \
- EXPORT_SYMBOL(name##_global_lock_online); \
- \
- void name##_global_unlock_online(void) { \
- int i; \
- rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \
- for_each_online_cpu(i) { \
- arch_spinlock_t *lock; \
- lock = &per_cpu(name##_lock, i); \
- arch_spin_unlock(lock); \
- } \
- preempt_enable(); \
- } \
- EXPORT_SYMBOL(name##_global_unlock_online); \
- \
- void name##_global_lock(void) { \
- int i; \
- preempt_disable(); \
- rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \
- for_each_online_cpu(i) { \
- arch_spinlock_t *lock; \
- lock = &per_cpu(name##_lock, i); \
- arch_spin_lock(lock); \
- } \
- } \
- EXPORT_SYMBOL(name##_global_lock); \
- \
- void name##_global_unlock(void) { \
- int i; \
- rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \
- for_each_online_cpu(i) { \
- arch_spinlock_t *lock; \
- lock = &per_cpu(name##_lock, i); \
- arch_spin_unlock(lock); \
- } \
- preempt_enable(); \
- } \
- EXPORT_SYMBOL(name##_global_unlock);
-#endif
diff --git a/trunk/include/linux/mm_types.h b/trunk/include/linux/mm_types.h
index ee7e258627f9..b8bb9a6a1f37 100644
--- a/trunk/include/linux/mm_types.h
+++ b/trunk/include/linux/mm_types.h
@@ -134,7 +134,7 @@ struct vm_area_struct {
within vm_mm. */
/* linked list of VM areas per task, sorted by address */
- struct vm_area_struct *vm_next, *vm_prev;
+ struct vm_area_struct *vm_next;
pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, see mm.h. */
diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h
index 1e2a6db2d7dd..ce160d68f5e7 100644
--- a/trunk/include/linux/sched.h
+++ b/trunk/include/linux/sched.h
@@ -2109,9 +2109,7 @@ extern void daemonize(const char *, ...);
extern int allow_signal(int);
extern int disallow_signal(int);
-extern int do_execve(const char *,
- const char __user * const __user *,
- const char __user * const __user *, struct pt_regs *);
+extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
struct task_struct *fork_idle(int);
diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h
index 9f63538928c0..6d14409c4d9a 100644
--- a/trunk/include/linux/slub_def.h
+++ b/trunk/include/linux/slub_def.h
@@ -68,7 +68,7 @@ struct kmem_cache_order_objects {
* Slab cache management.
*/
struct kmem_cache {
- struct kmem_cache_cpu __percpu *cpu_slab;
+ struct kmem_cache_cpu *cpu_slab;
/* Used for retriving partial slabs etc */
unsigned long flags;
int size; /* The size of an object including meta data */
diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h
index 92e52a1e6af3..ae0a5286f558 100644
--- a/trunk/include/linux/spi/spi.h
+++ b/trunk/include/linux/spi/spi.h
@@ -213,9 +213,6 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @dma_alignment: SPI controller constraint on DMA buffers alignment.
* @mode_bits: flags understood by this controller driver
* @flags: other constraints relevant to this driver
- * @bus_lock_spinlock: spinlock for SPI bus locking
- * @bus_lock_mutex: mutex for SPI bus locking
- * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
* must fail if an unrecognized or unsupported mode is requested.
diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h
index e6319d18a55d..6e5d19788634 100644
--- a/trunk/include/linux/syscalls.h
+++ b/trunk/include/linux/syscalls.h
@@ -820,7 +820,7 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
u64 mask, int fd,
const char __user *pathname);
-int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
asmlinkage long sys_perf_event_open(
diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h
index 67d64e6efe7a..1437da3ddc62 100644
--- a/trunk/include/linux/tty.h
+++ b/trunk/include/linux/tty.h
@@ -329,13 +329,6 @@ struct tty_struct {
struct tty_port *port;
};
-/* Each of a tty's open files has private_data pointing to tty_file_private */
-struct tty_file_private {
- struct tty_struct *tty;
- struct file *file;
- struct list_head list;
-};
-
/* tty magic number */
#define TTY_MAGIC 0x5401
@@ -465,7 +458,6 @@ extern void proc_clear_tty(struct task_struct *p);
extern struct tty_struct *get_current_tty(void);
extern void tty_default_fops(struct file_operations *fops);
extern struct tty_struct *alloc_tty_struct(void);
-extern void tty_add_file(struct tty_struct *tty, struct file *file);
extern void free_tty_struct(struct tty_struct *tty);
extern void initialize_tty_struct(struct tty_struct *tty,
struct tty_driver *driver, int idx);
@@ -478,7 +470,6 @@ extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty);
extern struct mutex tty_mutex;
-extern spinlock_t tty_files_lock;
extern void tty_write_unlock(struct tty_struct *tty);
extern int tty_write_lock(struct tty_struct *tty, int ndelay);
diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h
index 7dc97d12253c..6a664c3f7c1e 100644
--- a/trunk/include/sound/emu10k1.h
+++ b/trunk/include/sound/emu10k1.h
@@ -1707,7 +1707,6 @@ struct snd_emu10k1 {
unsigned int card_type; /* EMU10K1_CARD_* */
unsigned int ecard_ctrl; /* ecard control bits */
unsigned long dma_mask; /* PCI DMA mask */
- unsigned int delay_pcm_irq; /* in samples */
int max_cache_pages; /* max memory size / PAGE_SIZE */
struct snd_dma_buffer silent_page; /* silent page */
struct snd_dma_buffer ptb_pages; /* page table pages */
diff --git a/trunk/include/trace/events/workqueue.h b/trunk/include/trace/events/workqueue.h
deleted file mode 100644
index 49682d7e9d60..000000000000
--- a/trunk/include/trace/events/workqueue.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM workqueue
-
-#if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_WORKQUEUE_H
-
-#include
-#include
-
-/**
- * workqueue_execute_start - called immediately before the workqueue callback
- * @work: pointer to struct work_struct
- *
- * Allows to track workqueue execution.
- */
-TRACE_EVENT(workqueue_execute_start,
-
- TP_PROTO(struct work_struct *work),
-
- TP_ARGS(work),
-
- TP_STRUCT__entry(
- __field( void *, work )
- __field( void *, function)
- ),
-
- TP_fast_assign(
- __entry->work = work;
- __entry->function = work->func;
- ),
-
- TP_printk("work struct %p: function %pf", __entry->work, __entry->function)
-);
-
-/**
- * workqueue_execute_end - called immediately before the workqueue callback
- * @work: pointer to struct work_struct
- *
- * Allows to track workqueue execution.
- */
-TRACE_EVENT(workqueue_execute_end,
-
- TP_PROTO(struct work_struct *work),
-
- TP_ARGS(work),
-
- TP_STRUCT__entry(
- __field( void *, work )
- ),
-
- TP_fast_assign(
- __entry->work = work;
- ),
-
- TP_printk("work struct %p", __entry->work)
-);
-
-
-#endif /* _TRACE_WORKQUEUE_H */
-
-/* This part must be outside protection */
-#include
diff --git a/trunk/init/do_mounts_initrd.c b/trunk/init/do_mounts_initrd.c
index 3098a38f3ae1..2b108538d0d9 100644
--- a/trunk/init/do_mounts_initrd.c
+++ b/trunk/init/do_mounts_initrd.c
@@ -24,11 +24,10 @@ static int __init no_initrd(char *str)
__setup("noinitrd", no_initrd);
-static int __init do_linuxrc(void *_shell)
+static int __init do_linuxrc(void * shell)
{
- static const char *argv[] = { "linuxrc", NULL, };
- extern const char *envp_init[];
- const char *shell = _shell;
+ static char *argv[] = { "linuxrc", NULL, };
+ extern char * envp_init[];
sys_close(old_fd);sys_close(root_fd);
sys_setsid();
diff --git a/trunk/init/main.c b/trunk/init/main.c
index 94ab488039aa..22d61cb06f98 100644
--- a/trunk/init/main.c
+++ b/trunk/init/main.c
@@ -197,8 +197,8 @@ static int __init set_reset_devices(char *str)
__setup("reset_devices", set_reset_devices);
-static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
+char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static const char *panic_later, *panic_param;
extern const struct obs_kernel_param __setup_start[], __setup_end[];
@@ -809,7 +809,7 @@ static void __init do_pre_smp_initcalls(void)
do_one_initcall(*fn);
}
-static void run_init_process(const char *init_filename)
+static void run_init_process(char *init_filename)
{
argv_init[0] = init_filename;
kernel_execve(init_filename, argv_init, envp_init);
diff --git a/trunk/kernel/debug/kdb/kdb_private.h b/trunk/kernel/debug/kdb/kdb_private.h
index be775f7e81e0..c438f545a321 100644
--- a/trunk/kernel/debug/kdb/kdb_private.h
+++ b/trunk/kernel/debug/kdb/kdb_private.h
@@ -255,14 +255,7 @@ extern void kdb_ps1(const struct task_struct *p);
extern void kdb_print_nameval(const char *name, unsigned long val);
extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);
extern void kdb_meminfo_proc_show(void);
-#ifdef CONFIG_KALLSYMS
extern const char *kdb_walk_kallsyms(loff_t *pos);
-#else /* ! CONFIG_KALLSYMS */
-static inline const char *kdb_walk_kallsyms(loff_t *pos)
-{
- return NULL;
-}
-#endif /* ! CONFIG_KALLSYMS */
extern char *kdb_getstr(char *, size_t, char *);
/* Defines for kdb_symbol_print */
diff --git a/trunk/kernel/debug/kdb/kdb_support.c b/trunk/kernel/debug/kdb/kdb_support.c
index 6b2485dcb050..45344d5c53dd 100644
--- a/trunk/kernel/debug/kdb/kdb_support.c
+++ b/trunk/kernel/debug/kdb/kdb_support.c
@@ -82,8 +82,8 @@ static char *kdb_name_table[100]; /* arbitrary size */
int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
{
int ret = 0;
- unsigned long symbolsize = 0;
- unsigned long offset = 0;
+ unsigned long symbolsize;
+ unsigned long offset;
#define knt1_size 128 /* must be >= kallsyms table size */
char *knt1 = NULL;
diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c
index 03120229db28..671ed56e0a49 100644
--- a/trunk/kernel/exit.c
+++ b/trunk/kernel/exit.c
@@ -1386,7 +1386,8 @@ static int wait_task_stopped(struct wait_opts *wo,
if (!unlikely(wo->wo_flags & WNOWAIT))
*p_code = 0;
- uid = task_uid(p);
+ /* don't need the RCU readlock here as we're holding a spinlock */
+ uid = __task_cred(p)->uid;
unlock_sig:
spin_unlock_irq(&p->sighand->siglock);
if (!exit_code)
@@ -1459,7 +1460,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
}
if (!unlikely(wo->wo_flags & WNOWAIT))
p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
- uid = task_uid(p);
+ uid = __task_cred(p)->uid;
spin_unlock_irq(&p->sighand->siglock);
pid = task_pid_vnr(p);
diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c
index b7e9d60a675d..98b450876f93 100644
--- a/trunk/kernel/fork.c
+++ b/trunk/kernel/fork.c
@@ -300,7 +300,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
#ifdef CONFIG_MMU
static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
- struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
+ struct vm_area_struct *mpnt, *tmp, **pprev;
struct rb_node **rb_link, *rb_parent;
int retval;
unsigned long charge;
@@ -328,7 +328,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
if (retval)
goto out;
- prev = NULL;
for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
struct file *file;
@@ -360,7 +359,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
goto fail_nomem_anon_vma_fork;
tmp->vm_flags &= ~VM_LOCKED;
tmp->vm_mm = mm;
- tmp->vm_next = tmp->vm_prev = NULL;
+ tmp->vm_next = NULL;
file = tmp->vm_file;
if (file) {
struct inode *inode = file->f_path.dentry->d_inode;
@@ -393,8 +392,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
*/
*pprev = tmp;
pprev = &tmp->vm_next;
- tmp->vm_prev = prev;
- prev = tmp;
__vma_link_rb(mm, tmp, rb_link, rb_parent);
rb_link = &tmp->vm_rb.rb_right;
@@ -755,13 +752,13 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
struct fs_struct *fs = current->fs;
if (clone_flags & CLONE_FS) {
/* tsk->fs is already what we want */
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
if (fs->in_exec) {
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
return -EAGAIN;
}
fs->users++;
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
return 0;
}
tsk->fs = copy_fs_struct(fs);
@@ -1679,13 +1676,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
if (new_fs) {
fs = current->fs;
- spin_lock(&fs->lock);
+ write_lock(&fs->lock);
current->fs = new_fs;
if (--fs->users)
new_fs = NULL;
else
new_fs = fs;
- spin_unlock(&fs->lock);
+ write_unlock(&fs->lock);
}
if (new_mm) {
diff --git a/trunk/kernel/kfifo.c b/trunk/kernel/kfifo.c
index 6b5580c57644..4502604ecadf 100644
--- a/trunk/kernel/kfifo.c
+++ b/trunk/kernel/kfifo.c
@@ -503,15 +503,6 @@ unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf,
}
EXPORT_SYMBOL(__kfifo_out_r);
-void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize)
-{
- unsigned int n;
-
- n = __kfifo_peek_n(fifo, recsize);
- fifo->out += n + recsize;
-}
-EXPORT_SYMBOL(__kfifo_skip_r);
-
int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from,
unsigned long len, unsigned int *copied, size_t recsize)
{
diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c
index 9cd0591c96a2..6e9b19667a8d 100644
--- a/trunk/kernel/kmod.c
+++ b/trunk/kernel/kmod.c
@@ -153,9 +153,7 @@ static int ____call_usermodehelper(void *data)
goto fail;
}
- retval = kernel_execve(sub_info->path,
- (const char *const *)sub_info->argv,
- (const char *const *)sub_info->envp);
+ retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);
/* Exec failed? */
fail:
diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c
index 19cccc3c3028..3632ce87674f 100644
--- a/trunk/kernel/trace/ring_buffer.c
+++ b/trunk/kernel/trace/ring_buffer.c
@@ -3846,9 +3846,6 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
rpos = reader->read;
pos += size;
- if (rpos >= commit)
- break;
-
event = rb_reader_event(cpu_buffer);
size = rb_event_length(event);
} while (len > size);
diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c
index 9ec59f541156..ba14a22be4cc 100644
--- a/trunk/kernel/trace/trace.c
+++ b/trunk/kernel/trace/trace.c
@@ -3463,7 +3463,6 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
{
char *buf;
- size_t written;
if (tracing_disabled)
return -EINVAL;
@@ -3485,15 +3484,11 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
} else
buf[cnt] = '\0';
- written = mark_printk("%s", buf);
+ cnt = mark_printk("%s", buf);
kfree(buf);
- *fpos += written;
-
- /* don't tell userspace we wrote more - it might confuse them */
- if (written > cnt)
- written = cnt;
+ *fpos += cnt;
- return written;
+ return cnt;
}
static int tracing_clock_show(struct seq_file *m, void *v)
diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c
index 4c758f146328..09b4fa6e4d3b 100644
--- a/trunk/kernel/trace/trace_events.c
+++ b/trunk/kernel/trace/trace_events.c
@@ -598,165 +598,88 @@ system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
return ret;
}
-enum {
- FORMAT_HEADER = 1,
- FORMAT_PRINTFMT = 2,
-};
-
-static void *f_next(struct seq_file *m, void *v, loff_t *pos)
+static void print_event_fields(struct trace_seq *s, struct list_head *head)
{
- struct ftrace_event_call *call = m->private;
struct ftrace_event_field *field;
- struct list_head *head;
-
- (*pos)++;
-
- switch ((unsigned long)v) {
- case FORMAT_HEADER:
- head = &ftrace_common_fields;
-
- if (unlikely(list_empty(head)))
- return NULL;
-
- field = list_entry(head->prev, struct ftrace_event_field, link);
- return field;
-
- case FORMAT_PRINTFMT:
- /* all done */
- return NULL;
- }
- head = trace_get_fields(call);
+ list_for_each_entry_reverse(field, head, link) {
+ /*
+ * Smartly shows the array type(except dynamic array).
+ * Normal:
+ * field:TYPE VAR
+ * If TYPE := TYPE[LEN], it is shown:
+ * field:TYPE VAR[LEN]
+ */
+ const char *array_descriptor = strchr(field->type, '[');
- /*
- * To separate common fields from event fields, the
- * LSB is set on the first event field. Clear it in case.
- */
- v = (void *)((unsigned long)v & ~1L);
+ if (!strncmp(field->type, "__data_loc", 10))
+ array_descriptor = NULL;
- field = v;
- /*
- * If this is a common field, and at the end of the list, then
- * continue with main list.
- */
- if (field->link.prev == &ftrace_common_fields) {
- if (unlikely(list_empty(head)))
- return NULL;
- field = list_entry(head->prev, struct ftrace_event_field, link);
- /* Set the LSB to notify f_show to print an extra newline */
- field = (struct ftrace_event_field *)
- ((unsigned long)field | 1);
- return field;
+ if (!array_descriptor) {
+ trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
+ "\tsize:%u;\tsigned:%d;\n",
+ field->type, field->name, field->offset,
+ field->size, !!field->is_signed);
+ } else {
+ trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
+ "\tsize:%u;\tsigned:%d;\n",
+ (int)(array_descriptor - field->type),
+ field->type, field->name,
+ array_descriptor, field->offset,
+ field->size, !!field->is_signed);
+ }
}
-
- /* If we are done tell f_show to print the format */
- if (field->link.prev == head)
- return (void *)FORMAT_PRINTFMT;
-
- field = list_entry(field->link.prev, struct ftrace_event_field, link);
-
- return field;
-}
-
-static void *f_start(struct seq_file *m, loff_t *pos)
-{
- loff_t l = 0;
- void *p;
-
- /* Start by showing the header */
- if (!*pos)
- return (void *)FORMAT_HEADER;
-
- p = (void *)FORMAT_HEADER;
- do {
- p = f_next(m, p, &l);
- } while (p && l < *pos);
-
- return p;
}
-static int f_show(struct seq_file *m, void *v)
+static ssize_t
+event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
{
- struct ftrace_event_call *call = m->private;
- struct ftrace_event_field *field;
- const char *array_descriptor;
-
- switch ((unsigned long)v) {
- case FORMAT_HEADER:
- seq_printf(m, "name: %s\n", call->name);
- seq_printf(m, "ID: %d\n", call->event.type);
- seq_printf(m, "format:\n");
- return 0;
+ struct ftrace_event_call *call = filp->private_data;
+ struct list_head *head;
+ struct trace_seq *s;
+ char *buf;
+ int r;
- case FORMAT_PRINTFMT:
- seq_printf(m, "\nprint fmt: %s\n",
- call->print_fmt);
+ if (*ppos)
return 0;
- }
-
- /*
- * To separate common fields from event fields, the
- * LSB is set on the first event field. Clear it and
- * print a newline if it is set.
- */
- if ((unsigned long)v & 1) {
- seq_putc(m, '\n');
- v = (void *)((unsigned long)v & ~1L);
- }
-
- field = v;
-
- /*
- * Smartly shows the array type(except dynamic array).
- * Normal:
- * field:TYPE VAR
- * If TYPE := TYPE[LEN], it is shown:
- * field:TYPE VAR[LEN]
- */
- array_descriptor = strchr(field->type, '[');
- if (!strncmp(field->type, "__data_loc", 10))
- array_descriptor = NULL;
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
- if (!array_descriptor)
- seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
- field->type, field->name, field->offset,
- field->size, !!field->is_signed);
- else
- seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
- (int)(array_descriptor - field->type),
- field->type, field->name,
- array_descriptor, field->offset,
- field->size, !!field->is_signed);
+ trace_seq_init(s);
- return 0;
-}
+ trace_seq_printf(s, "name: %s\n", call->name);
+ trace_seq_printf(s, "ID: %d\n", call->event.type);
+ trace_seq_printf(s, "format:\n");
-static void f_stop(struct seq_file *m, void *p)
-{
-}
+ /* print common fields */
+ print_event_fields(s, &ftrace_common_fields);
-static const struct seq_operations trace_format_seq_ops = {
- .start = f_start,
- .next = f_next,
- .stop = f_stop,
- .show = f_show,
-};
+ trace_seq_putc(s, '\n');
-static int trace_format_open(struct inode *inode, struct file *file)
-{
- struct ftrace_event_call *call = inode->i_private;
- struct seq_file *m;
- int ret;
+ /* print event specific fields */
+ head = trace_get_fields(call);
+ print_event_fields(s, head);
- ret = seq_open(file, &trace_format_seq_ops);
- if (ret < 0)
- return ret;
+ r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt);
- m = file->private_data;
- m->private = call;
+ if (!r) {
+ /*
+ * ug! The format output is bigger than a PAGE!!
+ */
+ buf = "FORMAT TOO BIG\n";
+ r = simple_read_from_buffer(ubuf, cnt, ppos,
+ buf, strlen(buf));
+ goto out;
+ }
- return 0;
+ r = simple_read_from_buffer(ubuf, cnt, ppos,
+ s->buffer, s->len);
+ out:
+ kfree(s);
+ return r;
}
static ssize_t
@@ -954,10 +877,8 @@ static const struct file_operations ftrace_enable_fops = {
};
static const struct file_operations ftrace_event_format_fops = {
- .open = trace_format_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
+ .open = tracing_open_generic,
+ .read = event_format_read,
};
static const struct file_operations ftrace_event_id_fops = {
diff --git a/trunk/kernel/trace/trace_functions_graph.c b/trunk/kernel/trace/trace_functions_graph.c
index 6f233698518e..6bff23625781 100644
--- a/trunk/kernel/trace/trace_functions_graph.c
+++ b/trunk/kernel/trace/trace_functions_graph.c
@@ -507,15 +507,7 @@ get_return_for_leaf(struct trace_iterator *iter,
* if the output fails.
*/
data->ent = *curr;
- /*
- * If the next event is not a return type, then
- * we only care about what type it is. Otherwise we can
- * safely copy the entire event.
- */
- if (next->ent.type == TRACE_GRAPH_RET)
- data->ret = *next;
- else
- data->ret.ent.type = next->ent.type;
+ data->ret = *next;
}
}
diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c
index 8bd600c020e5..2994a0e3a61c 100644
--- a/trunk/kernel/workqueue.c
+++ b/trunk/kernel/workqueue.c
@@ -35,9 +35,6 @@
#include
#include
-#define CREATE_TRACE_POINTS
-#include
-
#include "workqueue_sched.h"
enum {
@@ -1793,13 +1790,7 @@ static void process_one_work(struct worker *worker, struct work_struct *work)
work_clear_pending(work);
lock_map_acquire(&cwq->wq->lockdep_map);
lock_map_acquire(&lockdep_map);
- trace_workqueue_execute_start(work);
f(work);
- /*
- * While we must be careful to not use "work" after this, the trace
- * point will only record its address.
- */
- trace_workqueue_execute_end(work);
lock_map_release(&lockdep_map);
lock_map_release(&cwq->wq->lockdep_map);
diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug
index 1b4afd2e6ca0..9e06b7f5ecf1 100644
--- a/trunk/lib/Kconfig.debug
+++ b/trunk/lib/Kconfig.debug
@@ -994,16 +994,13 @@ config FAULT_INJECTION_STACKTRACE_FILTER
config LATENCYTOP
bool "Latency measuring infrastructure"
- depends on HAVE_LATENCYTOP_SUPPORT
- depends on DEBUG_KERNEL
- depends on STACKTRACE_SUPPORT
- depends on PROC_FS
select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE
select KALLSYMS
select KALLSYMS_ALL
select STACKTRACE
select SCHEDSTATS
select SCHED_DEBUG
+ depends on HAVE_LATENCYTOP_SUPPORT
help
Enable this option if you want to use the LatencyTOP tool
to find out which userspace is blocking on what kernel operations.
diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c
index 5b7d4623f0b7..1014171dd1c5 100644
--- a/trunk/lib/radix-tree.c
+++ b/trunk/lib/radix-tree.c
@@ -174,14 +174,16 @@ static void radix_tree_node_rcu_free(struct rcu_head *head)
{
struct radix_tree_node *node =
container_of(head, struct radix_tree_node, rcu_head);
+ int i;
/*
* must only free zeroed nodes into the slab. radix_tree_shrink
* can leave us with a non-NULL entry in the first slot, so clear
* that here to make sure.
*/
- tag_clear(node, 0, 0);
- tag_clear(node, 1, 0);
+ for (i = 0; i < RADIX_TREE_MAX_TAGS; i++)
+ tag_clear(node, i, 0);
+
node->slots[0] = NULL;
node->count = 0;
@@ -625,8 +627,6 @@ EXPORT_SYMBOL(radix_tree_tag_get);
*
* The function returns number of leaves where the tag was set and sets
* *first_indexp to the first unscanned index.
- * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must
- * be prepared to handle that.
*/
unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
unsigned long *first_indexp, unsigned long last_index,
@@ -677,8 +677,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
next:
/* Go to next item at level determined by 'shift' */
index = ((index >> shift) + 1) << shift;
- /* Overflow can happen when last_index is ~0UL... */
- if (index > last_index || !index)
+ if (index > last_index)
break;
if (tagged >= nr_to_tag)
break;
diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c
index 2ed2267439df..b6e5fd23cc5a 100644
--- a/trunk/mm/memory.c
+++ b/trunk/mm/memory.c
@@ -2770,18 +2770,11 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
{
address &= PAGE_MASK;
if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
- struct vm_area_struct *prev = vma->vm_prev;
-
- /*
- * Is there a mapping abutting this one below?
- *
- * That's only ok if it's the same stack mapping
- * that has gotten split..
- */
- if (prev && prev->vm_end == address)
- return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
+ address -= PAGE_SIZE;
+ if (find_vma(vma->vm_mm, address) != vma)
+ return -ENOMEM;
- expand_stack(vma, address - PAGE_SIZE);
+ expand_stack(vma, address);
}
return 0;
}
diff --git a/trunk/mm/mlock.c b/trunk/mm/mlock.c
index cbae7c5b9568..49e5e4cb8232 100644
--- a/trunk/mm/mlock.c
+++ b/trunk/mm/mlock.c
@@ -135,19 +135,6 @@ void munlock_vma_page(struct page *page)
}
}
-/* Is the vma a continuation of the stack vma above it? */
-static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr)
-{
- return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
-}
-
-static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
-{
- return (vma->vm_flags & VM_GROWSDOWN) &&
- (vma->vm_start == addr) &&
- !vma_stack_continue(vma->vm_prev, addr);
-}
-
/**
* __mlock_vma_pages_range() - mlock a range of pages in the vma.
* @vma: target vma
@@ -181,9 +168,11 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
gup_flags |= FOLL_WRITE;
/* We don't try to access the guard page of a stack vma */
- if (stack_guard_page(vma, start)) {
- addr += PAGE_SIZE;
- nr_pages--;
+ if (vma->vm_flags & VM_GROWSDOWN) {
+ if (start == vma->vm_start) {
+ start += PAGE_SIZE;
+ nr_pages--;
+ }
}
while (nr_pages > 0) {
diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c
index 331e51af38c9..31003338b978 100644
--- a/trunk/mm/mmap.c
+++ b/trunk/mm/mmap.c
@@ -388,23 +388,17 @@ static inline void
__vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
struct vm_area_struct *prev, struct rb_node *rb_parent)
{
- struct vm_area_struct *next;
-
- vma->vm_prev = prev;
if (prev) {
- next = prev->vm_next;
+ vma->vm_next = prev->vm_next;
prev->vm_next = vma;
} else {
mm->mmap = vma;
if (rb_parent)
- next = rb_entry(rb_parent,
+ vma->vm_next = rb_entry(rb_parent,
struct vm_area_struct, vm_rb);
else
- next = NULL;
+ vma->vm_next = NULL;
}
- vma->vm_next = next;
- if (next)
- next->vm_prev = vma;
}
void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -489,11 +483,7 @@ static inline void
__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
struct vm_area_struct *prev)
{
- struct vm_area_struct *next = vma->vm_next;
-
- prev->vm_next = next;
- if (next)
- next->vm_prev = prev;
+ prev->vm_next = vma->vm_next;
rb_erase(&vma->vm_rb, &mm->mm_rb);
if (mm->mmap_cache == vma)
mm->mmap_cache = prev;
@@ -1925,7 +1915,6 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr;
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
- vma->vm_prev = NULL;
do {
rb_erase(&vma->vm_rb, &mm->mm_rb);
mm->map_count--;
@@ -1933,8 +1922,6 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
vma = vma->vm_next;
} while (vma && vma->vm_start < end);
*insertion_point = vma;
- if (vma)
- vma->vm_prev = prev;
tail_vma->vm_next = NULL;
if (mm->unmap_area == arch_unmap_area)
addr = prev ? prev->vm_end : mm->mmap_base;
diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c
index 88ff091eb07a..efa9a380335e 100644
--- a/trunk/mm/nommu.c
+++ b/trunk/mm/nommu.c
@@ -604,7 +604,7 @@ static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
*/
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
{
- struct vm_area_struct *pvma, **pp, *next;
+ struct vm_area_struct *pvma, **pp;
struct address_space *mapping;
struct rb_node **p, *parent;
@@ -664,11 +664,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
break;
}
- next = *pp;
+ vma->vm_next = *pp;
*pp = vma;
- vma->vm_next = next;
- if (next)
- next->vm_prev = vma;
}
/*
diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c
index fc81cb22869e..5014e50644d1 100644
--- a/trunk/mm/oom_kill.c
+++ b/trunk/mm/oom_kill.c
@@ -372,7 +372,7 @@ static void dump_tasks(const struct mem_cgroup *mem)
}
pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n",
- task->pid, task_uid(task), task->tgid,
+ task->pid, __task_cred(task)->uid, task->tgid,
task->mm->total_vm, get_mm_rss(task->mm),
task_cpu(task), task->signal->oom_adj,
task->signal->oom_score_adj, task->comm);
@@ -401,9 +401,10 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
static int oom_kill_task(struct task_struct *p, struct mem_cgroup *mem)
{
p = find_lock_task_mm(p);
- if (!p)
+ if (!p) {
+ task_unlock(p);
return 1;
-
+ }
pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
task_pid_nr(p), p->comm, K(p->mm->total_vm),
K(get_mm_counter(p->mm, MM_ANONPAGES)),
@@ -646,7 +647,6 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
unsigned long freed = 0;
unsigned int points;
enum oom_constraint constraint = CONSTRAINT_NONE;
- int killed = 0;
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
if (freed > 0)
@@ -684,7 +684,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
if (!oom_kill_process(current, gfp_mask, order, 0, totalpages,
NULL, nodemask,
"Out of memory (oom_kill_allocating_task)"))
- goto out;
+ return;
}
retry:
@@ -692,7 +692,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
constraint == CONSTRAINT_MEMORY_POLICY ? nodemask :
NULL);
if (PTR_ERR(p) == -1UL)
- goto out;
+ return;
/* Found nothing?!?! Either we hang forever, or we panic. */
if (!p) {
@@ -704,15 +704,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
if (oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
nodemask, "Out of memory"))
goto retry;
- killed = 1;
-out:
read_unlock(&tasklist_lock);
/*
* Give "p" a good chance of killing itself before we
* retry to allocate memory unless "p" is current
*/
- if (killed && !test_thread_flag(TIF_MEMDIE))
+ if (!test_thread_flag(TIF_MEMDIE))
schedule_timeout_uninterruptible(1);
}
diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c
index c09ef5219cbe..7262aacea8a2 100644
--- a/trunk/mm/page-writeback.c
+++ b/trunk/mm/page-writeback.c
@@ -836,8 +836,7 @@ void tag_pages_for_writeback(struct address_space *mapping,
spin_unlock_irq(&mapping->tree_lock);
WARN_ON_ONCE(tagged > WRITEBACK_TAG_BATCH);
cond_resched();
- /* We check 'start' to handle wrapping when end == ~0UL */
- } while (tagged >= WRITEBACK_TAG_BATCH && start);
+ } while (tagged >= WRITEBACK_TAG_BATCH);
}
EXPORT_SYMBOL(tag_pages_for_writeback);
diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c
index 080b09a57a8f..dfaa0f4e9789 100644
--- a/trunk/mm/shmem.c
+++ b/trunk/mm/shmem.c
@@ -2325,10 +2325,7 @@ static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs)
static void shmem_put_super(struct super_block *sb)
{
- struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-
- percpu_counter_destroy(&sbinfo->used_blocks);
- kfree(sbinfo);
+ kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
}
@@ -2370,8 +2367,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
#endif
spin_lock_init(&sbinfo->stat_lock);
- if (percpu_counter_init(&sbinfo->used_blocks, 0))
- goto failed;
+ percpu_counter_init(&sbinfo->used_blocks, 0);
sbinfo->free_inodes = sbinfo->max_inodes;
sb->s_maxbytes = SHMEM_MAX_BYTES;
diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c
index fcae9815d3b3..88435fcc8387 100644
--- a/trunk/mm/slab.c
+++ b/trunk/mm/slab.c
@@ -2330,8 +2330,8 @@ kmem_cache_create (const char *name, size_t size, size_t align,
}
#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
if (size >= malloc_sizes[INDEX_L3 + 1].cs_size
- && cachep->obj_size > cache_line_size() && ALIGN(size, align) < PAGE_SIZE) {
- cachep->obj_offset += PAGE_SIZE - ALIGN(size, align);
+ && cachep->obj_size > cache_line_size() && size < PAGE_SIZE) {
+ cachep->obj_offset += PAGE_SIZE - size;
size = PAGE_SIZE;
}
#endif
diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c
index 3721fbb9a83c..1ae654391442 100644
--- a/trunk/net/core/dev.c
+++ b/trunk/net/core/dev.c
@@ -3143,7 +3143,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
put_page(skb_shinfo(skb)->frags[0].page);
memmove(skb_shinfo(skb)->frags,
skb_shinfo(skb)->frags + 1,
- --skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
+ --skb_shinfo(skb)->nr_frags);
}
}
diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c
index 51d6c3167975..6bccba31d132 100644
--- a/trunk/net/ipv4/netfilter/arp_tables.c
+++ b/trunk/net/ipv4/netfilter/arp_tables.c
@@ -735,7 +735,6 @@ static void get_counters(const struct xt_table_info *t,
if (cpu == curcpu)
continue;
i = 0;
- local_bh_disable();
xt_info_wrlock(cpu);
xt_entry_foreach(iter, t->entries[cpu], t->size) {
ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -743,7 +742,6 @@ static void get_counters(const struct xt_table_info *t,
++i;
}
xt_info_wrunlock(cpu);
- local_bh_enable();
}
put_cpu();
}
diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c
index 97b64b22c412..c439721b165a 100644
--- a/trunk/net/ipv4/netfilter/ip_tables.c
+++ b/trunk/net/ipv4/netfilter/ip_tables.c
@@ -909,7 +909,6 @@ get_counters(const struct xt_table_info *t,
if (cpu == curcpu)
continue;
i = 0;
- local_bh_disable();
xt_info_wrlock(cpu);
xt_entry_foreach(iter, t->entries[cpu], t->size) {
ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -917,7 +916,6 @@ get_counters(const struct xt_table_info *t,
++i; /* macro does multi eval of i */
}
xt_info_wrunlock(cpu);
- local_bh_enable();
}
put_cpu();
}
diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c
index 29a7bca29e3f..5359ef4daac5 100644
--- a/trunk/net/ipv6/netfilter/ip6_tables.c
+++ b/trunk/net/ipv6/netfilter/ip6_tables.c
@@ -922,7 +922,6 @@ get_counters(const struct xt_table_info *t,
if (cpu == curcpu)
continue;
i = 0;
- local_bh_disable();
xt_info_wrlock(cpu);
xt_entry_foreach(iter, t->entries[cpu], t->size) {
ADD_COUNTER(counters[i], iter->counters.bcnt,
@@ -930,7 +929,6 @@ get_counters(const struct xt_table_info *t,
++i;
}
xt_info_wrunlock(cpu);
- local_bh_enable();
}
put_cpu();
}
diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c
index d126365ac046..8f2d0400cf8a 100644
--- a/trunk/net/ipv6/route.c
+++ b/trunk/net/ipv6/route.c
@@ -2580,7 +2580,7 @@ ctl_table ipv6_route_table_template[] = {
.data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_jiffies,
},
{
.procname = "mtu_expires",
@@ -2594,7 +2594,7 @@ ctl_table ipv6_route_table_template[] = {
.data = &init_net.ipv6.sysctl.ip6_rt_min_advmss,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_jiffies,
},
{
.procname = "gc_min_interval_ms",
diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c
index 8648a9922aab..2cbf380377d5 100644
--- a/trunk/net/netlink/af_netlink.c
+++ b/trunk/net/netlink/af_netlink.c
@@ -1406,7 +1406,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
struct netlink_sock *nlk = nlk_sk(sk);
int noblock = flags&MSG_DONTWAIT;
size_t copied;
- struct sk_buff *skb, *frag __maybe_unused = NULL;
+ struct sk_buff *skb;
int err;
if (flags&MSG_OOB)
@@ -1441,7 +1441,21 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
kfree_skb(skb);
skb = compskb;
} else {
- frag = skb_shinfo(skb)->frag_list;
+ /*
+ * Before setting frag_list to NULL, we must get a
+ * private copy of skb if shared (because of MSG_PEEK)
+ */
+ if (skb_shared(skb)) {
+ struct sk_buff *nskb;
+
+ nskb = pskb_copy(skb, GFP_KERNEL);
+ kfree_skb(skb);
+ skb = nskb;
+ err = -ENOMEM;
+ if (!skb)
+ goto out;
+ }
+ kfree_skb(skb_shinfo(skb)->frag_list);
skb_shinfo(skb)->frag_list = NULL;
}
}
@@ -1478,10 +1492,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
if (flags & MSG_TRUNC)
copied = skb->len;
-#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
- skb_shinfo(skb)->frag_list = frag;
-#endif
-
skb_free_datagram(sk, skb);
if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
diff --git a/trunk/net/sched/act_gact.c b/trunk/net/sched/act_gact.c
index c2ed90a4c0b4..8406c6654990 100644
--- a/trunk/net/sched/act_gact.c
+++ b/trunk/net/sched/act_gact.c
@@ -152,24 +152,21 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result
static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
{
unsigned char *b = skb_tail_pointer(skb);
+ struct tc_gact opt;
struct tcf_gact *gact = a->priv;
- struct tc_gact opt = {
- .index = gact->tcf_index,
- .refcnt = gact->tcf_refcnt - ref,
- .bindcnt = gact->tcf_bindcnt - bind,
- .action = gact->tcf_action,
- };
struct tcf_t t;
+ opt.index = gact->tcf_index;
+ opt.refcnt = gact->tcf_refcnt - ref;
+ opt.bindcnt = gact->tcf_bindcnt - bind;
+ opt.action = gact->tcf_action;
NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
#ifdef CONFIG_GACT_PROB
if (gact->tcfg_ptype) {
- struct tc_gact_p p_opt = {
- .paction = gact->tcfg_paction,
- .pval = gact->tcfg_pval,
- .ptype = gact->tcfg_ptype,
- };
-
+ struct tc_gact_p p_opt;
+ p_opt.paction = gact->tcfg_paction;
+ p_opt.pval = gact->tcfg_pval;
+ p_opt.ptype = gact->tcfg_ptype;
NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
}
#endif
diff --git a/trunk/net/sched/act_mirred.c b/trunk/net/sched/act_mirred.c
index 0c311be92827..11f195af2da0 100644
--- a/trunk/net/sched/act_mirred.c
+++ b/trunk/net/sched/act_mirred.c
@@ -219,16 +219,15 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_mirred *m = a->priv;
- struct tc_mirred opt = {
- .index = m->tcf_index,
- .action = m->tcf_action,
- .refcnt = m->tcf_refcnt - ref,
- .bindcnt = m->tcf_bindcnt - bind,
- .eaction = m->tcfm_eaction,
- .ifindex = m->tcfm_ifindex,
- };
+ struct tc_mirred opt;
struct tcf_t t;
+ opt.index = m->tcf_index;
+ opt.action = m->tcf_action;
+ opt.refcnt = m->tcf_refcnt - ref;
+ opt.bindcnt = m->tcf_bindcnt - bind;
+ opt.eaction = m->tcfm_eaction;
+ opt.ifindex = m->tcfm_ifindex;
NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
diff --git a/trunk/net/sched/act_nat.c b/trunk/net/sched/act_nat.c
index 186eb837e600..509a2d53a99d 100644
--- a/trunk/net/sched/act_nat.c
+++ b/trunk/net/sched/act_nat.c
@@ -272,19 +272,19 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_nat *p = a->priv;
- struct tc_nat opt = {
- .old_addr = p->old_addr,
- .new_addr = p->new_addr,
- .mask = p->mask,
- .flags = p->flags,
-
- .index = p->tcf_index,
- .action = p->tcf_action,
- .refcnt = p->tcf_refcnt - ref,
- .bindcnt = p->tcf_bindcnt - bind,
- };
+ struct tc_nat opt;
struct tcf_t t;
+ opt.old_addr = p->old_addr;
+ opt.new_addr = p->new_addr;
+ opt.mask = p->mask;
+ opt.flags = p->flags;
+
+ opt.index = p->tcf_index;
+ opt.action = p->tcf_action;
+ opt.refcnt = p->tcf_refcnt - ref;
+ opt.bindcnt = p->tcf_bindcnt - bind;
+
NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
diff --git a/trunk/net/sched/act_simple.c b/trunk/net/sched/act_simple.c
index 97e84f3ee775..4a1d640b0cf1 100644
--- a/trunk/net/sched/act_simple.c
+++ b/trunk/net/sched/act_simple.c
@@ -164,14 +164,13 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_defact *d = a->priv;
- struct tc_defact opt = {
- .index = d->tcf_index,
- .refcnt = d->tcf_refcnt - ref,
- .bindcnt = d->tcf_bindcnt - bind,
- .action = d->tcf_action,
- };
+ struct tc_defact opt;
struct tcf_t t;
+ opt.index = d->tcf_index;
+ opt.refcnt = d->tcf_refcnt - ref;
+ opt.bindcnt = d->tcf_bindcnt - bind;
+ opt.action = d->tcf_action;
NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
diff --git a/trunk/net/sched/act_skbedit.c b/trunk/net/sched/act_skbedit.c
index 66cbf4eb8855..e9607fe55b58 100644
--- a/trunk/net/sched/act_skbedit.c
+++ b/trunk/net/sched/act_skbedit.c
@@ -159,14 +159,13 @@ static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
{
unsigned char *b = skb_tail_pointer(skb);
struct tcf_skbedit *d = a->priv;
- struct tc_skbedit opt = {
- .index = d->tcf_index,
- .refcnt = d->tcf_refcnt - ref,
- .bindcnt = d->tcf_bindcnt - bind,
- .action = d->tcf_action,
- };
+ struct tc_skbedit opt;
struct tcf_t t;
+ opt.index = d->tcf_index;
+ opt.refcnt = d->tcf_refcnt - ref;
+ opt.bindcnt = d->tcf_bindcnt - bind;
+ opt.action = d->tcf_action;
NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
if (d->flags & SKBEDIT_F_PRIORITY)
NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
diff --git a/trunk/net/sunrpc/Kconfig b/trunk/net/sunrpc/Kconfig
index 3376d7657185..443c161eb8bd 100644
--- a/trunk/net/sunrpc/Kconfig
+++ b/trunk/net/sunrpc/Kconfig
@@ -18,11 +18,10 @@ config SUNRPC_XPRT_RDMA
If unsure, say N.
config RPCSEC_GSS_KRB5
- tristate
- depends on SUNRPC && CRYPTO
- prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4)
- default y
+ tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
+ depends on SUNRPC && EXPERIMENTAL
select SUNRPC_GSS
+ select CRYPTO
select CRYPTO_MD5
select CRYPTO_DES
select CRYPTO_CBC
@@ -35,7 +34,7 @@ config RPCSEC_GSS_KRB5
available from http://linux-nfs.org/. In addition, user-space
Kerberos support should be installed.
- If unsure, say Y.
+ If unsure, say N.
config RPCSEC_GSS_SPKM3
tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
diff --git a/trunk/net/sunrpc/xprtrdma/rpc_rdma.c b/trunk/net/sunrpc/xprtrdma/rpc_rdma.c
index 2ac3f6e8adff..e5e28d1946a4 100644
--- a/trunk/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/trunk/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -249,8 +249,6 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
req->rl_nchunks = nchunks;
BUG_ON(nchunks == 0);
- BUG_ON((r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
- && (nchunks > 3));
/*
* finish off header. If write, marshal discrim and nchunks.
diff --git a/trunk/net/sunrpc/xprtrdma/verbs.c b/trunk/net/sunrpc/xprtrdma/verbs.c
index 5f4c7b3bc711..27015c6d8eb5 100644
--- a/trunk/net/sunrpc/xprtrdma/verbs.c
+++ b/trunk/net/sunrpc/xprtrdma/verbs.c
@@ -650,22 +650,10 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
ep->rep_attr.cap.max_send_wr = cdata->max_requests;
switch (ia->ri_memreg_strategy) {
case RPCRDMA_FRMR:
- /* Add room for frmr register and invalidate WRs.
- * 1. FRMR reg WR for head
- * 2. FRMR invalidate WR for head
- * 3. FRMR reg WR for pagelist
- * 4. FRMR invalidate WR for pagelist
- * 5. FRMR reg WR for tail
- * 6. FRMR invalidate WR for tail
- * 7. The RDMA_SEND WR
- */
- ep->rep_attr.cap.max_send_wr *= 7;
- if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) {
- cdata->max_requests = devattr.max_qp_wr / 7;
- if (!cdata->max_requests)
- return -EINVAL;
- ep->rep_attr.cap.max_send_wr = cdata->max_requests * 7;
- }
+ /* Add room for frmr register and invalidate WRs */
+ ep->rep_attr.cap.max_send_wr *= 3;
+ if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
+ return -EINVAL;
break;
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
@@ -1502,7 +1490,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
memset(&frmr_wr, 0, sizeof frmr_wr);
frmr_wr.opcode = IB_WR_FAST_REG_MR;
frmr_wr.send_flags = 0; /* unsignaled */
- frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
+ frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma;
frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
frmr_wr.wr.fast_reg.page_list_len = i;
frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c
index b6309db56226..49a62f0c4b87 100644
--- a/trunk/net/sunrpc/xprtsock.c
+++ b/trunk/net/sunrpc/xprtsock.c
@@ -1305,11 +1305,10 @@ static void xs_tcp_state_change(struct sock *sk)
if (!(xprt = xprt_from_sock(sk)))
goto out;
dprintk("RPC: xs_tcp_state_change client %p...\n", xprt);
- dprintk("RPC: state %x conn %d dead %d zapped %d sk_shutdown %d\n",
+ dprintk("RPC: state %x conn %d dead %d zapped %d\n",
sk->sk_state, xprt_connected(xprt),
sock_flag(sk, SOCK_DEAD),
- sock_flag(sk, SOCK_ZAPPED),
- sk->sk_shutdown);
+ sock_flag(sk, SOCK_ZAPPED));
switch (sk->sk_state) {
case TCP_ESTABLISHED:
@@ -1780,25 +1779,10 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra
{
unsigned int state = transport->inet->sk_state;
- if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) {
- /* we don't need to abort the connection if the socket
- * hasn't undergone a shutdown
- */
- if (transport->inet->sk_shutdown == 0)
- return;
- dprintk("RPC: %s: TCP_CLOSEd and sk_shutdown set to %d\n",
- __func__, transport->inet->sk_shutdown);
- }
- if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) {
- /* we don't need to abort the connection if the socket
- * hasn't undergone a shutdown
- */
- if (transport->inet->sk_shutdown == 0)
- return;
- dprintk("RPC: %s: ESTABLISHED/SYN_SENT "
- "sk_shutdown set to %d\n",
- __func__, transport->inet->sk_shutdown);
- }
+ if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
+ return;
+ if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
+ return;
xs_abort_connection(xprt, transport);
}
diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c
index b14ed4b1f27c..ba59983aaffe 100644
--- a/trunk/net/xfrm/xfrm_user.c
+++ b/trunk/net/xfrm/xfrm_user.c
@@ -2504,7 +2504,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
if (p->dir > XFRM_POLICY_OUT)
return NULL;
- xp = xfrm_policy_alloc(net, GFP_ATOMIC);
+ xp = xfrm_policy_alloc(net, GFP_KERNEL);
if (xp == NULL) {
*dir = -ENOBUFS;
return NULL;
diff --git a/trunk/samples/kfifo/bytestream-example.c b/trunk/samples/kfifo/bytestream-example.c
index 178061e87ffe..642eef3f6336 100644
--- a/trunk/samples/kfifo/bytestream-example.c
+++ b/trunk/samples/kfifo/bytestream-example.c
@@ -44,17 +44,10 @@ static struct kfifo test;
static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
#endif
-static const unsigned char expected_result[FIFO_SIZE] = {
- 3, 4, 5, 6, 7, 8, 9, 0,
- 1, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42,
-};
-
static int __init testfunc(void)
{
unsigned char buf[6];
- unsigned char i, j;
+ unsigned char i;
unsigned int ret;
printk(KERN_INFO "byte stream fifo test start\n");
@@ -80,34 +73,16 @@ static int __init testfunc(void)
ret = kfifo_in(&test, buf, ret);
printk(KERN_INFO "ret: %d\n", ret);
- /* skip first element of the fifo */
- printk(KERN_INFO "skip 1st element\n");
- kfifo_skip(&test);
-
/* put values into the fifo until is full */
for (i = 20; kfifo_put(&test, &i); i++)
;
printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
- /* show the first value without removing from the fifo */
- if (kfifo_peek(&test, &i))
- printk(KERN_INFO "%d\n", i);
-
- /* check the correctness of all values in the fifo */
- j = 0;
- while (kfifo_get(&test, &i)) {
- printk(KERN_INFO "item = %d\n", i);
- if (i != expected_result[j++]) {
- printk(KERN_WARNING "value mismatch: test failed\n");
- return -EIO;
- }
- }
- if (j != ARRAY_SIZE(expected_result)) {
- printk(KERN_WARNING "size mismatch: test failed\n");
- return -EIO;
- }
- printk(KERN_INFO "test passed\n");
+ /* print out all values in the fifo */
+ while (kfifo_get(&test, &i))
+ printk("%d ", i);
+ printk("\n");
return 0;
}
@@ -163,12 +138,7 @@ static int __init example_init(void)
#else
INIT_KFIFO(test);
#endif
- if (testfunc() < 0) {
-#ifdef DYNAMIC
- kfifo_free(&test);
-#endif
- return -EIO;
- }
+ testfunc();
if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
#ifdef DYNAMIC
diff --git a/trunk/samples/kfifo/dma-example.c b/trunk/samples/kfifo/dma-example.c
index ee03a4f0b64f..b9482c28b41a 100644
--- a/trunk/samples/kfifo/dma-example.c
+++ b/trunk/samples/kfifo/dma-example.c
@@ -29,8 +29,8 @@ static int __init example_init(void)
printk(KERN_INFO "DMA fifo test start\n");
if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
- printk(KERN_WARNING "error kfifo_alloc\n");
- return -ENOMEM;
+ printk(KERN_ERR "error kfifo_alloc\n");
+ return 1;
}
printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo));
@@ -41,99 +41,72 @@ static int __init example_init(void)
kfifo_put(&fifo, &i);
/* kick away first byte */
- kfifo_skip(&fifo);
+ ret = kfifo_get(&fifo, &i);
printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));
- /*
- * Configure the kfifo buffer to receive data from DMA input.
- *
- * .--------------------------------------.
- * | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 |
- * |---|------------------|---------------|
- * \_/ \________________/ \_____________/
- * \ \ \
- * \ \_allocated data \
- * \_*free space* \_*free space*
- *
- * We need two different SG entries: one for the free space area at the
- * end of the kfifo buffer (19 bytes) and another for the first free
- * byte at the beginning, after the kfifo_skip().
- */
- sg_init_table(sg, ARRAY_SIZE(sg));
ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE);
printk(KERN_INFO "DMA sgl entries: %d\n", ret);
- if (!ret) {
- /* fifo is full and no sgl was created */
- printk(KERN_WARNING "error kfifo_dma_in_prepare\n");
- return -EIO;
- }
- /* receive data */
- printk(KERN_INFO "scatterlist for receive:\n");
- for (i = 0; i < ARRAY_SIZE(sg); i++) {
- printk(KERN_INFO
- "sg[%d] -> "
- "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
- i, sg[i].page_link, sg[i].offset, sg[i].length);
+ /* if 0 was returned, fifo is full and no sgl was created */
+ if (ret) {
+ printk(KERN_INFO "scatterlist for receive:\n");
+ for (i = 0; i < ARRAY_SIZE(sg); i++) {
+ printk(KERN_INFO
+ "sg[%d] -> "
+ "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
+ i, sg[i].page_link, sg[i].offset, sg[i].length);
- if (sg_is_last(&sg[i]))
- break;
- }
+ if (sg_is_last(&sg[i]))
+ break;
+ }
- /* put here your code to setup and exectute the dma operation */
- /* ... */
+ /* but here your code to setup and exectute the dma operation */
+ /* ... */
- /* example: zero bytes received */
- ret = 0;
+ /* example: zero bytes received */
+ ret = 0;
- /* finish the dma operation and update the received data */
- kfifo_dma_in_finish(&fifo, ret);
+ /* finish the dma operation and update the received data */
+ kfifo_dma_in_finish(&fifo, ret);
+ }
- /* Prepare to transmit data, example: 8 bytes */
ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8);
printk(KERN_INFO "DMA sgl entries: %d\n", ret);
- if (!ret) {
- /* no data was available and no sgl was created */
- printk(KERN_WARNING "error kfifo_dma_out_prepare\n");
- return -EIO;
- }
- printk(KERN_INFO "scatterlist for transmit:\n");
- for (i = 0; i < ARRAY_SIZE(sg); i++) {
- printk(KERN_INFO
- "sg[%d] -> "
- "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
- i, sg[i].page_link, sg[i].offset, sg[i].length);
+ /* if 0 was returned, no data was available and no sgl was created */
+ if (ret) {
+ printk(KERN_INFO "scatterlist for transmit:\n");
+ for (i = 0; i < ARRAY_SIZE(sg); i++) {
+ printk(KERN_INFO
+ "sg[%d] -> "
+ "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n",
+ i, sg[i].page_link, sg[i].offset, sg[i].length);
- if (sg_is_last(&sg[i]))
- break;
- }
+ if (sg_is_last(&sg[i]))
+ break;
+ }
- /* put here your code to setup and exectute the dma operation */
- /* ... */
+ /* but here your code to setup and exectute the dma operation */
+ /* ... */
- /* example: 5 bytes transmitted */
- ret = 5;
+ /* example: 5 bytes transmitted */
+ ret = 5;
- /* finish the dma operation and update the transmitted data */
- kfifo_dma_out_finish(&fifo, ret);
+ /* finish the dma operation and update the transmitted data */
+ kfifo_dma_out_finish(&fifo, ret);
+ }
- ret = kfifo_len(&fifo);
printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo));
- if (ret != 7) {
- printk(KERN_WARNING "size mismatch: test failed");
- return -EIO;
- }
- printk(KERN_INFO "test passed\n");
-
return 0;
}
static void __exit example_exit(void)
{
- kfifo_free(&fifo);
+#ifdef DYNAMIC
+ kfifo_free(&test);
+#endif
}
module_init(example_init);
diff --git a/trunk/samples/kfifo/inttype-example.c b/trunk/samples/kfifo/inttype-example.c
index 71b2aabca96a..d6c5b7d9df64 100644
--- a/trunk/samples/kfifo/inttype-example.c
+++ b/trunk/samples/kfifo/inttype-example.c
@@ -44,17 +44,10 @@ static DECLARE_KFIFO_PTR(test, int);
static DEFINE_KFIFO(test, int, FIFO_SIZE);
#endif
-static const int expected_result[FIFO_SIZE] = {
- 3, 4, 5, 6, 7, 8, 9, 0,
- 1, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42,
-};
-
static int __init testfunc(void)
{
int buf[6];
- int i, j;
+ int i;
unsigned int ret;
printk(KERN_INFO "int fifo test start\n");
@@ -73,13 +66,8 @@ static int __init testfunc(void)
ret = kfifo_in(&test, buf, ret);
printk(KERN_INFO "ret: %d\n", ret);
- /* skip first element of the fifo */
- printk(KERN_INFO "skip 1st element\n");
- kfifo_skip(&test);
-
- /* put values into the fifo until is full */
- for (i = 20; kfifo_put(&test, &i); i++)
- ;
+ for (i = 20; i != 30; i++)
+ kfifo_put(&test, &i);
printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
@@ -87,20 +75,10 @@ static int __init testfunc(void)
if (kfifo_peek(&test, &i))
printk(KERN_INFO "%d\n", i);
- /* check the correctness of all values in the fifo */
- j = 0;
- while (kfifo_get(&test, &i)) {
- printk(KERN_INFO "item = %d\n", i);
- if (i != expected_result[j++]) {
- printk(KERN_WARNING "value mismatch: test failed\n");
- return -EIO;
- }
- }
- if (j != ARRAY_SIZE(expected_result)) {
- printk(KERN_WARNING "size mismatch: test failed\n");
- return -EIO;
- }
- printk(KERN_INFO "test passed\n");
+ /* print out all values in the fifo */
+ while (kfifo_get(&test, &i))
+ printk("%d ", i);
+ printk("\n");
return 0;
}
@@ -154,12 +132,7 @@ static int __init example_init(void)
return ret;
}
#endif
- if (testfunc() < 0) {
-#ifdef DYNAMIC
- kfifo_free(&test);
-#endif
- return -EIO;
- }
+ testfunc();
if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
#ifdef DYNAMIC
diff --git a/trunk/samples/kfifo/record-example.c b/trunk/samples/kfifo/record-example.c
index e68bd16a5da4..32c6e0bda744 100644
--- a/trunk/samples/kfifo/record-example.c
+++ b/trunk/samples/kfifo/record-example.c
@@ -55,19 +55,6 @@ typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest;
static mytest test;
#endif
-static const char *expected_result[] = {
- "a",
- "bb",
- "ccc",
- "dddd",
- "eeeee",
- "ffffff",
- "ggggggg",
- "hhhhhhhh",
- "iiiiiiiii",
- "jjjjjjjjjj",
-};
-
static int __init testfunc(void)
{
char buf[100];
@@ -88,10 +75,6 @@ static int __init testfunc(void)
kfifo_in(&test, buf, i + 1);
}
- /* skip first element of the fifo */
- printk(KERN_INFO "skip 1st element\n");
- kfifo_skip(&test);
-
printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));
/* show the first record without removing from the fifo */
@@ -99,22 +82,11 @@ static int __init testfunc(void)
if (ret)
printk(KERN_INFO "%.*s\n", ret, buf);
- /* check the correctness of all values in the fifo */
- i = 0;
+ /* print out all records in the fifo */
while (!kfifo_is_empty(&test)) {
ret = kfifo_out(&test, buf, sizeof(buf));
- buf[ret] = '\0';
- printk(KERN_INFO "item = %.*s\n", ret, buf);
- if (strcmp(buf, expected_result[i++])) {
- printk(KERN_WARNING "value mismatch: test failed\n");
- return -EIO;
- }
- }
- if (i != ARRAY_SIZE(expected_result)) {
- printk(KERN_WARNING "size mismatch: test failed\n");
- return -EIO;
+ printk(KERN_INFO "%.*s\n", ret, buf);
}
- printk(KERN_INFO "test passed\n");
return 0;
}
@@ -170,12 +142,7 @@ static int __init example_init(void)
#else
INIT_KFIFO(test);
#endif
- if (testfunc() < 0) {
-#ifdef DYNAMIC
- kfifo_free(&test);
-#endif
- return -EIO;
- }
+ testfunc();
if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
#ifdef DYNAMIC
diff --git a/trunk/scripts/recordmcount.pl b/trunk/scripts/recordmcount.pl
index e67f05486087..0171060b5fd6 100755
--- a/trunk/scripts/recordmcount.pl
+++ b/trunk/scripts/recordmcount.pl
@@ -159,7 +159,6 @@
my $function_regex; # Find the name of a function
# (return offset and func name)
my $mcount_regex; # Find the call site to mcount (return offset)
-my $mcount_adjust; # Address adjustment to mcount offset
my $alignment; # The .align value to use for $mcount_section
my $section_type; # Section header plus possible alignment command
my $can_use_local = 0; # If we can use local function references
@@ -214,7 +213,6 @@ sub check_objcopy
$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
$section_type = '@progbits';
-$mcount_adjust = 0;
$type = ".long";
if ($arch eq "x86_64") {
@@ -353,9 +351,6 @@ sub check_objcopy
} elsif ($arch eq "microblaze") {
# Microblaze calls '_mcount' instead of plain 'mcount'.
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
-} elsif ($arch eq "blackfin") {
- $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
- $mcount_adjust = -4;
} else {
die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
}
@@ -516,7 +511,7 @@ sub update_funcs
}
# is this a call site to mcount? If so, record it to print later
if ($text_found && /$mcount_regex/) {
- push(@offsets, (hex $1) + $mcount_adjust);
+ push(@offsets, hex $1);
}
}
diff --git a/trunk/security/apparmor/lsm.c b/trunk/security/apparmor/lsm.c
index f73e2c204218..d5666d3cc21b 100644
--- a/trunk/security/apparmor/lsm.c
+++ b/trunk/security/apparmor/lsm.c
@@ -607,8 +607,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
return error;
}
-static int apparmor_task_setrlimit(struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
+static int apparmor_task_setrlimit(unsigned int resource,
+ struct rlimit *new_rlim)
{
struct aa_profile *profile = aa_current_profile();
int error = 0;
diff --git a/trunk/security/apparmor/path.c b/trunk/security/apparmor/path.c
index 19358dc14605..96bab9469d48 100644
--- a/trunk/security/apparmor/path.c
+++ b/trunk/security/apparmor/path.c
@@ -62,14 +62,19 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
int deleted, connected;
int error = 0;
- /* Get the root we want to resolve too, released below */
+ /* Get the root we want to resolve too */
if (flags & PATH_CHROOT_REL) {
/* resolve paths relative to chroot */
- get_fs_root(current->fs, &root);
+ read_lock(¤t->fs->lock);
+ root = current->fs->root;
+ /* released below */
+ path_get(&root);
+ read_unlock(¤t->fs->lock);
} else {
/* resolve paths relative to namespace */
root.mnt = current->nsproxy->mnt_ns->root;
root.dentry = root.mnt->mnt_root;
+ /* released below */
path_get(&root);
}
diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c
index 9d172e6e330c..4e015996dd4d 100644
--- a/trunk/security/commoncap.c
+++ b/trunk/security/commoncap.c
@@ -40,7 +40,7 @@
*
* Warn if that happens, once per boot.
*/
-static void warn_setuid_and_fcaps_mixed(const char *fname)
+static void warn_setuid_and_fcaps_mixed(char *fname)
{
static int warned;
if (!warned) {
diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c
index 4796ddd4e721..42043f96e54f 100644
--- a/trunk/security/selinux/hooks.c
+++ b/trunk/security/selinux/hooks.c
@@ -2170,9 +2170,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
tty = get_current_tty();
if (tty) {
- spin_lock(&tty_files_lock);
+ file_list_lock();
if (!list_empty(&tty->tty_files)) {
- struct tty_file_private *file_priv;
struct inode *inode;
/* Revalidate access to controlling tty.
@@ -2180,16 +2179,14 @@ static inline void flush_unauthorized_files(const struct cred *cred,
than using file_has_perm, as this particular open
file may belong to another process and we are only
interested in the inode-based check here. */
- file_priv = list_first_entry(&tty->tty_files,
- struct tty_file_private, list);
- file = file_priv->file;
+ file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list);
inode = file->f_path.dentry->d_inode;
if (inode_has_perm(cred, inode,
FILE__READ | FILE__WRITE, NULL)) {
drop_tty = 1;
}
}
- spin_unlock(&tty_files_lock);
+ file_list_unlock();
tty_kref_put(tty);
}
/* Reset controlling tty. */
diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c
index 134fc6c2e08d..a3b2a6479246 100644
--- a/trunk/sound/core/pcm_native.c
+++ b/trunk/sound/core/pcm_native.c
@@ -978,10 +978,6 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
{
if (substream->runtime->trigger_master != substream)
return 0;
- /* some drivers might use hw_ptr to recover from the pause -
- update the hw_ptr now */
- if (push)
- snd_pcm_update_hw_ptr(substream);
/* The jiffies check in snd_pcm_update_hw_ptr*() is done by
* a delta betwen the current jiffies, this gives a large enough
* delta, effectively to skip the check once.
diff --git a/trunk/sound/pci/emu10k1/emu10k1.c b/trunk/sound/pci/emu10k1/emu10k1.c
index aff8387c45cf..4203782d7cb7 100644
--- a/trunk/sound/pci/emu10k1/emu10k1.c
+++ b/trunk/sound/pci/emu10k1/emu10k1.c
@@ -52,7 +52,6 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
static int enable_ir[SNDRV_CARDS];
static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
-static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -74,8 +73,6 @@ module_param_array(enable_ir, bool, NULL, 0444);
MODULE_PARM_DESC(enable_ir, "Enable IR.");
module_param_array(subsystem, uint, NULL, 0444);
MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
-module_param_array(delay_pcm_irq, uint, NULL, 0444);
-MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
/*
* Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
*/
@@ -130,7 +127,6 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
&emu)) < 0)
goto error;
card->private_data = emu;
- emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
goto error;
if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
diff --git a/trunk/sound/pci/emu10k1/emupcm.c b/trunk/sound/pci/emu10k1/emupcm.c
index 622bace148e3..55b83ef73c63 100644
--- a/trunk/sound/pci/emu10k1/emupcm.c
+++ b/trunk/sound/pci/emu10k1/emupcm.c
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
evoice->epcm->ccca_start_addr = start_addr + ccis;
if (extra) {
start_addr += ccis;
- end_addr += ccis + emu->delay_pcm_irq;
+ end_addr += ccis;
}
if (stereo && !extra) {
snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
@@ -360,9 +360,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
/* Assumption that PT is already 0 so no harm overwriting */
snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
- snd_emu10k1_ptr_write(emu, PSST, voice,
- (start_addr + (extra ? emu->delay_pcm_irq : 0)) |
- (send_amount[2] << 24));
+ snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
if (emu->card_capabilities->emu_model)
pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
else
@@ -734,23 +732,6 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
snd_emu10k1_ptr_write(emu, IP, voice, 0);
}
-static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
- struct snd_emu10k1_pcm *epcm,
- struct snd_pcm_substream *substream,
- struct snd_pcm_runtime *runtime)
-{
- unsigned int ptr, period_pos;
-
- /* try to sychronize the current position for the interrupt
- source voice */
- period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
- period_pos %= runtime->period_size;
- ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
- ptr &= ~0x00ffffff;
- ptr |= epcm->ccca_start_addr + period_pos;
- snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
-}
-
static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
int cmd)
{
@@ -772,8 +753,6 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
/* follow thru */
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
- snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
mix = &emu->pcm_mixer[substream->number];
snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -890,9 +869,8 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
#endif
/*
printk(KERN_DEBUG
- "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
- (long)ptr, (long)runtime->buffer_size,
- (long)runtime->period_size);
+ "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n",
+ ptr, runtime->buffer_size, runtime->period_size);
*/
return ptr;
}
diff --git a/trunk/sound/pci/emu10k1/memory.c b/trunk/sound/pci/emu10k1/memory.c
index 957a311514c8..ffb1ddb8dc28 100644
--- a/trunk/sound/pci/emu10k1/memory.c
+++ b/trunk/sound/pci/emu10k1/memory.c
@@ -310,10 +310,8 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
if (snd_BUG_ON(!hdr))
return NULL;
- idx = runtime->period_size >= runtime->buffer_size ?
- (emu->delay_pcm_irq * 2) : 0;
mutex_lock(&hdr->block_mutex);
- blk = search_empty(emu, runtime->dma_bytes + idx);
+ blk = search_empty(emu, runtime->dma_bytes);
if (blk == NULL) {
mutex_unlock(&hdr->block_mutex);
return NULL;
diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c
index c424952a734e..31b5d9eeba68 100644
--- a/trunk/sound/pci/hda/patch_conexant.c
+++ b/trunk/sound/pci/hda/patch_conexant.c
@@ -3049,7 +3049,6 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
CXT5066_DELL_LAPTOP),
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
- SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO),
SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c
index a4dd04524e43..2cd1ae809e46 100644
--- a/trunk/sound/pci/hda/patch_realtek.c
+++ b/trunk/sound/pci/hda/patch_realtek.c
@@ -19030,7 +19030,6 @@ static int patch_alc888(struct hda_codec *codec)
/*
* ALC680 support
*/
-#define ALC680_DIGIN_NID ALC880_DIGIN_NID
#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
#define alc680_modes alc260_modes
@@ -19045,93 +19044,23 @@ static hda_nid_t alc680_adc_nids[3] = {
0x07, 0x08, 0x09
};
-/*
- * Analog capture ADC cgange
- */
-static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int pre_mic, pre_line;
-
- pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
- pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]);
-
- spec->cur_adc_stream_tag = stream_tag;
- spec->cur_adc_format = format;
-
- if (pre_mic || pre_line) {
- if (pre_mic)
- snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0,
- format);
- else
- snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0,
- format);
- } else
- snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format);
- return 0;
-}
-
-static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- snd_hda_codec_cleanup_stream(codec, 0x07);
- snd_hda_codec_cleanup_stream(codec, 0x08);
- snd_hda_codec_cleanup_stream(codec, 0x09);
- return 0;
-}
-
-static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
- .substreams = 1, /* can be overridden */
- .channels_min = 2,
- .channels_max = 2,
- /* NID is set in alc_build_pcms */
- .ops = {
- .prepare = alc680_capture_pcm_prepare,
- .cleanup = alc680_capture_pcm_cleanup
- },
-};
-
static struct snd_kcontrol_new alc680_base_mixer[] = {
/* output mixer control */
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
{ }
};
-static struct hda_bind_ctls alc680_bind_cap_vol = {
- .ops = &snd_hda_bind_vol,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
- 0
- },
-};
-
-static struct hda_bind_ctls alc680_bind_cap_switch = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
- 0
- },
-};
-
-static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
- HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
- HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
+static struct snd_kcontrol_new alc680_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
{ } /* end */
};
@@ -19139,73 +19068,25 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
* generic initialization of ADC, input mixers and output mixers
*/
static struct hda_verb alc680_init_verbs[] = {
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Unmute DAC0-1 and set vol = 0 */
+ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
- {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
- {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
- {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
-
{ }
};
-/* toggle speaker-output according to the hp-jack state */
-static void alc680_base_setup(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
-
- spec->autocfg.hp_pins[0] = 0x16;
- spec->autocfg.speaker_pins[0] = 0x14;
- spec->autocfg.speaker_pins[1] = 0x15;
- spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18;
- spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19;
-}
-
-static void alc680_rec_autoswitch(struct hda_codec *codec)
-{
- struct alc_spec *spec = codec->spec;
- struct auto_pin_cfg *cfg = &spec->autocfg;
- unsigned int present;
- hda_nid_t new_adc;
-
- present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
-
- new_adc = present ? 0x8 : 0x7;
- __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1);
- snd_hda_codec_setup_stream(codec, new_adc,
- spec->cur_adc_stream_tag, 0,
- spec->cur_adc_format);
-
-}
-
-static void alc680_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- if ((res >> 26) == ALC880_HP_EVENT)
- alc_automute_amp(codec);
- if ((res >> 26) == ALC880_MIC_EVENT)
- alc680_rec_autoswitch(codec);
-}
-
-static void alc680_inithook(struct hda_codec *codec)
-{
- alc_automute_amp(codec);
- alc680_rec_autoswitch(codec);
-}
-
/* create input playback/capture controls for the given pin */
static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
const char *ctlname, int idx)
@@ -19316,7 +19197,13 @@ static void alc680_auto_init_hp_out(struct hda_codec *codec)
#define alc680_pcm_analog_capture alc880_pcm_analog_capture
#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
#define alc680_pcm_digital_playback alc880_pcm_digital_playback
-#define alc680_pcm_digital_capture alc880_pcm_digital_capture
+
+static struct hda_input_mux alc680_capture_source = {
+ .num_items = 1,
+ .items = {
+ { "Mic", 0x0 },
+ },
+};
/*
* BIOS auto configuration
@@ -19331,7 +19218,6 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
alc680_ignore);
if (err < 0)
return err;
-
if (!spec->autocfg.line_outs) {
if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
spec->multiout.max_channels = 2;
@@ -19353,6 +19239,8 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
add_mixer(spec, spec->kctls.list);
add_verb(spec, alc680_init_verbs);
+ spec->num_mux_defs = 1;
+ spec->input_mux = &alc680_capture_source;
err = alc_auto_add_mic_boost(codec);
if (err < 0)
@@ -19391,17 +19279,17 @@ static struct snd_pci_quirk alc680_cfg_tbl[] = {
static struct alc_config_preset alc680_presets[] = {
[ALC680_BASE] = {
.mixers = { alc680_base_mixer },
- .cap_mixer = alc680_master_capture_mixer,
+ .cap_mixer = alc680_capture_mixer,
.init_verbs = { alc680_init_verbs },
.num_dacs = ARRAY_SIZE(alc680_dac_nids),
.dac_nids = alc680_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
+ .adc_nids = alc680_adc_nids,
+ .hp_nid = 0x04,
.dig_out_nid = ALC680_DIGOUT_NID,
.num_channel_mode = ARRAY_SIZE(alc680_modes),
.channel_mode = alc680_modes,
- .unsol_event = alc680_unsol_event,
- .setup = alc680_base_setup,
- .init_hook = alc680_inithook,
-
+ .input_mux = &alc680_capture_source,
},
};
@@ -19445,9 +19333,9 @@ static int patch_alc680(struct hda_codec *codec)
setup_preset(codec, &alc680_presets[board_config]);
spec->stream_analog_playback = &alc680_pcm_analog_playback;
- spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
+ spec->stream_analog_capture = &alc680_pcm_analog_capture;
+ spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
spec->stream_digital_playback = &alc680_pcm_digital_playback;
- spec->stream_digital_capture = &alc680_pcm_digital_capture;
if (!spec->adc_nids) {
spec->adc_nids = alc680_adc_nids;
diff --git a/trunk/sound/pci/riptide/riptide.c b/trunk/sound/pci/riptide/riptide.c
index ad5202efd7a9..f64fb7d988cb 100644
--- a/trunk/sound/pci/riptide/riptide.c
+++ b/trunk/sound/pci/riptide/riptide.c
@@ -1224,14 +1224,15 @@ static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
firmware.firmware.ASIC, firmware.firmware.CODEC,
firmware.firmware.AUXDSP, firmware.firmware.PROG);
- if (!chip)
- return 1;
-
for (i = 0; i < FIRMWARE_VERSIONS; i++) {
if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
- return 1; /* OK */
-
+ break;
}
+ if (i >= FIRMWARE_VERSIONS)
+ return 0; /* no match */
+
+ if (!chip)
+ return 1; /* OK */
snd_printdd("Writing Firmware\n");
if (!chip->fw_entry) {
diff --git a/trunk/sound/soc/codecs/wm8776.c b/trunk/sound/soc/codecs/wm8776.c
index f8154e661524..4e212ed62ea6 100644
--- a/trunk/sound/soc/codecs/wm8776.c
+++ b/trunk/sound/soc/codecs/wm8776.c
@@ -178,6 +178,13 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
case SND_SOC_DAIFMT_LEFT_J:
iface |= 0x0001;
break;
+ /* FIXME: CHECK A/B */
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= 0x0007;
+ break;
default:
return -EINVAL;
}
diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile
index 4f1fa77c1feb..41abb90df50d 100644
--- a/trunk/tools/perf/Makefile
+++ b/trunk/tools/perf/Makefile
@@ -5,12 +5,6 @@ endif
# The default target of this Makefile is...
all::
-ifneq ($(OUTPUT),)
-# check that the output directory actually exists
-OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
-$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
-endif
-
# Define V=1 to have a more verbose compile.
# Define V=2 to have an even more verbose compile.
#
@@ -163,6 +157,10 @@ endif
#
# Define NO_DWARF if you do not want debug-info analysis feature at all.
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/{perl,python}/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)util/{ui/browsers,scripting-engines}/' 2> /dev/null)
+$(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null)
+
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
-include $(OUTPUT)PERF-VERSION-FILE
@@ -188,6 +186,8 @@ ifeq ($(ARCH),x86_64)
ARCH := x86
endif
+$(shell sh -c 'mkdir -p $(OUTPUT)arch/$(ARCH)/util/' 2> /dev/null)
+
# CFLAGS and LDFLAGS are for the users to override from the command line.
#
@@ -268,7 +268,6 @@ export prefix bindir sharedir sysconfdir
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
RM = rm -f
-MKDIR = mkdir
TAR = tar
FIND = find
INSTALL = install
@@ -839,7 +838,6 @@ ifndef V
QUIET_CC = @echo ' ' CC $@;
QUIET_AR = @echo ' ' AR $@;
QUIET_LINK = @echo ' ' LINK $@;
- QUIET_MKDIR = @echo ' ' MKDIR $@;
QUIET_BUILT_IN = @echo ' ' BUILTIN $@;
QUIET_GEN = @echo ' ' GEN $@;
QUIET_SUBDIR0 = +@subdir=
@@ -937,15 +935,15 @@ $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
$(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
- $(QUIET_GEN)$(RM) $(OUTPUT)$@ $(OUTPUT)$@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
-e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
-e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
- $@.sh > $(OUTPUT)$@+ && \
- chmod +x $(OUTPUT)$@+ && \
- mv $(OUTPUT)$@+ $(OUTPUT)$@
+ $@.sh >$@+ && \
+ chmod +x $@+ && \
+ mv $@+ $(OUTPUT)$@
configure: configure.ac
$(QUIET_GEN)$(RM) $@ $<+ && \
@@ -1014,14 +1012,6 @@ $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
-# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
-# we depend the various files onto their directories.
-DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
-$(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS)))
-# In the second step, we make a rule to actually create these directories
-$(sort $(dir $(DIRECTORY_DEPS))):
- $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
-
$(LIB_FILE): $(LIB_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
diff --git a/trunk/tools/perf/feature-tests.mak b/trunk/tools/perf/feature-tests.mak
index 7a7b60859053..ddb68e601f0e 100644
--- a/trunk/tools/perf/feature-tests.mak
+++ b/trunk/tools/perf/feature-tests.mak
@@ -113,7 +113,7 @@ endef
# try-cc
# Usage: option = $(call try-cc, source-to-build, cc-options)
try-cc = $(shell sh -c \
- 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
+ 'TMP="$(TMPOUT).$$$$"; \
echo "$(1)" | \
$(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
rm -f "$$TMP"')
diff --git a/trunk/tools/perf/util/ui/browsers/annotate.c b/trunk/tools/perf/util/ui/browsers/annotate.c
index a90273e63f4f..55ff792459ac 100644
--- a/trunk/tools/perf/util/ui/browsers/annotate.c
+++ b/trunk/tools/perf/util/ui/browsers/annotate.c
@@ -146,7 +146,6 @@ static int annotate_browser__run(struct annotate_browser *self,
return -1;
newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT);
- newtFormAddHotKey(self->b.form, NEWT_KEY_RIGHT);
nd = self->curr_hot;
if (nd) {
@@ -179,7 +178,7 @@ static int annotate_browser__run(struct annotate_browser *self,
}
out:
ui_browser__hide(&self->b);
- return es->u.key;
+ return 0;
}
int hist_entry__tui_annotate(struct hist_entry *self)